Mercurial > hg > truffle
comparison test/testlibrary/com/oracle/java/testlibrary/InMemoryJavaCompiler.java @ 12063:1a8fb39bdbc4
8014659: NPG: performance counters for compressed klass space
Reviewed-by: mgerdin, coleenp, hseigel, jmasa, ctornqvi
author | ehelin |
---|---|
date | Wed, 07 Aug 2013 16:47:32 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
12061:e5003079dfa5 | 12063:1a8fb39bdbc4 |
---|---|
1 /* | |
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 | |
24 package com.oracle.java.testlibrary; | |
25 | |
26 import java.io.ByteArrayOutputStream; | |
27 import java.io.IOException; | |
28 import java.io.OutputStream; | |
29 | |
30 import java.net.URI; | |
31 import java.util.Arrays; | |
32 | |
33 import javax.tools.ForwardingJavaFileManager; | |
34 import javax.tools.ForwardingJavaFileManager; | |
35 import javax.tools.FileObject; | |
36 import javax.tools.JavaCompiler; | |
37 import javax.tools.JavaCompiler.CompilationTask; | |
38 import javax.tools.JavaFileManager; | |
39 import javax.tools.JavaFileObject; | |
40 import javax.tools.JavaFileObject.Kind; | |
41 import javax.tools.SimpleJavaFileObject; | |
42 import javax.tools.ToolProvider; | |
43 | |
44 /** | |
45 * {@code InMemoryJavaCompiler} can be used for compiling a {@link | |
46 * CharSequence} to a {@code byte[]}. | |
47 * | |
48 * The compiler will not use the file system at all, instead using a {@link | |
49 * ByteArrayOutputStream} for storing the byte code. For the source code, any | |
50 * kind of {@link CharSequence} can be used, e.g. {@link String}, {@link | |
51 * StringBuffer} or {@link StringBuilder}. | |
52 * | |
53 * The {@code InMemoryCompiler} can easily be used together with a {@code | |
54 * ByteClassLoader} to easily compile and load source code in a {@link String}: | |
55 * | |
56 * <pre> | |
57 * {@code | |
58 * import com.oracle.java.testlibrary.InMemoryJavaCompiler; | |
59 * import com.oracle.java.testlibrary.ByteClassLoader; | |
60 * | |
61 * class Example { | |
62 * public static void main(String[] args) { | |
63 * String className = "Foo"; | |
64 * String sourceCode = "public class " + className + " {" + | |
65 * " public void bar() {" + | |
66 * " System.out.println("Hello from bar!");" + | |
67 * " }" + | |
68 * "}"; | |
69 * byte[] byteCode = InMemoryJavaCompiler.compile(className, sourceCode); | |
70 * Class fooClass = ByteClassLoader.load(className, byteCode); | |
71 * } | |
72 * } | |
73 * } | |
74 * </pre> | |
75 */ | |
76 public class InMemoryJavaCompiler { | |
77 private static class MemoryJavaFileObject extends SimpleJavaFileObject { | |
78 private final String className; | |
79 private final CharSequence sourceCode; | |
80 private final ByteArrayOutputStream byteCode; | |
81 | |
82 public MemoryJavaFileObject(String className, CharSequence sourceCode) { | |
83 super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); | |
84 this.className = className; | |
85 this.sourceCode = sourceCode; | |
86 this.byteCode = new ByteArrayOutputStream(); | |
87 } | |
88 | |
89 @Override | |
90 public CharSequence getCharContent(boolean ignoreEncodingErrors) { | |
91 return sourceCode; | |
92 } | |
93 | |
94 @Override | |
95 public OutputStream openOutputStream() throws IOException { | |
96 return byteCode; | |
97 } | |
98 | |
99 public byte[] getByteCode() { | |
100 return byteCode.toByteArray(); | |
101 } | |
102 | |
103 public String getClassName() { | |
104 return className; | |
105 } | |
106 } | |
107 | |
108 private static class FileManagerWrapper extends ForwardingJavaFileManager { | |
109 private MemoryJavaFileObject file; | |
110 | |
111 public FileManagerWrapper(MemoryJavaFileObject file) { | |
112 super(getCompiler().getStandardFileManager(null, null, null)); | |
113 this.file = file; | |
114 } | |
115 | |
116 @Override | |
117 public JavaFileObject getJavaFileForOutput(Location location, String className, | |
118 Kind kind, FileObject sibling) | |
119 throws IOException { | |
120 if (!file.getClassName().equals(className)) { | |
121 throw new IOException("Expected class with name " + file.getClassName() + | |
122 ", but got " + className); | |
123 } | |
124 return file; | |
125 } | |
126 } | |
127 | |
128 /** | |
129 * Compiles the class with the given name and source code. | |
130 * | |
131 * @param className The name of the class | |
132 * @param sourceCode The source code for the class with name {@code className} | |
133 * @throws RuntimeException if the compilation did not succeed | |
134 * @return The resulting byte code from the compilation | |
135 */ | |
136 public static byte[] compile(String className, CharSequence sourceCode) { | |
137 MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode); | |
138 CompilationTask task = getCompilationTask(file); | |
139 | |
140 if(!task.call()) { | |
141 throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode); | |
142 } | |
143 | |
144 return file.getByteCode(); | |
145 } | |
146 | |
147 private static JavaCompiler getCompiler() { | |
148 return ToolProvider.getSystemJavaCompiler(); | |
149 } | |
150 | |
151 private static CompilationTask getCompilationTask(MemoryJavaFileObject file) { | |
152 return getCompiler().getTask(null, new FileManagerWrapper(file), null, null, null, Arrays.asList(file)); | |
153 } | |
154 } |