Skip to content

Commit 8a1490e

Browse files
authored
Update JNIObjectHandles.java
In JNIGlobalHandles created 2 instances of ObjectHandlesImpl (one for strong and one for weak hadles). I divided the total global handels range into two halfs at bit 62. Bit 62 is 0 for strong global handles and 1 for weak global handles. Therefore a validation tag is redused from 32 bit to 31 bit
1 parent 20e8743 commit 8a1490e

File tree

1 file changed

+61
-17
lines changed

1 file changed

+61
-17
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
* </ul>
6666
*/
6767
public final class JNIObjectHandles {
68-
@Fold
68+
@Fold // replaces with true/false at compile time and removes unnecessary runtime checks
6969
static boolean haveAssertions() {
7070
return RuntimeAssertionsSupport.singleton().desiredAssertionStatus(JNIObjectHandles.class);
7171
}
@@ -219,15 +219,15 @@ public static void deleteLocalRef(JNIObjectHandle localRef) {
219219
getOrCreateLocals().delete(decodeLocal(localRef));
220220
}
221221
}
222-
222+
// in frames are local handles stored
223223
public static int pushLocalFrame(int capacity) {
224224
return getOrCreateLocals().pushFrame(capacity);
225225
}
226226

227227
public static void popLocalFrame() {
228228
getExistingLocals().popFrame();
229229
}
230-
230+
// pops frames down to a specific starting point identified by the int frame
231231
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
232232
public static void popLocalFramesIncluding(int frame) {
233233
getExistingLocals().popFramesIncluding(frame);
@@ -293,19 +293,36 @@ static long computeCurrentGlobalHandleCount() {
293293
* for example by native code that is unaware of isolates.
294294
*/
295295
final class JNIGlobalHandles {
296-
static final SignedWord MIN_VALUE = Word.signed(Long.MIN_VALUE);
297-
static final SignedWord MAX_VALUE = JNIObjectHandles.nullHandle().subtract(1);
296+
static final SignedWord MIN_VALUE = Word.signed(Long.MIN_VALUE); // -2^63
297+
static final SignedWord MAX_VALUE = JNIObjectHandles.nullHandle().subtract(1); // -1
298298
static {
299299
assert JNIObjectHandles.nullHandle().equal(Word.zero());
300300
}
301301

302+
// Handle=(MSB)+(Validation Tag)+(Handle Index)
302303
private static final int HANDLE_BITS_COUNT = 31;
303304
private static final SignedWord HANDLE_BITS_MASK = Word.signed((1L << HANDLE_BITS_COUNT) - 1);
304305
private static final int VALIDATION_BITS_SHIFT = HANDLE_BITS_COUNT;
305-
private static final int VALIDATION_BITS_COUNT = 32;
306+
private static final int VALIDATION_BITS_COUNT = 31;
306307
private static final SignedWord VALIDATION_BITS_MASK = Word.signed((1L << VALIDATION_BITS_COUNT) - 1).shiftLeft(VALIDATION_BITS_SHIFT);
308+
private static final SignedWord WEAK_HANDLE_FLAG = Word.signed(1L << 62);
307309
private static final SignedWord MSB = Word.signed(1L << 63);
308-
private static final ObjectHandlesImpl globalHandles = new ObjectHandlesImpl(JNIObjectHandles.nullHandle().add(1), HANDLE_BITS_MASK, JNIObjectHandles.nullHandle());
310+
311+
// Define the mid-point to split the range in half
312+
private static final SignedWord GLOBAL_RANGE_SPLIT_POINT = Word.signed(1L << 62);
313+
314+
// Strong global handles will occupy the lower half of the global handles range
315+
public static final SignedWord STRONG_GLOBAL_RANGE_MIN = MIN_VALUE;
316+
public static final SignedWord STRONG_GLOBAL_RANGE_MAX = GLOBAL_RANGE_SPLIT_POINT.substract(1);
317+
318+
// Weak global handles will occupy the upper half of the global handles range
319+
public static final SignedWord WEAK_GLOBAL_RANGE_MIN = GLOBAL_RANGE_SPLIT_POINT;
320+
public static final SignedWord WEAK_GLOBAL_RANGE_MAX = MAX_VALUE;
321+
322+
private static final ObjectHandlesImpl strongGlobalHandles
323+
= new ObjectHandlesImpl(STRONG_GLOBAL_RANGE_MIN.add(1), STRONG_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle());
324+
private static final ObjectHandlesImpl weakGlobalHandles
325+
= new ObjectHandlesImpl(WEAK_GLOBAL_RANGE_MIN.add(1), WEAK_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle());
309326

310327
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
311328
static boolean isInRange(JNIObjectHandle handle) {
@@ -317,7 +334,7 @@ private static Word isolateHash() {
317334
return Word.unsigned(isolateHash);
318335
}
319336

320-
private static JNIObjectHandle encode(ObjectHandle handle) {
337+
private static JNIObjectHandle encodeStrong(ObjectHandle handle) {
321338
SignedWord h = (Word) handle;
322339
if (JNIObjectHandles.haveAssertions()) {
323340
assert h.and(HANDLE_BITS_MASK).equal(h) : "unencoded handle must fit in range";
@@ -330,6 +347,20 @@ private static JNIObjectHandle encode(ObjectHandle handle) {
330347
return (JNIObjectHandle) h;
331348
}
332349

350+
private static JNIObjectHandle encodeWeak(ObjectHandle handle) {
351+
SignedWord h = (Word) handle;
352+
if (JNIObjectHandles.haveAssertions()) {
353+
assert h.and(HANDLE_BITS_MASK).equal(h) : "unencoded handle must fit in range";
354+
Word v = isolateHash().shiftLeft(VALIDATION_BITS_SHIFT);
355+
assert v.and(VALIDATION_BITS_MASK).equal(v) : "validation value must fit in its range";
356+
h = h.or(v);
357+
}
358+
h = h.or(MSB);
359+
h = h.or(WEAK_HANDLE_FLAG); // Set bit 62 to mark it as weak
360+
assert isInRange((JNIObjectHandle) h);
361+
return (JNIObjectHandle) h;
362+
}
363+
333364
private static ObjectHandle decode(JNIObjectHandle handle) {
334365
assert isInRange(handle);
335366
assert ((Word) handle).and(VALIDATION_BITS_MASK).unsignedShiftRight(VALIDATION_BITS_SHIFT)
@@ -338,35 +369,48 @@ private static ObjectHandle decode(JNIObjectHandle handle) {
338369
}
339370

340371
static <T> T getObject(JNIObjectHandle handle) {
341-
return globalHandles.get(decode(handle));
372+
SignedWord handleValue = (Word) handle;
373+
if (handleValue.greaterOrEqual(STRONG_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(STRONG_GLOBAL_RANGE_MAX)) {
374+
return strongGlobalHandles.get(decode(handle));
375+
}
376+
377+
if (handleValue.greaterOrEqual(WEAK_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(WEAK_GLOBAL_RANGE_MAX)) {
378+
return weakGlobalHandles.get(decode((handle)));
379+
}
380+
381+
throw throwIllegalArgumentException();
342382
}
343383

344384
static JNIObjectRefType getHandleType(JNIObjectHandle handle) {
345-
assert isInRange(handle);
346-
if (globalHandles.isWeak(decode(handle))) {
385+
SignedWord handleValue = (Word) handle;
386+
if (handleValue.greaterOrEqual(STRONG_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(STRONG_GLOBAL_RANGE_MAX)) {
387+
return JNIObjectRefType.Global;
388+
}
389+
390+
if (handleValue.greaterOrEqual(WEAK_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(WEAK_GLOBAL_RANGE_MAX)) {
347391
return JNIObjectRefType.WeakGlobal;
348392
}
349-
return JNIObjectRefType.Global;
393+
return JNIObjectRefType.Invalid;
350394
}
351395

352396
static JNIObjectHandle create(Object obj) {
353-
return encode(globalHandles.create(obj));
397+
return encodeStrong(strongGlobalHandles.create(obj));
354398
}
355399

356400
static void destroy(JNIObjectHandle handle) {
357-
globalHandles.destroy(decode(handle));
401+
strongGlobalHandles.destroy(decode(handle));
358402
}
359403

360404
static JNIObjectHandle createWeak(Object obj) {
361-
return encode(globalHandles.createWeak(obj));
405+
return encodeWeak(weakGlobalHandles.create(obj));
362406
}
363407

364408
static void destroyWeak(JNIObjectHandle weakRef) {
365-
globalHandles.destroyWeak(decode(weakRef));
409+
weakGlobalHandles.destroy(decode(weakRef));
366410
}
367411

368412
public static long computeCurrentCount() {
369-
return globalHandles.computeCurrentCount();
413+
return strongGlobalHandles.computeCurrentCount() + weakGlobalHandles.computeCurrentCount();
370414
}
371415
}
372416

0 commit comments

Comments
 (0)