|
|
@@ -1588,7 +1588,7 @@ GlobOpt::OptArguments(IR::Instr *instr)
|
|
|
if (CurrentBlockData()->IsArgumentsOpnd(src1))
|
|
|
{
|
|
|
instr->usesStackArgumentsObject = true;
|
|
|
- instr->m_func->unoptableInlineArgCount++;
|
|
|
+ instr->m_func->unoptimizableArgumentsObjReference++;
|
|
|
}
|
|
|
|
|
|
if (CurrentBlockData()->IsArgumentsOpnd(src1) &&
|
|
|
@@ -1608,7 +1608,7 @@ GlobOpt::OptArguments(IR::Instr *instr)
|
|
|
if (builtinFunction == Js::BuiltinFunction::JavascriptFunction_Apply)
|
|
|
{
|
|
|
CurrentBlockData()->ClearArgumentsSym(src1->AsRegOpnd());
|
|
|
- instr->m_func->unoptableInlineArgCount--;
|
|
|
+ instr->m_func->unoptimizableArgumentsObjReference--;
|
|
|
}
|
|
|
}
|
|
|
else if (builtinOpnd->IsRegOpnd())
|
|
|
@@ -1616,7 +1616,7 @@ GlobOpt::OptArguments(IR::Instr *instr)
|
|
|
if (builtinOpnd->AsRegOpnd()->m_sym->m_builtInIndex == Js::BuiltinFunction::JavascriptFunction_Apply)
|
|
|
{
|
|
|
CurrentBlockData()->ClearArgumentsSym(src1->AsRegOpnd());
|
|
|
- instr->m_func->unoptableInlineArgCount--;
|
|
|
+ instr->m_func->unoptimizableArgumentsObjReference--;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -2449,7 +2449,7 @@ GlobOpt::OptInstr(IR::Instr *&instr, bool* isInstrRemoved)
|
|
|
OptimizeChecks(instr);
|
|
|
OptArraySrc(&instr, &src1Val, &src2Val);
|
|
|
OptNewScObject(&instr, src1Val);
|
|
|
- OptArgLenAndConst(instr, &src1Val);
|
|
|
+ OptStackArgLenAndConst(instr, &src1Val);
|
|
|
|
|
|
instr = this->OptPeep(instr, src1Val, src2Val);
|
|
|
|
|
|
@@ -13206,15 +13206,21 @@ GlobOpt::OptArraySrc(IR::Instr ** const instrRef, Value ** src1Val, Value ** src
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-GlobOpt::OptArgLenAndConst(IR::Instr* instr, Value** src1Val)
|
|
|
+GlobOpt::OptStackArgLenAndConst(IR::Instr* instr, Value** src1Val)
|
|
|
{
|
|
|
- if (instr->usesStackArgumentsObject && instr->IsInlined())
|
|
|
+ if (!PHASE_OFF(Js::StackArgLenConstOptPhase, instr->m_func) && instr->m_func->IsStackArgsEnabled() && instr->usesStackArgumentsObject && instr->IsInlined())
|
|
|
{
|
|
|
IR::Opnd* src1 = instr->GetSrc1();
|
|
|
- auto replaceInstr = [&](IR::Opnd* newopnd, Js::OpCode opCode = Js::OpCode::Ld_A)
|
|
|
+ auto replaceInstr = [&](IR::Opnd* newopnd, Js::OpCode opcode)
|
|
|
{
|
|
|
+ if (PHASE_TESTTRACE(Js::StackArgLenConstOptPhase, instr->m_func))
|
|
|
+ {
|
|
|
+ Output::Print(_u("Inlined function %s have replaced opcode %s with opcode %s for stack arg optimization. \n"), instr->m_func->GetJITFunctionBody()->GetDisplayName(),
|
|
|
+ Js::OpCodeUtil::GetOpCodeName(instr->m_opcode), Js::OpCodeUtil::GetOpCodeName(opcode));
|
|
|
+ Output::Flush();
|
|
|
+ }
|
|
|
this->CaptureByteCodeSymUses(instr);
|
|
|
- instr->m_opcode = opCode;
|
|
|
+ instr->m_opcode = opcode;
|
|
|
instr->ReplaceSrc1(newopnd);
|
|
|
if (instr->HasBailOutInfo())
|
|
|
{
|
|
|
@@ -13229,10 +13235,9 @@ GlobOpt::OptArgLenAndConst(IR::Instr* instr, Value** src1Val)
|
|
|
case Js::OpCode::LdLen_A:
|
|
|
{
|
|
|
IR::AddrOpnd* newopnd = IR::AddrOpnd::New(Js::TaggedInt::ToVarUnchecked(instr->m_func->actualCount - 1), IR::AddrOpndKindConstantVar, instr->m_func);
|
|
|
- replaceInstr(newopnd);
|
|
|
+ replaceInstr(newopnd, Js::OpCode::Ld_A);
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
case Js::OpCode::LdElemI_A:
|
|
|
case Js::OpCode::TypeofElem:
|
|
|
{
|
|
|
@@ -13251,26 +13256,32 @@ GlobOpt::OptArgLenAndConst(IR::Instr* instr, Value** src1Val)
|
|
|
}
|
|
|
return false;
|
|
|
});
|
|
|
+
|
|
|
+ Js::OpCode replacementOpcode;
|
|
|
+ if (instr->m_opcode == Js::OpCode::TypeofElem)
|
|
|
+ {
|
|
|
+ replacementOpcode = Js::OpCode::Typeof;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ replacementOpcode = Js::OpCode::Ld_A;
|
|
|
+ }
|
|
|
+
|
|
|
// If we cannot find the right instruction. I.E. When calling arguments[2] and no arguments were passed to the func
|
|
|
if (defInstr == nullptr)
|
|
|
{
|
|
|
IR::Opnd * undefined = IR::AddrOpnd::New(instr->m_func->GetScriptContextInfo()->GetUndefinedAddr(), IR::AddrOpndKindDynamicVar, instr->m_func, true);
|
|
|
undefined->SetValueType(ValueType::Undefined);
|
|
|
- replaceInstr(undefined);
|
|
|
+ replaceInstr(undefined, replacementOpcode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if (instr->m_opcode == Js::OpCode::TypeofElem) {
|
|
|
- replaceInstr(defInstr->GetSrc1(), Js::OpCode::Typeof);
|
|
|
- }
|
|
|
- else {
|
|
|
- replaceInstr(defInstr->GetSrc1());
|
|
|
- }
|
|
|
+ replaceInstr(defInstr->GetSrc1(), replacementOpcode);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- instr->m_func->unoptableInlineArgCount++;
|
|
|
+ instr->m_func->unoptimizableArgumentsObjReference++;
|
|
|
}
|
|
|
break;
|
|
|
}
|