2525package com .oracle .svm .jni ;
2626
2727import org .graalvm .compiler .api .replacements .Fold ;
28+ import org .graalvm .compiler .nodes .extended .BranchProbabilityNode ;
2829import org .graalvm .compiler .word .Word ;
2930import org .graalvm .nativeimage .CurrentIsolate ;
3031import org .graalvm .nativeimage .Isolate ;
@@ -112,22 +113,27 @@ private static ThreadLocalHandles<ObjectHandle> createLocals() {
112113 }
113114
114115 @ SuppressWarnings ("unchecked" )
116+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
115117 private static ThreadLocalHandles <ObjectHandle > getExistingLocals () {
116118 return handles .get ();
117119 }
118120
121+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
119122 private static boolean isInLocalRange (JNIObjectHandle handle ) {
120123 return ThreadLocalHandles .isInRange ((ObjectHandle ) handle );
121124 }
122125
126+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
123127 private static ObjectHandle decodeLocal (JNIObjectHandle handle ) {
124128 return (ObjectHandle ) handle ;
125129 }
126130
131+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
127132 private static JNIObjectHandle encodeLocal (ObjectHandle handle ) {
128133 return (JNIObjectHandle ) handle ;
129134 }
130135
136+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
131137 public static <T > T getObject (JNIObjectHandle handle ) {
132138 if (handle .equal (nullHandle ())) {
133139 return null ;
@@ -138,10 +144,18 @@ public static <T> T getObject(JNIObjectHandle handle) {
138144 if (useImageHeapHandles () && JNIImageHeapHandles .isInRange (handle )) {
139145 return JNIImageHeapHandles .getObject (handle );
140146 }
147+ return getObjectSlow (handle );
148+ }
149+
150+ @ Uninterruptible (reason = "Not really, but our caller is to allow inlining and we must be safe at this point." , calleeMustBe = false )
151+ private static <T > T getObjectSlow (JNIObjectHandle handle ) {
152+ return getObjectSlow0 (handle );
153+ }
154+
155+ private static <T > T getObjectSlow0 (JNIObjectHandle handle ) {
141156 if (JNIGlobalHandles .isInRange (handle )) {
142157 return JNIGlobalHandles .getObject (handle );
143158 }
144-
145159 throw throwIllegalArgumentException ();
146160 }
147161
@@ -163,10 +177,30 @@ public static JNIObjectRefType getHandleType(JNIObjectHandle handle) {
163177 return JNIObjectRefType .Invalid ; // intentionally includes the null handle
164178 }
165179
180+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
166181 public static JNIObjectHandle createLocal (Object obj ) {
182+ if (obj == null ) {
183+ return JNIObjectHandles .nullHandle ();
184+ }
167185 if (useImageHeapHandles () && JNIImageHeapHandles .isInImageHeap (obj )) {
168186 return JNIImageHeapHandles .asLocal (obj );
169187 }
188+ ThreadLocalHandles <ObjectHandle > locals = getExistingLocals ();
189+ if (BranchProbabilityNode .probability (BranchProbabilityNode .VERY_FAST_PATH_PROBABILITY , locals != null )) {
190+ ObjectHandle handle = locals .tryCreateNonNull (obj );
191+ if (BranchProbabilityNode .probability (BranchProbabilityNode .FAST_PATH_PROBABILITY , handle .notEqual (nullHandle ()))) {
192+ return encodeLocal (handle );
193+ }
194+ }
195+ return createLocalSlow (obj );
196+ }
197+
198+ @ Uninterruptible (reason = "Not really, but our caller is uninterruptible for inlining and we must be safe at this point." , calleeMustBe = false )
199+ private static JNIObjectHandle createLocalSlow (Object obj ) {
200+ return createLocalSlow0 (obj );
201+ }
202+
203+ private static JNIObjectHandle createLocalSlow0 (Object obj ) {
170204 return encodeLocal (getOrCreateLocals ().create (obj ));
171205 }
172206
@@ -269,6 +303,7 @@ final class JNIGlobalHandles {
269303 private static final SignedWord MSB = WordFactory .signed (1L << 63 );
270304 private static final ObjectHandlesImpl globalHandles = new ObjectHandlesImpl (JNIObjectHandles .nullHandle ().add (1 ), HANDLE_BITS_MASK , JNIObjectHandles .nullHandle ());
271305
306+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
272307 static boolean isInRange (JNIObjectHandle handle ) {
273308 return MIN_VALUE .lessOrEqual ((SignedWord ) handle ) && MAX_VALUE .greaterThan ((SignedWord ) handle );
274309 }
@@ -355,15 +390,18 @@ final class JNIImageHeapHandles {
355390 assert ENTIRE_RANGE_MAX .lessThan (JNIGlobalHandles .MIN_VALUE ) || ENTIRE_RANGE_MIN .greaterThan (JNIGlobalHandles .MAX_VALUE );
356391 }
357392
393+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
358394 static boolean isInImageHeap (Object target ) {
359395 return target != null && Heap .getHeap ().isInImageHeap (target );
360396 }
361397
398+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
362399 static boolean isInRange (JNIObjectHandle handle ) {
363400 SignedWord handleValue = (SignedWord ) handle ;
364401 return handleValue .greaterOrEqual (ENTIRE_RANGE_MIN ) && handleValue .lessOrEqual (ENTIRE_RANGE_MAX );
365402 }
366403
404+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
367405 static JNIObjectHandle asLocal (Object target ) {
368406 assert isInImageHeap (target );
369407 SignedWord base = (SignedWord ) Isolates .getHeapBase (CurrentIsolate .getIsolate ());
@@ -390,6 +428,7 @@ private static JNIObjectHandle toRange(JNIObjectHandle handle, SignedWord rangeM
390428 return (JNIObjectHandle ) ((SignedWord ) handle ).and (OBJ_OFFSET_BITS_MASK ).add (rangeMin );
391429 }
392430
431+ @ Uninterruptible (reason = "Allow inlining from entry points, which are uninterruptible." , mayBeInlined = true )
393432 static <T > T getObject (JNIObjectHandle handle ) {
394433 assert isInRange (handle );
395434 UnsignedWord base = (UnsignedWord ) Isolates .getHeapBase (CurrentIsolate .getIsolate ());
0 commit comments