32
32
import java .lang .reflect .Field ;
33
33
import java .lang .reflect .Method ;
34
34
import java .lang .reflect .Modifier ;
35
+ import java .net .MalformedURLException ;
36
+ import java .net .URL ;
37
+ import java .net .URLClassLoader ;
35
38
import java .nio .file .Files ;
36
39
import java .nio .file .Path ;
37
40
import java .util .ArrayList ;
38
41
import java .util .Arrays ;
39
42
import java .util .Collections ;
43
+ import java .util .Comparator ;
40
44
import java .util .Enumeration ;
41
45
import java .util .HashMap ;
42
46
import java .util .HashSet ;
48
52
import java .util .concurrent .ThreadPoolExecutor ;
49
53
import java .util .concurrent .TimeUnit ;
50
54
import java .util .function .Supplier ;
55
+ import java .util .stream .Collectors ;
56
+ import java .util .stream .Stream ;
51
57
import java .util .zip .ZipEntry ;
52
58
import java .util .zip .ZipFile ;
53
59
109
115
import jdk .vm .ci .code .BailoutException ;
110
116
import jdk .vm .ci .code .Register ;
111
117
import jdk .vm .ci .code .Register .RegisterCategory ;
112
- import jdk .vm .ci .hotspot .HotSpotConstantPool ;
113
118
import jdk .vm .ci .meta .ConstantPool ;
114
119
import jdk .vm .ci .meta .JavaField ;
115
120
import jdk .vm .ci .meta .JavaMethod ;
@@ -151,7 +156,7 @@ public static void main(String[] args) {
151
156
152
157
public static String relativeFileName (String absolutePath ) {
153
158
int lastFileSeparatorIndex = absolutePath .lastIndexOf (File .separator );
154
- return absolutePath .substring (lastFileSeparatorIndex >= 0 ? lastFileSeparatorIndex : 0 );
159
+ return absolutePath .substring (Math . max ( lastFileSeparatorIndex , 0 ) );
155
160
}
156
161
157
162
public static class InvariantsTool {
@@ -162,27 +167,41 @@ protected boolean shouldProcess(String classpathEntry) {
162
167
}
163
168
if (classpathEntry .endsWith (".jar" )) {
164
169
String name = new File (classpathEntry ).getName ();
165
- return name .contains ("graal" ) || name . contains ( "jdk.graal.compiler" ) ;
170
+ return name .contains ("graal" );
166
171
}
167
172
return false ;
168
173
}
169
174
170
- protected String getClassPath () {
171
- String classpath ;
172
- classpath = JRT_CLASS_PATH_ENTRY ;
173
- String upgradeModulePath = System .getProperty ("jdk.module.upgrade.path" );
174
- if (upgradeModulePath != null ) {
175
- classpath += File .pathSeparator + upgradeModulePath ;
176
- }
177
-
178
- // Also process classes that go into the libgraal native image.
175
+ Path getLibgraalJar () {
176
+ assert shouldVerifyLibGraalInvariants ();
179
177
String javaClassPath = System .getProperty ("java.class.path" );
180
178
if (javaClassPath != null ) {
181
- for (String path : javaClassPath .split (File .pathSeparator )) {
182
- if (path .contains ("libgraal" ) && !path .contains ("processor" ) && !path .contains ("management" )) {
183
- classpath += File .pathSeparator + path ;
179
+ String [] jcp = javaClassPath .split (File .pathSeparator );
180
+ for (String s : jcp ) {
181
+ Path path = Path .of (s );
182
+ if (s .endsWith (".jar" )) {
183
+ Path libgraal = path .getParent ().resolve ("libgraal.jar" );
184
+ if (Files .exists (libgraal )) {
185
+ return libgraal ;
186
+ }
184
187
}
185
188
}
189
+ throw new AssertionError (String .format ("Could not find libgraal.jar as sibling of a jar on java.class.path:%n %s" ,
190
+ Stream .of (jcp ).sorted ().collect (Collectors .joining ("\n " ))));
191
+ }
192
+ throw new AssertionError ("The java.class.path system property is missing" );
193
+ }
194
+
195
+ protected List <String > getClassPath () {
196
+ List <String > classpath = new ArrayList <>();
197
+ classpath .add (JRT_CLASS_PATH_ENTRY );
198
+ String upgradeModulePath = System .getProperty ("jdk.module.upgrade.path" );
199
+ if (upgradeModulePath != null ) {
200
+ classpath .addAll (List .of (upgradeModulePath .split (File .pathSeparator )));
201
+ }
202
+
203
+ if (shouldVerifyLibGraalInvariants ()) {
204
+ classpath .add (getLibgraalJar ().toString ());
186
205
}
187
206
return classpath ;
188
207
}
@@ -194,6 +213,10 @@ protected boolean shouldLoadClass(String className) {
194
213
return true ;
195
214
}
196
215
216
+ public boolean shouldVerifyLibGraalInvariants () {
217
+ return true ;
218
+ }
219
+
197
220
public boolean shouldVerifyFoldableMethods () {
198
221
return true ;
199
222
}
@@ -253,11 +276,11 @@ public static void runTest(InvariantsTool tool) {
253
276
254
277
Assume .assumeTrue (VerifyPhase .class .desiredAssertionStatus ());
255
278
256
- String bootclasspath = tool .getClassPath ();
257
- Assert .assertNotNull ("Cannot find boot class path" , bootclasspath );
279
+ List < String > classPath = tool .getClassPath ();
280
+ Assert .assertNotNull ("Cannot find class path" , classPath );
258
281
259
282
final List <String > classNames = new ArrayList <>();
260
- for (String path : bootclasspath . split ( File . pathSeparator ) ) {
283
+ for (String path : classPath ) {
261
284
if (tool .shouldProcess (path )) {
262
285
try {
263
286
if (path .equals (JRT_CLASS_PATH_ENTRY )) {
@@ -284,16 +307,17 @@ public static void runTest(InvariantsTool tool) {
284
307
}
285
308
});
286
309
} else {
287
- final ZipFile zipFile = new ZipFile (file );
288
- for (final Enumeration <? extends ZipEntry > entry = zipFile .entries (); entry .hasMoreElements ();) {
289
- final ZipEntry zipEntry = entry .nextElement ();
290
- String name = zipEntry .getName ();
291
- if (name .endsWith (".class" ) && !name .startsWith ("META-INF/versions/" )) {
292
- String className = name .substring (0 , name .length () - ".class" .length ()).replace ('/' , '.' );
293
- if (isInNativeImage (className ) || isGSON (className ) || isONNX (className )) {
294
- continue ;
310
+ try (ZipFile zipFile = new ZipFile (file )) {
311
+ for (final Enumeration <? extends ZipEntry > entry = zipFile .entries (); entry .hasMoreElements ();) {
312
+ final ZipEntry zipEntry = entry .nextElement ();
313
+ String name = zipEntry .getName ();
314
+ if (name .endsWith (".class" ) && !name .startsWith ("META-INF/versions/" )) {
315
+ String className = name .substring (0 , name .length () - ".class" .length ()).replace ('/' , '.' );
316
+ if (isInNativeImage (className ) || isGSON (className ) || isONNX (className )) {
317
+ continue ;
318
+ }
319
+ classNames .add (className );
295
320
}
296
- classNames .add (className );
297
321
}
298
322
}
299
323
}
@@ -303,7 +327,7 @@ public static void runTest(InvariantsTool tool) {
303
327
}
304
328
}
305
329
}
306
- Assert .assertFalse ("Could not find graal jars on boot class path: " + bootclasspath , classNames .isEmpty ());
330
+ Assert .assertFalse ("Could not find graal jars on class path: " + classPath , classNames .isEmpty ());
307
331
308
332
// Allows a subset of methods to be checked through use of a system property
309
333
String property = System .getProperty (CheckGraalInvariants .class .getName () + ".filters" );
@@ -336,7 +360,6 @@ public static void runTest(InvariantsTool tool) {
336
360
verifiers .add (new VerifyDebugUsage ());
337
361
verifiers .add (new VerifyVirtualizableUsage ());
338
362
verifiers .add (new VerifyUpdateUsages ());
339
- verifiers .add (new VerifyLibGraalContextChecks ());
340
363
verifiers .add (new VerifyWordFactoryUsage ());
341
364
verifiers .add (new VerifyBailoutUsage ());
342
365
verifiers .add (new VerifySystemPropertyUsage ());
@@ -357,7 +380,6 @@ public static void runTest(InvariantsTool tool) {
357
380
verifiers .add (new VerifyStringCaseUsage ());
358
381
verifiers .add (new VerifyMathAbs ());
359
382
verifiers .add (new VerifyLoopInfo ());
360
- verifiers .add (new VerifyRuntimeVersionFeature ());
361
383
verifiers .add (new VerifyGuardsStageUsages ());
362
384
verifiers .add (new VerifyAArch64RegisterUsages ());
363
385
VerifyAssertionUsage assertionUsages = null ;
@@ -368,6 +390,10 @@ public static void runTest(InvariantsTool tool) {
368
390
verifiers .add (assertionUsages );
369
391
}
370
392
393
+ if (tool .shouldVerifyLibGraalInvariants ()) {
394
+ verifiers .add (new VerifyLibGraalContextChecks ());
395
+ }
396
+
371
397
loadVerifiers (verifiers );
372
398
373
399
VerifyFoldableMethods foldableMethodsVerifier = new VerifyFoldableMethods ();
@@ -401,9 +427,14 @@ public static void runTest(InvariantsTool tool) {
401
427
ResolvedJavaType optionDescriptorsType = metaAccess .lookupJavaType (OptionDescriptors .class );
402
428
403
429
if (errors .isEmpty ()) {
430
+ ClassLoader cl = CheckGraalInvariants .class .getClassLoader ();
431
+ if (tool .shouldVerifyLibGraalInvariants ()) {
432
+ URL [] urls = {toURL (tool .getLibgraalJar ())};
433
+ cl = new URLClassLoader (urls , cl );
434
+ }
404
435
// Order outer classes before the inner classes
405
- classNames .sort (( String a , String b ) -> a . compareTo ( b ));
406
- List <Class <?>> classes = loadClasses (tool , metaAccess , classNames );
436
+ classNames .sort (Comparator . naturalOrder ( ));
437
+ List <Class <?>> classes = loadClasses (tool , metaAccess , classNames , cl );
407
438
for (Class <?> c : classes ) {
408
439
String className = c .getName ();
409
440
executor .execute (() -> {
@@ -491,7 +522,7 @@ public static void runTest(InvariantsTool tool) {
491
522
StringBuilder msg = new StringBuilder ();
492
523
String nl = String .format ("%n" );
493
524
for (String e : errors ) {
494
- if (msg .length () != 0 ) {
525
+ if (! msg .isEmpty () ) {
495
526
msg .append (nl );
496
527
}
497
528
msg .append (e );
@@ -500,6 +531,14 @@ public static void runTest(InvariantsTool tool) {
500
531
}
501
532
}
502
533
534
+ private static URL toURL (Path path ) {
535
+ try {
536
+ return path .toUri ().toURL ();
537
+ } catch (MalformedURLException e ) {
538
+ throw new GraalError (e );
539
+ }
540
+ }
541
+
503
542
@ SuppressWarnings ("unchecked" )
504
543
private static void loadVerifiers (List <VerifyPhase <CoreProviders >> verifiers ) {
505
544
for (VerifyPhase <CoreProviders > verifier : ServiceLoader .load (VerifyPhase .class )) {
@@ -578,14 +617,14 @@ private static boolean isONNX(String className) {
578
617
return className .contains ("ai.onnxruntime" );
579
618
}
580
619
581
- private static List <Class <?>> loadClasses (InvariantsTool tool , MetaAccessProvider metaAccess , List <String > classNames ) {
620
+ private static List <Class <?>> loadClasses (InvariantsTool tool , MetaAccessProvider metaAccess , List <String > classNames , ClassLoader cl ) {
582
621
List <Class <?>> classes = new ArrayList <>(classNames .size ());
583
622
for (String className : classNames ) {
584
623
if (!tool .shouldLoadClass (className )) {
585
624
continue ;
586
625
}
587
626
try {
588
- Class <?> c = Class .forName (className , false , CheckGraalInvariants . class . getClassLoader () );
627
+ Class <?> c = Class .forName (className , false , cl );
589
628
590
629
/*
591
630
* Ensure all types are linked eagerly, so that we can access the bytecode of all
@@ -806,7 +845,7 @@ public boolean supportsLazyInitialization(ConstantPool cp) {
806
845
807
846
@ Override
808
847
public void loadReferencedType (GraphBuilderContext builder , ConstantPool cp , int cpi , int bytecode ) {
809
- (( HotSpotConstantPool ) cp ) .loadReferencedType (cpi , bytecode , false );
848
+ cp .loadReferencedType (cpi , bytecode , false );
810
849
}
811
850
812
851
@ Override
0 commit comments