@@ -3200,6 +3200,29 @@ static char *suffixedName(char *baseName, char typeSuffix, char *buf, int32_t bu
3200
3200
return methodName;
3201
3201
}
3202
3202
3203
+ static int32_t countParams (unsigned char *sig)
3204
+ {
3205
+ sig++; // skip opening brace
3206
+ int32_t count = 0 ;
3207
+ while (*sig != ' )' )
3208
+ {
3209
+ while (*sig == ' [' )
3210
+ {
3211
+ sig++;
3212
+ }
3213
+ if (*sig == ' L' )
3214
+ {
3215
+ while (*sig != ' ;' )
3216
+ {
3217
+ sig++;
3218
+ }
3219
+ }
3220
+ count++;
3221
+ sig++;
3222
+ }
3223
+ return count;
3224
+ }
3225
+
3203
3226
void
3204
3227
TR_J9ByteCodeIlGenerator::genInvokeDynamic (int32_t callSiteIndex)
3205
3228
{
@@ -3210,7 +3233,7 @@ TR_J9ByteCodeIlGenerator::genInvokeDynamic(int32_t callSiteIndex)
3210
3233
{
3211
3234
comp ()->failCompilation <J9::AOTHasInvokeHandle>(" COMPILATION_AOT_HAS_INVOKEHANDLE 0" );
3212
3235
}
3213
- // Call generated when call site table entry is resolved:
3236
+ // Call generated when call site table entry is resolved and appendix object is non-null :
3214
3237
// -----------------------------------------------------
3215
3238
// call <target method obtained from memberName object>
3216
3239
// arg0
@@ -3261,7 +3284,33 @@ TR_J9ByteCodeIlGenerator::genInvokeDynamic(int32_t callSiteIndex)
3261
3284
if (comp ()->getOption (TR_TraceILGen))
3262
3285
printStack (comp (), _stack, " (Stack after load from callsite table)" );
3263
3286
3264
- TR::Node* callNode = genInvokeDirect (targetMethodSymRef);
3287
+ /* We need to get the expected number of parameters from the signature. There is a case where findOrCreateDynamicMethodSymbol()
3288
+ * returns an error-throwing MethodHandle that takes 0 arguments (occurs when an error is caught during resolveInvokeDynamic()). We cannot use
3289
+ * TR::Method::numberOfExplicitParameters() since that fetches the number of parameters of targetMethodSymRefs (the MH actually returned)
3290
+ * instead of whats expected the invokedynamic call. This can be a problem since the expcected of args are already on the stack and won't be
3291
+ * properly popped.
3292
+ */
3293
+ int32_t paramCount = 0 ;
3294
+ if (isUnresolved)
3295
+ {
3296
+ // we need both appendix and membername objects ==> we have at least 2 args
3297
+ paramCount = 2 ;
3298
+ }
3299
+ else
3300
+ {
3301
+ // we only need to account for the appendix object if it is non-null
3302
+ paramCount = (isInvokeCacheAppendixNull ? 0 : 1 );
3303
+ }
3304
+
3305
+ TR_ResolvedJ9Method* ownerMethod = static_cast <TR_ResolvedJ9Method *>(_methodSymbol->getResolvedMethod ());
3306
+ J9ROMClass *ownerROMMethod = ownerMethod->romClassPtr ();
3307
+ J9SRP *callSiteData = (J9SRP *) J9ROMCLASS_CALLSITEDATA (ownerROMMethod);
3308
+ J9ROMNameAndSignature *nameAndSig = SRP_PTR_GET (callSiteData + callSiteIndex, J9ROMNameAndSignature*);
3309
+ J9UTF8* sig = J9ROMNAMEANDSIGNATURE_SIGNATURE (nameAndSig);
3310
+ // count params gets the number of explicit parameters and does not include the appendix and/or membername objects
3311
+ paramCount += countParams (J9UTF8_DATA (sig));
3312
+
3313
+ TR::Node* callNode = genInvokeDirect (targetMethodSymRef, paramCount);
3265
3314
3266
3315
#else
3267
3316
if (comp ()->compileRelocatableCode ())
@@ -3659,11 +3708,11 @@ static TR::SymbolReference * getPrimitiveValueFieldSymbolReference(TR_J9ByteCode
3659
3708
}
3660
3709
3661
3710
TR::Node*
3662
- TR_J9ByteCodeIlGenerator::genInvoke (TR::SymbolReference * symRef, TR::Node *indirectCallFirstChild, TR::Node *invokedynamicReceiver)
3711
+ TR_J9ByteCodeIlGenerator::genInvoke (TR::SymbolReference * symRef, TR::Node *indirectCallFirstChild, TR::Node *invokedynamicReceiver, int32_t numExpectedArgs )
3663
3712
{
3664
3713
TR::KnownObjectTable::Index requiredKoi;
3665
3714
TR::Node *callNode = genInvokeInner (
3666
- symRef, indirectCallFirstChild, invokedynamicReceiver, &requiredKoi);
3715
+ symRef, indirectCallFirstChild, invokedynamicReceiver, &requiredKoi, numExpectedArgs );
3667
3716
3668
3717
if (requiredKoi == TR::KnownObjectTable::UNKNOWN)
3669
3718
return callNode;
@@ -3682,7 +3731,8 @@ TR_J9ByteCodeIlGenerator::genInvokeInner(
3682
3731
TR::SymbolReference * symRef,
3683
3732
TR::Node *indirectCallFirstChild,
3684
3733
TR::Node *invokedynamicReceiver,
3685
- TR::KnownObjectTable::Index *requiredKoi)
3734
+ TR::KnownObjectTable::Index *requiredKoi,
3735
+ int32_t numExpectedArgs)
3686
3736
{
3687
3737
TR::MethodSymbol * symbol = symRef->getSymbol ()->castToMethodSymbol ();
3688
3738
bool isStatic = symbol->isStatic ();
@@ -3691,6 +3741,12 @@ TR_J9ByteCodeIlGenerator::genInvokeInner(
3691
3741
TR::Method * calledMethod = symbol->getMethod ();
3692
3742
int32_t numArgs = calledMethod->numberOfExplicitParameters () + (isStatic ? 0 : 1 );
3693
3743
3744
+ // need to track stack size at beginning and end of ILGeneration for invokeDynamic for the case
3745
+ // where we get the special error throwing MethodHandle
3746
+ int32_t startingStackSize = _stack->size ();
3747
+ if (numExpectedArgs == -1 )
3748
+ numExpectedArgs = numArgs;
3749
+
3694
3750
if (pushRequiredConst (requiredKoi))
3695
3751
{
3696
3752
TR::Node *result = pop ();
@@ -4601,6 +4657,22 @@ break
4601
4657
else
4602
4658
resultNode = callNode;
4603
4659
4660
+ /* There is a case where findOrCreateDynamicMethodSymbol() returns an error-throwing MethodHandle that
4661
+ * takes 0 arguments (occurs when an error is thrown during resolveInvokeDynamic()). In that case, we will not have
4662
+ * popped all the arguments off the stack, so we need to pop the expected number.
4663
+ */
4664
+ int32_t numPopped = startingStackSize - _stack->size ();
4665
+ if (numPopped < numExpectedArgs)
4666
+ {
4667
+ if (comp ()->getOption (TR_TraceILGen))
4668
+ traceMsg (comp (), " InvokeDynamic recieved error throwing MethodHandle. Popping extra args.\n " );
4669
+ while (numPopped < numExpectedArgs)
4670
+ {
4671
+ pop ();
4672
+ numPopped++;
4673
+ }
4674
+ }
4675
+
4604
4676
TR::DataType returnType = calledMethod->returnType ();
4605
4677
if (returnType != TR::NoType)
4606
4678
{
0 commit comments