24
24
*/
25
25
package jdk .graal .compiler .libgraal ;
26
26
27
- import static java .lang .invoke .MethodType .methodType ;
28
-
29
- import java .lang .invoke .MethodHandle ;
30
- import java .lang .invoke .MethodHandles ;
27
+ import java .lang .module .ModuleDescriptor ;
31
28
import java .lang .reflect .Field ;
32
- import java .lang .reflect .Method ;
33
29
import java .nio .file .Path ;
34
30
import java .util .ArrayList ;
35
31
import java .util .Collections ;
52
48
import jdk .graal .compiler .serviceprovider .GraalServices ;
53
49
import jdk .graal .compiler .truffle .host .TruffleHostEnvironment ;
54
50
import jdk .graal .compiler .util .ObjectCopier ;
51
+ import jdk .internal .module .Modules ;
55
52
import jdk .vm .ci .hotspot .HotSpotJVMCIBackendFactory ;
56
53
import jdk .vm .ci .hotspot .HotSpotJVMCIRuntime ;
57
54
import jdk .vm .ci .services .JVMCIServiceLocator ;
58
- import jdk .vm .ci .services .Services ;
59
55
import org .graalvm .collections .EconomicMap ;
60
56
import org .graalvm .jniutils .NativeBridgeSupport ;
61
57
import org .graalvm .nativeimage .ImageSingletons ;
@@ -116,6 +112,35 @@ public static LibGraalFeature singleton() {
116
112
return singleton ;
117
113
}
118
114
115
+ /**
116
+ * Looks up a class in the libgraal class loader.
117
+ *
118
+ * @throws Error if the lookup fails
119
+ */
120
+ public static Class <?> lookupClass (String className ) {
121
+ try {
122
+ return Class .forName (className , false , LibGraalFeature .class .getClassLoader ());
123
+ } catch (ClassNotFoundException ex ) {
124
+ throw new GraalError (ex );
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Looks up a field via reflection and makes it accessible for reading.
130
+ *
131
+ * @throws Error if the operation fails
132
+ */
133
+ public static Field lookupField (Class <?> declaringClass , String fieldName ) {
134
+ try {
135
+ Field result = declaringClass .getDeclaredField (fieldName );
136
+ Modules .addOpensToAllUnnamed (declaringClass .getModule (), declaringClass .getPackageName ());
137
+ result .setAccessible (true );
138
+ return result ;
139
+ } catch (ReflectiveOperationException ex ) {
140
+ throw new GraalError (ex );
141
+ }
142
+ }
143
+
119
144
public static final class IsEnabled implements BooleanSupplier {
120
145
@ Override
121
146
public boolean getAsBoolean () {
@@ -124,8 +149,6 @@ public boolean getAsBoolean() {
124
149
}
125
150
}
126
151
127
- final MethodHandles .Lookup mhl = MethodHandles .lookup ();
128
-
129
152
final LibGraalLoader libgraalLoader = (LibGraalLoader ) getClass ().getClassLoader ();
130
153
131
154
/**
@@ -139,41 +162,21 @@ public void addFeatureComponent(FeatureComponent fc) {
139
162
140
163
@ Override
141
164
public void afterRegistration (AfterRegistrationAccess access ) {
142
- // LibGraalEntryPoints uses a number of classes in org.graalvm.nativeimage.builder
143
- exportModulesToLibGraal ("org.graalvm.nativeimage.builder" );
144
-
145
- // LibGraalFeature accesses a few Graal classes (see import statements above)
146
- exportModulesToLibGraal ("jdk.graal.compiler" );
147
-
148
- // LibGraalTruffleToLibGraalEntryPoints access TruffleToLibGraal.Id
149
- exportModulesToLibGraal ("org.graalvm.truffle.compiler" );
150
-
151
165
ImageSingletons .add (NativeBridgeSupport .class , new LibGraalNativeBridgeSupport ());
152
166
153
- // Guest JVMCI and Graal need access to some JDK internal packages
154
- String [] basePackages = {
155
- "jdk.internal.misc" ,
156
- "jdk.internal.util" ,
157
- "jdk.internal.vm" };
158
- LibGraalUtil .accessPackagesToClass (LibGraalUtil .Access .EXPORT , null , false , "java.base" , basePackages );
159
- }
160
-
161
- static void exportModulesToLibGraal (String ... moduleNames ) {
162
- accessModulesToClass (LibGraalUtil .Access .EXPORT , LibGraalFeature .class , moduleNames );
163
- }
164
-
165
- static void accessModulesToClass (LibGraalUtil .Access access , Class <?> accessingClass , String ... moduleNames ) {
166
- for (String moduleName : moduleNames ) {
167
- var module = getBootModule (moduleName );
168
- LibGraalUtil .accessPackagesToClass (access , accessingClass , false ,
169
- module .getName (), module .getPackages ().toArray (String []::new ));
167
+ // The qualified exports from java.base to jdk.internal.vm.ci
168
+ // and jdk.graal.compiler need to be expressed as exports to
169
+ // ALL-UNNAMED so that access is also possible when these classes
170
+ // are loaded via the libgraal loader.
171
+ Module javaBase = ModuleLayer .boot ().findModule ("java.base" ).orElseThrow ();
172
+ Set <ModuleDescriptor .Exports > exports = javaBase .getDescriptor ().exports ();
173
+ for (ModuleDescriptor .Exports e : exports ) {
174
+ if (e .targets ().contains ("jdk.internal.vm.ci" ) || e .targets ().contains ("jdk.graal.compiler" )) {
175
+ Modules .addExportsToAllUnnamed (javaBase , e .source ());
176
+ }
170
177
}
171
178
}
172
179
173
- static Module getBootModule (String moduleName ) {
174
- return ModuleLayer .boot ().findModule (moduleName ).orElseThrow ();
175
- }
176
-
177
180
@ Override
178
181
public void duringSetup (DuringSetupAccess access ) {
179
182
optionCollector = new OptionCollector ();
@@ -247,18 +250,12 @@ class FieldOffsetsTransformer implements FieldValueTransformer {
247
250
*/
248
251
private final Map <Object , Map .Entry <long [], Long >> replacements = new IdentityHashMap <>();
249
252
250
- final Class <?> edgesClass ;
251
- final Class <?> fieldsClass ;
252
253
final Field fieldsOffsetsField ;
253
254
final Field edgesIterationMaskField ;
254
- final Method recomputeOffsetsAndIterationMaskMethod ;
255
255
256
256
FieldOffsetsTransformer () {
257
- edgesClass = Edges .class ;
258
- fieldsClass = Fields .class ;
259
- fieldsOffsetsField = LibGraalUtil .lookupField (fieldsClass , "offsets" );
260
- edgesIterationMaskField = LibGraalUtil .lookupField (edgesClass , "iterationMask" );
261
- recomputeOffsetsAndIterationMaskMethod = LibGraalUtil .lookupMethod (fieldsClass , "recomputeOffsetsAndIterationMask" , BeforeCompilationAccess .class );
257
+ fieldsOffsetsField = lookupField (Fields .class , "offsets" );
258
+ edgesIterationMaskField = lookupField (Edges .class , "iterationMask" );
262
259
}
263
260
264
261
void register (BeforeAnalysisAccess access ) {
@@ -286,38 +283,28 @@ private Map.Entry<long[], Long> getReplacement(Object receiver) {
286
283
}
287
284
}
288
285
289
- @ SuppressWarnings ("unchecked" )
290
286
private Map .Entry <long [], Long > computeReplacement (Object receiver ) {
291
- try {
292
- return (Map .Entry <long [], Long >) recomputeOffsetsAndIterationMaskMethod .invoke (receiver , beforeCompilationAccess );
293
- } catch (Throwable e ) {
294
- throw GraalError .shouldNotReachHere (e );
295
- }
287
+ Fields fields = (Fields ) receiver ;
288
+ return fields .recomputeOffsetsAndIterationMask (beforeCompilationAccess );
296
289
}
297
290
}
298
291
299
292
/**
300
293
* Transforms {@code GlobalAtomicLong.addressSupplier} by replacing it with a {@link GlobalData}
301
294
* backed address supplier.
302
295
*/
303
- class GlobalAtomicLongTransformer implements FieldValueTransformer {
304
- private MethodHandle globalAtomicLongGetInitialValue ;
296
+ static class GlobalAtomicLongTransformer implements FieldValueTransformer {
305
297
306
298
void register (BeforeAnalysisAccess access ) {
307
- Field addressSupplierField = LibGraalUtil . lookupField (GlobalAtomicLong .class , "addressSupplier" );
299
+ Field addressSupplierField = lookupField (GlobalAtomicLong .class , "addressSupplier" );
308
300
access .registerFieldValueTransformer (addressSupplierField , this );
309
- try {
310
- globalAtomicLongGetInitialValue = mhl .findVirtual (GlobalAtomicLong .class , "getInitialValue" , methodType (long .class ));
311
- } catch (Throwable e ) {
312
- GraalError .shouldNotReachHere (e );
313
- }
314
301
}
315
302
316
303
@ Override
317
304
public Object transform (Object receiver , Object originalValue ) {
318
305
long initialValue ;
319
306
try {
320
- initialValue = (long ) globalAtomicLongGetInitialValue . invoke ( receiver );
307
+ initialValue = (( GlobalAtomicLong ) receiver ). getInitialValue ( );
321
308
} catch (Throwable e ) {
322
309
throw GraalError .shouldNotReachHere (e );
323
310
}
@@ -334,28 +321,29 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
334
321
335
322
/* Contains static fields that depend on HotSpotJVMCIRuntime */
336
323
RuntimeClassInitialization .initializeAtRunTime (HotSpotModifiers .class );
337
- RuntimeClassInitialization .initializeAtRunTime (LibGraalUtil . lookupClass ("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream" ));
338
- RuntimeClassInitialization .initializeAtRunTime (LibGraalUtil . lookupClass ("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag" ));
324
+ RuntimeClassInitialization .initializeAtRunTime (lookupClass ("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream" ));
325
+ RuntimeClassInitialization .initializeAtRunTime (lookupClass ("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag" ));
339
326
340
327
/* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */
341
328
RuntimeReflection .registerAllDeclaredClasses (Character .class );
342
- RuntimeReflection .register (LibGraalUtil . lookupField (LibGraalUtil . lookupClass ("java.lang.Character$CharacterCache" ), "cache" ));
329
+ RuntimeReflection .register (lookupField (lookupClass ("java.lang.Character$CharacterCache" ), "cache" ));
343
330
RuntimeReflection .registerAllDeclaredClasses (Byte .class );
344
- RuntimeReflection .register (LibGraalUtil . lookupField (LibGraalUtil . lookupClass ("java.lang.Byte$ByteCache" ), "cache" ));
331
+ RuntimeReflection .register (lookupField (lookupClass ("java.lang.Byte$ByteCache" ), "cache" ));
345
332
RuntimeReflection .registerAllDeclaredClasses (Short .class );
346
- RuntimeReflection .register (LibGraalUtil . lookupField (LibGraalUtil . lookupClass ("java.lang.Short$ShortCache" ), "cache" ));
333
+ RuntimeReflection .register (lookupField (lookupClass ("java.lang.Short$ShortCache" ), "cache" ));
347
334
RuntimeReflection .registerAllDeclaredClasses (Integer .class );
348
- RuntimeReflection .register (LibGraalUtil . lookupField (LibGraalUtil . lookupClass ("java.lang.Integer$IntegerCache" ), "cache" ));
335
+ RuntimeReflection .register (lookupField (lookupClass ("java.lang.Integer$IntegerCache" ), "cache" ));
349
336
RuntimeReflection .registerAllDeclaredClasses (Long .class );
350
- RuntimeReflection .register (LibGraalUtil . lookupField (LibGraalUtil . lookupClass ("java.lang.Long$LongCache" ), "cache" ));
337
+ RuntimeReflection .register (lookupField (lookupClass ("java.lang.Long$LongCache" ), "cache" ));
351
338
352
339
doLegacyJVMCIInitialization ();
353
340
354
341
Path libGraalJavaHome = libgraalLoader .getJavaHome ();
355
342
GetCompilerConfig .Result configResult = GetCompilerConfig .from (libGraalJavaHome );
356
343
for (var e : configResult .opens ().entrySet ()) {
344
+ Module module = ModuleLayer .boot ().findModule (e .getKey ()).orElseThrow ();
357
345
for (String source : e .getValue ()) {
358
- LibGraalUtil . accessPackagesToClass ( LibGraalUtil . Access . OPEN , getClass (), false , e . getKey () , source );
346
+ Modules . addOpensToAllUnnamed ( module , source );
359
347
}
360
348
}
361
349
@@ -385,8 +373,7 @@ private void doLegacyJVMCIInitialization() {
385
373
try {
386
374
String rawArch = GraalServices .getSavedProperty ("os.arch" );
387
375
String arch = switch (rawArch ) {
388
- case "x86_64" -> "AMD64" ;
389
- case "amd64" -> "AMD64" ;
376
+ case "x86_64" , "amd64" -> "AMD64" ;
390
377
case "aarch64" -> "aarch64" ;
391
378
case "riscv64" -> "riscv64" ;
392
379
default -> throw new GraalError ("Unknown or unsupported arch: %s" , rawArch );
@@ -414,19 +401,6 @@ private void doLegacyJVMCIInitialization() {
414
401
}
415
402
}
416
403
417
- /**
418
- * Determines if the JDK runtime includes JDK-8346781. Without it, initialization of some JVMCI
419
- * static cache fields must be done explicitly by {@link LibGraalFeature}.
420
- */
421
- static boolean has8346781 () {
422
- try {
423
- Services .class .getField ("IS_BUILDING_NATIVE_IMAGE" );
424
- return false ;
425
- } catch (NoSuchFieldException e ) {
426
- return true ;
427
- }
428
- }
429
-
430
404
@ Override
431
405
public void duringAnalysis (DuringAnalysisAccess access ) {
432
406
for (var c : libGraalFeatureComponents ) {
0 commit comments