42
42
import java .util .List ;
43
43
import java .util .Objects ;
44
44
45
+ import com .oracle .svm .hosted .substitute .SubstitutionType ;
45
46
import org .graalvm .nativeimage .AnnotationAccess ;
46
47
47
48
import com .oracle .graal .pointsto .constraints .TypeInstantiationException ;
@@ -180,6 +181,7 @@ public abstract static class SharedBytecodeParser extends BytecodeParser {
180
181
private static final Class <?> SCOPED_SUBSTRATE_ANNOTATION ;
181
182
private static final Executable SESSION_EXCEPTION_HANDLER_METHOD ;
182
183
private static final Class <?> MAPPED_MEMORY_UTILS_PROXY_CLASS ;
184
+ private static final Class <?> ABSTRACT_MEMORY_SEGMENT_IMPL_CLASS ;
183
185
184
186
static {
185
187
SCOPED_SUBSTRATE_ANNOTATION = ReflectionUtil .lookupClass (true , "com.oracle.svm.core.foreign.Target_jdk_internal_misc_ScopedMemoryAccess_Scoped" );
@@ -188,6 +190,7 @@ public abstract static class SharedBytecodeParser extends BytecodeParser {
188
190
? ReflectionUtil .lookupMethod (substrateForeignUtilClass , "sessionExceptionHandler" , MemorySessionImpl .class , Object .class , long .class )
189
191
: null ;
190
192
MAPPED_MEMORY_UTILS_PROXY_CLASS = ReflectionUtil .lookupClass (true , "jdk.internal.access.foreign.MappedMemoryUtilsProxy" );
193
+ ABSTRACT_MEMORY_SEGMENT_IMPL_CLASS = ReflectionUtil .lookupClass (true , "jdk.internal.foreign.AbstractMemorySegmentImpl" );
191
194
}
192
195
193
196
protected List <ValueNode > scopedMemorySessions ;
@@ -420,12 +423,16 @@ private static List<SessionCheck> getSessionArguments(ResolvedJavaMethod method,
420
423
assert method != null ;
421
424
final ResolvedJavaType sessionType = ((AnalysisType ) metaAccess .lookupJavaType (MemorySessionImpl .class )).getWrapped ();
422
425
assert sessionType != null ;
426
+ final ResolvedJavaType abstractSegmentImpl = ((AnalysisType ) metaAccess .lookupJavaType (ABSTRACT_MEMORY_SEGMENT_IMPL_CLASS )).getWrapped ();
427
+ assert abstractSegmentImpl != null ;
423
428
final ResolvedJavaType baseType = ((AnalysisType ) metaAccess .lookupJavaType (Object .class )).getWrapped ();
424
429
assert baseType != null ;
425
430
final ResolvedJavaType offsetType = ((AnalysisType ) metaAccess .lookupJavaType (long .class )).getWrapped ();
426
431
assert offsetType != null ;
427
432
final ResolvedJavaType utilsType = ((AnalysisType ) metaAccess .lookupJavaType (MAPPED_MEMORY_UTILS_PROXY_CLASS )).getWrapped ();
428
433
assert utilsType != null ;
434
+ final ResolvedJavaType classType = ((SubstitutionType ) ((AnalysisType ) metaAccess .lookupJavaType (Class .class )).getWrapped ()).getOriginal ();
435
+ assert classType != null ;
429
436
430
437
Parameter [] p = method .getParameters ();
431
438
if (!p [0 ].getType ().equals (sessionType )) {
@@ -464,11 +471,43 @@ private static List<SessionCheck> getSessionArguments(ResolvedJavaMethod method,
464
471
} else {
465
472
// 1 session case
466
473
ValueNode session = graph .getParameter (pIndex ++);
467
- ValueNode base = graph .getParameter (pIndex ++);
468
- ValueNode offset = graph .getParameter (pIndex ++);
469
- SessionCheck check = new SessionCheck (session , base , offset );
470
- verifySession (sessionType , baseType , offsetType , check , metaAccess );
471
- return List .of (check );
474
+ if (p [1 ].getType ().equals (classType )) {
475
+ // example with a vmClass -
476
+ // storeIntoMemorySegmentScopedInternal(MemorySessionImpl session,
477
+ // Class<? extends V> vmClass, Class<E> e, int length,V v,
478
+ // AbstractMemorySegmentImpl msp, long offset,
479
+
480
+ /*
481
+ * For all patterns involving a vmClass the following holds: session is always
482
+ * p[0], and vmClass is always p[1]. However, in between we can have Class<E> e,
483
+ * int length, V v, M m then msp, offset, M m, S s, offsetInRange etc.
484
+ *
485
+ * We always map AbstractMemorySegmentImpl msp to base and offset to offset
486
+ * (which always comes after). There can be arguments after offset which we
487
+ * ignore. And we skip all arguments between vmClass and msp. So any arg between
488
+ * vmClass and msp can be skipped.
489
+ *
490
+ * If any of these invariants stops holding the verifySession call below will
491
+ * fail hard and we will be noticed of new/changed API.
492
+ */
493
+ while (!p [pIndex ].getType ().equals (abstractSegmentImpl )) {
494
+ pIndex ++;
495
+ }
496
+
497
+ // use msp as base and offset as offset
498
+ ValueNode base = graph .getParameter (pIndex ++); // use msp
499
+ ValueNode offset = graph .getParameter (pIndex ++);
500
+
501
+ SessionCheck check = new SessionCheck (session , base , offset );
502
+ verifySession (sessionType , baseType , offsetType , check , metaAccess );
503
+ return List .of (check );
504
+ } else {
505
+ ValueNode base = graph .getParameter (pIndex ++);
506
+ ValueNode offset = graph .getParameter (pIndex ++);
507
+ SessionCheck check = new SessionCheck (session , base , offset );
508
+ verifySession (sessionType , baseType , offsetType , check , metaAccess );
509
+ return List .of (check );
510
+ }
472
511
}
473
512
}
474
513
0 commit comments