Skip to content

Commit 67d644a

Browse files
committed
Clean up null checks for linkTo* methods in BytecodeInterpreter
Commons out null checks into on j9objects (mh receiver, mn obejct, etc) into nullcheck method with handles stack pointer restoration and builds the jit resolve frame when required Signed-off-by: Matthew Hall <[email protected]>
1 parent 3261650 commit 67d644a

File tree

1 file changed

+66
-68
lines changed

1 file changed

+66
-68
lines changed

runtime/vm/BytecodeInterpreter.hpp

+66-68
Original file line numberDiff line numberDiff line change
@@ -9532,7 +9532,21 @@ class INTERPRETER_CLASS
95329532
#endif /* defined(J9VM_OPT_METHOD_HANDLE) */
95339533
}
95349534

9535-
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
9535+
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
9536+
9537+
VMINLINE bool
9538+
j9ObjIsNull(j9object_t j9Obj, bool fromJIT, REGISTER_ARGS_LIST, UDATA decSP)
9539+
{
9540+
if (J9_UNEXPECTED(NULL == j9Obj)) {
9541+
if (fromJIT) {
9542+
_sp -= decSP;
9543+
buildJITResolveFrame(REGISTER_ARGS);
9544+
}
9545+
return true;
9546+
}
9547+
return false;
9548+
}
9549+
95369550
/* This INL only covers invokeBasic dispatched directly from bytecode, invokeBasic calls
95379551
* dispatched from linkToVirtual is inlined to avoid need of flags and tempValues to
95389552
* pass the correct argCount during VM transition since the ramCP index still points
@@ -9558,23 +9572,23 @@ class INTERPRETER_CLASS
95589572
mhReceiverIndex = (methodIndexAndArgCount & 0xFF);
95599573
}
95609574

9575+
j9object_t lambdaForm = NULL;
9576+
j9object_t memberName = NULL;
95619577
j9object_t mhReceiver = ((j9object_t *)_sp)[mhReceiverIndex];
9562-
if (J9_UNEXPECTED(NULL == mhReceiver)) {
9563-
if (fromJIT) {
9564-
buildJITResolveFrame(REGISTER_ARGS);
9565-
}
9566-
return THROW_NPE;
9578+
if (j9ObjIsNull(mhReceiver, fromJIT, REGISTER_ARGS, 0)) {
9579+
rc = THROW_NPE;
9580+
goto done;
95679581
}
95689582

9569-
j9object_t lambdaForm = J9VMJAVALANGINVOKEMETHODHANDLE_FORM(_currentThread, mhReceiver);
9570-
j9object_t memberName = J9VMJAVALANGINVOKELAMBDAFORM_VMENTRY(_currentThread, lambdaForm);
9583+
lambdaForm = J9VMJAVALANGINVOKEMETHODHANDLE_FORM(_currentThread, mhReceiver);
9584+
memberName = J9VMJAVALANGINVOKELAMBDAFORM_VMENTRY(_currentThread, lambdaForm);
95719585
_sendMethod = (J9Method *)(UDATA)J9OBJECT_U64_LOAD(_currentThread, memberName, _vm->vmtargetOffset);
95729586

95739587
if (fromJIT) {
95749588
VM_JITInterface::restoreJITReturnAddress(_currentThread, _sp, (void *)_literals);
95759589
rc = j2iTransition(REGISTER_ARGS, true);
95769590
}
9577-
9591+
done:
95789592
return rc;
95799593
}
95809594

@@ -9588,8 +9602,9 @@ class INTERPRETER_CLASS
95889602

95899603
/* Pop memberNameObject from the stack. */
95909604
j9object_t memberNameObject = *(j9object_t *)_sp++;
9591-
if (J9_UNEXPECTED(NULL == memberNameObject)) {
9592-
goto throw_npe;
9605+
if (j9ObjIsNull(memberNameObject, fromJIT, REGISTER_ARGS, true)) {
9606+
rc = THROW_NPE;
9607+
goto done;
95939608
}
95949609

95959610
_sendMethod = (J9Method *)(UDATA)J9OBJECT_U64_LOAD(_currentThread, memberNameObject, _vm->vmtargetOffset);
@@ -9600,8 +9615,9 @@ class INTERPRETER_CLASS
96009615

96019616
if (J9_ARE_NO_BITS_SET(romMethod->modifiers, J9AccStatic)) {
96029617
j9object_t mhReceiver = ((j9object_t *)_sp)[methodArgCount - 1];
9603-
if (J9_UNEXPECTED(NULL == mhReceiver)) {
9604-
goto throw_npe;
9618+
if (j9ObjIsNull(mhReceiver, false, REGISTER_ARGS, false)) {
9619+
rc = THROW_NPE;
9620+
goto done;
96059621
}
96069622
}
96079623
}
@@ -9642,38 +9658,33 @@ class INTERPRETER_CLASS
96429658
VM_JITInterface::restoreJITReturnAddress(_currentThread, _sp, (void *)_literals);
96439659
rc = j2iTransition(REGISTER_ARGS, true);
96449660
}
9645-
9661+
done:
96469662
return rc;
9647-
9648-
throw_npe:
9649-
if (fromJIT) {
9650-
/* Restore SP to before popping memberNameObject. */
9651-
_sp -= 1;
9652-
buildJITResolveFrame(REGISTER_ARGS);
9653-
}
9654-
return THROW_NPE;
96559663
}
96569664

96579665
VMINLINE VM_BytecodeAction
96589666
linkToVirtual(REGISTER_ARGS_LIST)
96599667
{
96609668
VM_BytecodeAction rc = GOTO_RUN_METHOD;
9669+
J9Method *method = NULL;
9670+
J9ROMMethod *romMethod = NULL;
9671+
UDATA methodArgCount = 0;
9672+
bool isInvokeBasic = false;
9673+
j9object_t receiverObject = NULL;
9674+
UDATA vTableOffset = 0;
9675+
J9Class *receiverClass = NULL;
96619676
bool fromJIT = J9_ARE_ANY_BITS_SET(jitStackFrameFlags(REGISTER_ARGS, 0), J9_SSF_JIT_NATIVE_TRANSITION_FRAME);
96629677

96639678
/* Pop memberNameObject from the stack. */
96649679
j9object_t memberNameObject = *(j9object_t *)_sp++;
9665-
if (J9_UNEXPECTED(NULL == memberNameObject)) {
9666-
if (fromJIT) {
9667-
/* Restore SP to before popping memberNameObject. */
9668-
_sp -= 1;
9669-
buildJITResolveFrame(REGISTER_ARGS);
9670-
}
9671-
return THROW_NPE;
9680+
if (j9ObjIsNull(memberNameObject, fromJIT, REGISTER_ARGS, true)) {
9681+
rc = THROW_NPE;
9682+
goto done;
96729683
}
96739684

9674-
J9Method *method = (J9Method *)(UDATA)J9OBJECT_U64_LOAD(_currentThread, memberNameObject, _vm->vmtargetOffset);
9675-
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
9676-
UDATA methodArgCount = 0;
9685+
method = (J9Method *)(UDATA)J9OBJECT_U64_LOAD(_currentThread, memberNameObject, _vm->vmtargetOffset);
9686+
romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
9687+
methodArgCount = 0;
96779688
bool isInvokeBasic = (J9_BCLOOP_SEND_TARGET_METHODHANDLE_INVOKEBASIC == J9_BCLOOP_DECODE_SEND_TARGET(method->methodRunAddress));
96789689

96799690
/* In MethodHandle.loop API it may generate a invokeBasic NamedFunction (see LambdaForm$NamedFunction(MethodType basicInvokerType))
@@ -9688,14 +9699,10 @@ class INTERPRETER_CLASS
96889699
methodArgCount = romMethod->argCount;
96899700
}
96909701

9691-
j9object_t receiverObject = ((j9object_t *)_sp)[methodArgCount - 1];
9692-
if (J9_UNEXPECTED(NULL == receiverObject)) {
9693-
if (fromJIT) {
9694-
/* Restore SP to before popping memberNameObject. */
9695-
_sp -= 1;
9696-
buildJITResolveFrame(REGISTER_ARGS);
9697-
}
9698-
return THROW_NPE;
9702+
receiverObject = ((j9object_t *)_sp)[methodArgCount - 1];
9703+
if (j9ObjIsNull(receiverObject, fromJIT, REGISTER_ARGS, true)) {
9704+
rc = THROW_NPE;
9705+
goto done;
96999706
}
97009707

97019708
/* The vTable offset has been stored in memberNameObject.vmindex.
@@ -9706,8 +9713,8 @@ class INTERPRETER_CLASS
97069713
* In that case, MemberName resolution has already done the iTable walk to get the corresponding vTable offset in
97079714
* C and stored it in vmindex. The receiver is always an instance of C (or a subclass).
97089715
*/
9709-
UDATA vTableOffset = (UDATA)J9OBJECT_U64_LOAD(_currentThread, memberNameObject, _vm->vmindexOffset);
9710-
J9Class *receiverClass = J9OBJECT_CLAZZ(_currentThread, receiverObject);
9716+
vTableOffset = (UDATA)J9OBJECT_U64_LOAD(_currentThread, memberNameObject, _vm->vmindexOffset);
9717+
receiverClass = J9OBJECT_CLAZZ(_currentThread, receiverObject);
97119718
_sendMethod = *(J9Method **)(((UDATA)receiverClass) + vTableOffset);
97129719

97139720
/* The invokeBasic INL uses the methodArgCount from ramCP to locate the receiver object,
@@ -9734,7 +9741,7 @@ class INTERPRETER_CLASS
97349741
VM_JITInterface::restoreJITReturnAddress(_currentThread, _sp, (void *)_literals);
97359742
rc = j2iTransition(REGISTER_ARGS, true);
97369743
}
9737-
9744+
done:
97389745
return rc;
97399746
}
97409747

@@ -9755,12 +9762,7 @@ class INTERPRETER_CLASS
97559762

97569763
/* Pop memberNameObject from the stack. */
97579764
j9object_t memberNameObject = *(j9object_t *)_sp++;
9758-
if (J9_UNEXPECTED(NULL == memberNameObject)) {
9759-
if (fromJIT) {
9760-
/* Restore SP to before popping memberNameObject. */
9761-
_sp -= 1;
9762-
buildJITResolveFrame(REGISTER_ARGS);
9763-
}
9765+
if (j9ObjIsNull(memberNameObject, fromJIT, REGISTER_ARGS, true)) {
97649766
rc = THROW_NPE;
97659767
goto done;
97669768
}
@@ -9770,12 +9772,7 @@ class INTERPRETER_CLASS
97709772
methodArgCount = romMethod->argCount;
97719773

97729774
receiverObject = ((j9object_t *)_sp)[methodArgCount - 1];
9773-
if (J9_UNEXPECTED(NULL == receiverObject)) {
9774-
if (fromJIT) {
9775-
/* Restore SP to before popping memberNameObject. */
9776-
_sp -= 1;
9777-
buildJITResolveFrame(REGISTER_ARGS);
9778-
}
9775+
if (j9ObjIsNull(receiverObject, fromJIT, REGISTER_ARGS, true)) {
97799776
rc = THROW_NPE;
97809777
goto done;
97819778
}
@@ -9853,6 +9850,11 @@ class INTERPRETER_CLASS
98539850
linkToNative(REGISTER_ARGS_LIST)
98549851
{
98559852
VM_BytecodeAction rc = GOTO_RUN_METHOD;
9853+
j9object_t nepObject = NULL;
9854+
j9object_t methodType = NULL;
9855+
j9object_t invokeCacheArray = NULL;
9856+
j9object_t memberName = NULL;
9857+
j9object_t appendix = NULL;
98569858
bool fromJIT = J9_ARE_ANY_BITS_SET(jitStackFrameFlags(REGISTER_ARGS, 0), J9_SSF_JIT_NATIVE_TRANSITION_FRAME);
98579859

98589860
/* Pop up the dummy argument (the placeholder for the method type of the bound MH)
@@ -9863,24 +9865,20 @@ class INTERPRETER_CLASS
98639865
}
98649866

98659867
j9object_t nativeMH = *(j9object_t *)_sp;
9866-
if (J9_UNEXPECTED(NULL == nativeMH)) {
9867-
if (fromJIT) {
9868-
/* Restore SP to before popping the dummy argument. */
9869-
_sp -= 1;
9870-
buildJITResolveFrame(REGISTER_ARGS);
9871-
}
9872-
return THROW_NPE;
9868+
if (j9ObjIsNull(nativeMH, fromJIT, REGISTER_ARGS, true)) {
9869+
rc = THROW_NPE;
9870+
goto done;
98739871
}
98749872

9875-
j9object_t nepObject = J9VMJAVALANGINVOKENATIVEMETHODHANDLE_NEP(_currentThread, nativeMH);
9876-
j9object_t methodType = J9VMJAVALANGINVOKEMETHODHANDLE_TYPE(_currentThread, nepObject);
9873+
nepObject = J9VMJAVALANGINVOKENATIVEMETHODHANDLE_NEP(_currentThread, nativeMH);
9874+
methodType = J9VMJAVALANGINVOKEMETHODHANDLE_TYPE(_currentThread, nepObject);
98779875
UDATA methodArgCount = VM_VMHelpers::methodTypeParameterSlotCount(_currentThread, methodType);
98789876

98799877
/* The cache array stores the data (memberName & appendix) for the bound MH which
98809878
* has been resolved when generating the downcall handler.
98819879
*/
9882-
j9object_t invokeCacheArray = J9VMJAVALANGINVOKENATIVEMETHODHANDLE_INVOKECACHE(_currentThread, nativeMH);
9883-
j9object_t memberName = (j9object_t)J9JAVAARRAYOFOBJECT_LOAD(_currentThread, invokeCacheArray, 0);
9880+
invokeCacheArray = J9VMJAVALANGINVOKENATIVEMETHODHANDLE_INVOKECACHE(_currentThread, nativeMH);
9881+
memberName = (j9object_t)J9JAVAARRAYOFOBJECT_LOAD(_currentThread, invokeCacheArray, 0);
98849882
_sendMethod = (J9Method *)(UDATA)J9OBJECT_U64_LOAD(_currentThread, memberName, _vm->vmtargetOffset);
98859883

98869884
/* Shift arguments by 1 and place the NEP object as the placeholder before the first argument
@@ -9889,7 +9887,7 @@ class INTERPRETER_CLASS
98899887
memmove(_sp, _sp + 1, methodArgCount * sizeof(UDATA));
98909888
_sp[methodArgCount] = (UDATA)nepObject;
98919889

9892-
j9object_t appendix = (j9object_t)J9JAVAARRAYOFOBJECT_LOAD(_currentThread, invokeCacheArray, 1);
9890+
appendix = (j9object_t)J9JAVAARRAYOFOBJECT_LOAD(_currentThread, invokeCacheArray, 1);
98939891
/* The slot the dummy argument is replaced with the method type to ensure it works with
98949892
* and without JIT in terms of the argument count.
98959893
*/
@@ -9899,7 +9897,7 @@ class INTERPRETER_CLASS
98999897
VM_JITInterface::restoreJITReturnAddress(_currentThread, _sp, (void *)_literals);
99009898
rc = j2iTransition(REGISTER_ARGS, true);
99019899
}
9902-
9900+
done:
99039901
return rc;
99049902
}
99059903
#endif /* JAVA_SPEC_VERSION >= 22 */

0 commit comments

Comments
 (0)