1344477 - Part 1: Add JSOP_CALL_IGNORES_RV for function call that ignores return value.

This commit is contained in:
Gaming4JC 2019-07-14 19:04:34 -04:00 committed by Roy Tam
commit 417aa02122
22 changed files with 243 additions and 92 deletions

View file

@ -1939,6 +1939,7 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_funapply(GET_ARGC(pc));
case JSOP_CALL:
case JSOP_CALL_IGNORES_RV:
case JSOP_CALLITER:
case JSOP_NEW:
case JSOP_SUPERCALL:
@ -1946,7 +1947,8 @@ IonBuilder::inspectOpcode(JSOp op)
if (!outermostBuilder()->iterators_.append(current->peek(-1)))
return false;
}
return jsop_call(GET_ARGC(pc), (JSOp)*pc == JSOP_NEW || (JSOp)*pc == JSOP_SUPERCALL);
return jsop_call(GET_ARGC(pc), (JSOp)*pc == JSOP_NEW || (JSOp)*pc == JSOP_SUPERCALL,
(JSOp)*pc == JSOP_CALL_IGNORES_RV);
case JSOP_EVAL:
case JSOP_STRICTEVAL:
@ -5872,7 +5874,7 @@ IonBuilder::inlineGenericFallback(JSFunction* target, CallInfo& callInfo, MBasic
return false;
// Create a new CallInfo to track modified state within this block.
CallInfo fallbackInfo(alloc(), callInfo.constructing());
CallInfo fallbackInfo(alloc(), callInfo.constructing(), callInfo.ignoresReturnValue());
if (!fallbackInfo.init(callInfo))
return false;
fallbackInfo.popFormals(fallbackBlock);
@ -5911,7 +5913,7 @@ IonBuilder::inlineObjectGroupFallback(CallInfo& callInfo, MBasicBlock* dispatchB
MOZ_ASSERT(cache->idempotent());
// Create a new CallInfo to track modified state within the fallback path.
CallInfo fallbackInfo(alloc(), callInfo.constructing());
CallInfo fallbackInfo(alloc(), callInfo.constructing(), callInfo.ignoresReturnValue());
if (!fallbackInfo.init(callInfo))
return false;
@ -6087,7 +6089,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const ObjectVector& targets, BoolVec
inlineBlock->rewriteSlot(funIndex, funcDef);
// Create a new CallInfo to track modified state within the inline block.
CallInfo inlineInfo(alloc(), callInfo.constructing());
CallInfo inlineInfo(alloc(), callInfo.constructing(), callInfo.ignoresReturnValue());
if (!inlineInfo.init(callInfo))
return false;
inlineInfo.popFormals(inlineBlock);
@ -6536,7 +6538,8 @@ IonBuilder::jsop_funcall(uint32_t argc)
TemporaryTypeSet* calleeTypes = current->peek(calleeDepth)->resultTypeSet();
JSFunction* native = getSingleCallTarget(calleeTypes);
if (!native || !native->isNative() || native->native() != &fun_call) {
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, argc))
return false;
return makeCall(native, callInfo);
@ -6561,7 +6564,8 @@ IonBuilder::jsop_funcall(uint32_t argc)
argc -= 1;
}
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, argc))
return false;
@ -6598,7 +6602,8 @@ IonBuilder::jsop_funapply(uint32_t argc)
TemporaryTypeSet* calleeTypes = current->peek(calleeDepth)->resultTypeSet();
JSFunction* native = getSingleCallTarget(calleeTypes);
if (argc != 2 || info().analysisMode() == Analysis_ArgumentsUsage) {
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, argc))
return false;
return makeCall(native, callInfo);
@ -6627,7 +6632,8 @@ IonBuilder::jsop_funapply(uint32_t argc)
return jsop_funapplyarray(argc);
}
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, argc))
return false;
return makeCall(native, callInfo);
@ -6736,7 +6742,8 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
// can inline the apply() target and don't care about the actual arguments
// that were passed in.
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
// Vp
MDefinition* vp = current->pop();
@ -6782,7 +6789,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
}
bool
IonBuilder::jsop_call(uint32_t argc, bool constructing)
IonBuilder::jsop_call(uint32_t argc, bool constructing, bool ignoresReturnValue)
{
startTrackingOptimizations();
@ -6808,7 +6815,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing)
if (calleeTypes && !getPolyCallTargets(calleeTypes, constructing, targets, 4))
return false;
CallInfo callInfo(alloc(), constructing);
CallInfo callInfo(alloc(), constructing, ignoresReturnValue);
if (!callInfo.init(current, argc))
return false;
@ -6944,7 +6951,8 @@ IonBuilder::makeCallHelper(JSFunction* target, CallInfo& callInfo)
}
MCall* call = MCall::New(alloc(), target, targetArgs + 1 + callInfo.constructing(),
callInfo.argc(), callInfo.constructing(), isDOMCall);
callInfo.argc(), callInfo.constructing(),
callInfo.ignoresReturnValue(), isDOMCall);
if (!call)
return nullptr;
@ -7045,7 +7053,7 @@ IonBuilder::jsop_eval(uint32_t argc)
// Emit a normal call if the eval has never executed. This keeps us from
// disabling compilation for the script when testing with --ion-eager.
if (calleeTypes && calleeTypes->empty())
return jsop_call(argc, /* constructing = */ false);
return jsop_call(argc, /* constructing = */ false, false);
JSFunction* singleton = getSingleCallTarget(calleeTypes);
if (!singleton)
@ -7061,7 +7069,8 @@ IonBuilder::jsop_eval(uint32_t argc)
if (info().funMaybeLazy()->isArrow())
return abort("Direct eval from arrow function");
CallInfo callInfo(alloc(), /* constructing = */ false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, argc))
return false;
callInfo.setImplicitlyUsedUnchecked();
@ -7100,7 +7109,8 @@ IonBuilder::jsop_eval(uint32_t argc)
current->push(dynamicName);
current->push(constant(UndefinedValue())); // thisv
CallInfo evalCallInfo(alloc(), /* constructing = */ false);
CallInfo evalCallInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!evalCallInfo.init(current, /* argc = */ 0))
return false;
@ -7117,7 +7127,7 @@ IonBuilder::jsop_eval(uint32_t argc)
return resumeAfter(ins) && pushTypeBarrier(ins, types, BarrierKind::TypeSet);
}
return jsop_call(argc, /* constructing = */ false);
return jsop_call(argc, /* constructing = */ false, false);
}
bool
@ -11999,7 +12009,8 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName
current->push(obj);
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, 0))
return false;
@ -12494,7 +12505,8 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj,
// Call the setter. Note that we have to push the original value, not
// the setter's return value.
CallInfo callInfo(alloc(), false);
CallInfo callInfo(alloc(), /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
if (!callInfo.init(current, 1))
return false;