Skip to content

Commit 7404ddf

Browse files
Ramkumar Sunderbabulmesnik
Ramkumar Sunderbabu
authored andcommittedOct 30, 2024
8202100: Merge vm/share/InMemoryJavaCompiler w/ jdk/test/lib/compiler/InMemoryJavaCompiler
Reviewed-by: lmesnik
1 parent 821c514 commit 7404ddf

File tree

12 files changed

+142
-198
lines changed

12 files changed

+142
-198
lines changed
 

‎test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LambdaProxyCallerIsHidden.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,8 @@
3737
* jdk/test/lib/compiler/InMemoryJavaCompiler
3838
* jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1
3939
* jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper
40-
* jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject
40+
* jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile
41+
* jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile
4142
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
4243
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. LambdaProxyCallerIsHidden
4344
*/

‎test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RedefineCallerClassTest.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,8 @@ public class RedefineCallerClassTest extends DynamicArchiveTestBase {
5252
"jdk/test/lib/compiler/InMemoryJavaCompiler",
5353
"jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper",
5454
"jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1",
55-
"jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject"
55+
"jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile",
56+
"jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile"
5657
};
5758

5859
public static void main(String[] args) throws Exception {

‎test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/RegularHiddenClass.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,8 @@
3535
* jdk/test/lib/compiler/InMemoryJavaCompiler
3636
* jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1
3737
* jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper
38-
* jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject
38+
* jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile
39+
* jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile
3940
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
4041
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. RegularHiddenClass
4142
*/

‎test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineBasicTest.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,8 @@ public class RedefineBasicTest {
4747
"jdk/test/lib/compiler/InMemoryJavaCompiler",
4848
"jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper",
4949
"jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1",
50-
"jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject"
50+
"jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile",
51+
"jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile"
5152
};
5253

5354
public static void main(String[] args) throws Exception {

‎test/hotspot/jtreg/runtime/cds/appcds/redefineClass/RedefineRunningMethods_Shared.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,8 @@ public class RedefineRunningMethods_Shared {
4848
"jdk/test/lib/compiler/InMemoryJavaCompiler",
4949
"jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper",
5050
"jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1",
51-
"jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject"
51+
"jdk/test/lib/compiler/InMemoryJavaCompiler$SourceFile",
52+
"jdk/test/lib/compiler/InMemoryJavaCompiler$ClassFile"
5253
};
5354

5455
public static void main(String[] args) throws Exception {

‎test/hotspot/jtreg/vmTestbase/gc/g1/unloading/bytecode/BytecodeGeneratorFactory.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
2626
import java.util.Map;
2727
import java.util.Random;
2828

29-
import vm.share.InMemoryJavaCompiler;
29+
import jdk.test.lib.compiler.InMemoryJavaCompiler;
3030

3131
/**
3232
* BytecodeFactory that employs in memory compilation.
@@ -44,12 +44,10 @@ public BytecodeGeneratorFactory(long seed) {
4444

4545
@Override
4646
public Bytecode createBytecode(String className) {
47-
Map<String, CharSequence> sources = new HashMap<String, CharSequence>();
48-
sources.put(className, sourceGenerator.generateSource(className,
47+
byte[] bytecode = InMemoryJavaCompiler.compile(className, sourceGenerator.generateSource(className,
4948
"public static void main() { System.out.println(\"From main method in in-mem-compiled code " + random.nextGaussian() +
5049
" + str_bytesToReplace0 str_bytesToReplace1\"); }\n " +
5150
"public static int methodForCompilation(Object object) { int i = object.hashCode(); i = i * 2000 / 1994 + 153; return i; }\n"));
52-
byte[] bytecode = InMemoryJavaCompiler.compile(sources).values().iterator().next();
5351
return new Bytecode(className, bytecode);
5452
}
5553

‎test/hotspot/jtreg/vmTestbase/metaspace/staticReferences/StaticReferences.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
import nsk.share.test.Stresser;
6161
import nsk.share.test.TestBase;
6262
import nsk.share.test.Tests;
63-
import vm.share.InMemoryJavaCompiler;
63+
import jdk.test.lib.compiler.InMemoryJavaCompiler;
6464

6565
/**
6666
* Test checks that static fields will be initialized in new loaded class. Test performs in loop the following routine:
@@ -210,9 +210,7 @@ private void checkStaticFields(Class clazz) {
210210
}
211211

212212
private byte[] generateAndCompile(int[] fieldQuantities) {
213-
Map<String, CharSequence> sources = new HashMap<String, CharSequence>();
214-
sources.put("A", generateSource(fieldQuantities));
215-
return InMemoryJavaCompiler.compile(sources).values().iterator().next();
213+
return InMemoryJavaCompiler.compile("A", generateSource(fieldQuantities));
216214
}
217215

218216
private StringBuffer generateSource(int[] fieldQuantities) {

‎test/hotspot/jtreg/vmTestbase/metaspace/stressDictionary/StressDictionary.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
4343

4444
import nsk.share.gc.GCTestBase;
4545
import nsk.share.test.*;
46-
import vm.share.InMemoryJavaCompiler;
46+
import jdk.test.lib.compiler.InMemoryJavaCompiler;
4747

4848
/**
4949
* There is a data structure named "dictionary" in class BlockFreelist. It stores
@@ -178,10 +178,8 @@ public void run() {
178178
}
179179

180180
private byte[] generateAndCompile() {
181-
Map<String, CharSequence> sources = new HashMap<String, CharSequence>();
182181
String className = "MyClass" + classesCounter.incrementAndGet();
183-
sources.put(className, generateSource(className));
184-
return InMemoryJavaCompiler.compile(sources).values().iterator().next();
182+
return InMemoryJavaCompiler.compile(className, generateSource(className));
185183
}
186184

187185
private CharSequence generateSource(String className) {

‎test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/generateHierarchy/GenerateHierarchyHelper.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
2424

2525
import java.util.*;
2626

27-
import vm.share.InMemoryJavaCompiler;
27+
import jdk.test.lib.compiler.InMemoryJavaCompiler;
2828
import jdk.test.lib.Utils;
2929

3030
public class GenerateHierarchyHelper {

‎test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/StressRedefine.java

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -21,7 +21,6 @@
2121
* questions.
2222
*/
2323

24-
//package nsk.jvmti.RedefineClasses.StressRedefine;
2524
package nsk.jvmti.RedefineClasses;
2625

2726

@@ -41,7 +40,7 @@
4140
import nsk.share.test.Stresser;
4241
import nsk.share.test.Tests;
4342

44-
import vm.share.InMemoryJavaCompiler;
43+
import jdk.test.lib.compiler.InMemoryJavaCompiler;
4544

4645
/**
4746
* There is a data structure named "dictionary" in class BlockFreelist. It stores
@@ -203,9 +202,7 @@ private static ThreadFactory virtualThreadFactory() {
203202
}
204203

205204
private static byte[] generateAndCompile() {
206-
Map<String, CharSequence> sources = new HashMap<String, CharSequence>();
207-
sources.put(GenerateSourceHelper.CLASS_NAME, GenerateSourceHelper.generateSource());
208-
return InMemoryJavaCompiler.compile(sources).values().iterator().next();
205+
return InMemoryJavaCompiler.compile(GenerateSourceHelper.CLASS_NAME, GenerateSourceHelper.generateSource());
209206
}
210207

211208
// Auxiliary classloader. Used only once at the beginning.

‎test/hotspot/jtreg/vmTestbase/vm/share/InMemoryJavaCompiler.java

-125
This file was deleted.

‎test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java

+114-41
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,18 @@
2626
import java.io.ByteArrayOutputStream;
2727
import java.io.IOException;
2828
import java.io.OutputStream;
29+
import java.io.StringWriter;
30+
import java.io.Writer;
2931

3032
import java.net.URI;
3133
import java.util.ArrayList;
3234
import java.util.Arrays;
35+
import java.util.Collection;
36+
import java.util.HashMap;
37+
import java.util.LinkedList;
3338
import java.util.List;
39+
import java.util.Map;
40+
import java.util.Map.Entry;
3441

3542
import javax.tools.FileObject;
3643
import javax.tools.ForwardingJavaFileManager;
@@ -76,36 +83,6 @@
7683
* </pre>
7784
*/
7885
public class InMemoryJavaCompiler {
79-
private static class MemoryJavaFileObject extends SimpleJavaFileObject {
80-
private final String className;
81-
private final CharSequence sourceCode;
82-
private final ByteArrayOutputStream byteCode;
83-
84-
public MemoryJavaFileObject(String className, CharSequence sourceCode) {
85-
super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
86-
this.className = className;
87-
this.sourceCode = sourceCode;
88-
this.byteCode = new ByteArrayOutputStream();
89-
}
90-
91-
@Override
92-
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
93-
return sourceCode;
94-
}
95-
96-
@Override
97-
public OutputStream openOutputStream() throws IOException {
98-
return byteCode;
99-
}
100-
101-
public byte[] getByteCode() {
102-
return byteCode.toByteArray();
103-
}
104-
105-
public String getClassName() {
106-
return className;
107-
}
108-
}
10986

11087
private static class FileManagerWrapper extends ForwardingJavaFileManager<JavaFileManager> {
11188
private static final Location PATCH_LOCATION = new Location() {
@@ -119,29 +96,31 @@ public boolean isOutputLocation() {
11996
return false;
12097
}
12198
};
122-
private final MemoryJavaFileObject file;
99+
private final SourceFile srcFile;
100+
private ClassFile clsFile;
123101
private final String moduleOverride;
124102

125-
public FileManagerWrapper(MemoryJavaFileObject file, String moduleOverride) {
103+
public FileManagerWrapper(SourceFile file, String moduleOverride) {
126104
super(getCompiler().getStandardFileManager(null, null, null));
127-
this.file = file;
105+
this.srcFile = file;
128106
this.moduleOverride = moduleOverride;
129107
}
130108

131109
@Override
132110
public JavaFileObject getJavaFileForOutput(Location location, String className,
133111
Kind kind, FileObject sibling)
134112
throws IOException {
135-
if (!file.getClassName().equals(className)) {
136-
throw new IOException("Expected class with name " + file.getClassName() +
113+
if (!srcFile.getClassName().equals(className)) {
114+
throw new IOException("Expected class with name " + srcFile.getClassName() +
137115
", but got " + className);
138116
}
139-
return file;
117+
clsFile = new ClassFile(className);
118+
return clsFile;
140119
}
141120

142121
@Override
143122
public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
144-
if (fo == file && moduleOverride != null) {
123+
if (fo == srcFile && moduleOverride != null) {
145124
return PATCH_LOCATION;
146125
}
147126
return super.getLocationForModule(location, fo);
@@ -160,6 +139,100 @@ public boolean hasLocation(Location location) {
160139
return super.hasLocation(location) || location == StandardLocation.PATCH_MODULE_PATH;
161140
}
162141

142+
public byte[] getByteCode() {
143+
return clsFile.toByteArray();
144+
}
145+
146+
}
147+
148+
// Wraper for class file
149+
static class ClassFile extends SimpleJavaFileObject {
150+
151+
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
152+
153+
protected ClassFile(String name) {
154+
super(URI.create("memo:///" + name.replace('.', '/') + Kind.CLASS.extension), Kind.CLASS);
155+
}
156+
157+
@Override
158+
public ByteArrayOutputStream openOutputStream() { return this.baos; }
159+
160+
byte[] toByteArray() { return baos.toByteArray(); }
161+
}
162+
163+
// File manager which spawns ClassFile instances by demand
164+
static class FileManager extends ForwardingJavaFileManager<JavaFileManager> {
165+
166+
private Map<String, ClassFile> classesMap = new HashMap<String, ClassFile>();
167+
168+
protected FileManager(JavaFileManager fileManager) {
169+
super(fileManager);
170+
}
171+
172+
@Override
173+
public ClassFile getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject source) {
174+
ClassFile classFile = new ClassFile(name);
175+
classesMap.put(name, classFile);
176+
return classFile;
177+
}
178+
179+
public Map<String, byte[]> getByteCode() {
180+
Map<String, byte[]> result = new HashMap<String, byte[]>();
181+
for (Entry<String, ClassFile> entry : classesMap.entrySet()) {
182+
result.put(entry.getKey(), entry.getValue().toByteArray());
183+
}
184+
return result;
185+
}
186+
}
187+
188+
// Wrapper for source file
189+
static class SourceFile extends SimpleJavaFileObject {
190+
191+
private CharSequence sourceCode;
192+
private String className;
193+
194+
public SourceFile(String name, CharSequence sourceCode) {
195+
super(URI.create("memo:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
196+
this.sourceCode = sourceCode;
197+
this.className = name;
198+
}
199+
200+
@Override
201+
public CharSequence getCharContent(boolean ignore) {
202+
return this.sourceCode;
203+
}
204+
205+
public String getClassName() {
206+
return this.className;
207+
}
208+
}
209+
210+
/**
211+
* Compiles the list of classes with the given map of name and source code.
212+
* This overloaded version of compile is useful for batch compile use cases.
213+
*
214+
* @param inputMap The map containing the name of the class and corresponding source code
215+
* @throws RuntimeException if the compilation did not succeed
216+
* @return The resulting byte code from the compilation
217+
*/
218+
public static Map<String, byte[]> compile(Map<String, ? extends CharSequence> inputMap) {
219+
Collection<JavaFileObject> sourceFiles = new LinkedList<JavaFileObject>();
220+
for (Entry<String, ? extends CharSequence> entry : inputMap.entrySet()) {
221+
sourceFiles.add(new SourceFile(entry.getKey(), entry.getValue()));
222+
}
223+
224+
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
225+
FileManager fileManager = new FileManager(compiler.getStandardFileManager(null, null, null));
226+
227+
Writer writer = new StringWriter();
228+
Boolean exitCode = compiler.getTask(writer, fileManager, null, null, null, sourceFiles).call();
229+
if (!exitCode) {
230+
System.out.println("*********** javac output begin ***********");
231+
System.out.println(writer.toString());
232+
System.out.println("*********** javac output end ***********");
233+
throw new RuntimeException("Test bug: in memory compilation failed.");
234+
}
235+
return fileManager.getByteCode();
163236
}
164237

165238
/**
@@ -173,7 +246,7 @@ public boolean hasLocation(Location location) {
173246
* @return The resulting byte code from the compilation
174247
*/
175248
public static byte[] compile(String className, CharSequence sourceCode, String... options) {
176-
MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode);
249+
SourceFile file = new SourceFile(className, sourceCode);
177250
List<String> opts = new ArrayList<>();
178251
String moduleOverride = null;
179252
for (String opt : options) {
@@ -183,13 +256,13 @@ public static byte[] compile(String className, CharSequence sourceCode, String..
183256
opts.add(opt);
184257
}
185258
}
186-
try (JavaFileManager fileManager = new FileManagerWrapper(file, moduleOverride)) {
259+
try (FileManagerWrapper fileManager = new FileManagerWrapper(file, moduleOverride)) {
187260
CompilationTask task = getCompiler().getTask(null, fileManager, null, opts, null, Arrays.asList(file));
188261
if (!task.call()) {
189262
throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode);
190263
}
191264

192-
return file.getByteCode();
265+
return fileManager.getByteCode();
193266
} catch (IOException ioe) {
194267
throw new RuntimeException(ioe);
195268
}

0 commit comments

Comments
 (0)
Please sign in to comment.