@@ -7107,6 +7107,57 @@ Lowerer::LowerStFld(
71077107 IR::Opnd *dst = stFldInstr->UnlinkDst();
71087108 AssertMsg(dst->IsSymOpnd() && dst->AsSymOpnd()->m_sym->IsPropertySym(), "Expected property sym as dst of field store");
71097109
7110+ BailOutInfo * bailOutInfo = nullptr;
7111+ bool doCheckLayout = false;
7112+ IR::PropertySymOpnd * propertySymOpnd = nullptr;
7113+ if (dst->AsSymOpnd()->IsPropertySymOpnd())
7114+ {
7115+ propertySymOpnd = dst->AsPropertySymOpnd();
7116+ if (stFldInstr->HasBailOutInfo() && !propertySymOpnd->IsTypeCheckSeqCandidate() && propertySymOpnd->TypeCheckRequired())
7117+ {
7118+ IR::Instr * instrBailTarget = stFldInstr->ShareBailOut();
7119+ LowerBailTarget(instrBailTarget);
7120+ doCheckLayout = true;
7121+ bailOutInfo = stFldInstr->GetBailOutInfo();
7122+ switch (helperMethod)
7123+ {
7124+ case IR::HelperOp_PatchPutValue:
7125+ helperMethod = IR::HelperOp_PatchPutValueCheckLayout;
7126+ break;
7127+ case IR::HelperOp_PatchPutValuePolymorphic:
7128+ helperMethod = IR::HelperOp_PatchPutValuePolymorphicCheckLayout;
7129+ break;
7130+ case IR::HelperOp_PatchPutValueNoLocalFastPath:
7131+ helperMethod = IR::HelperOp_PatchPutValueNoLocalFastPathCheckLayout;
7132+ break;
7133+ case IR::HelperOp_PatchPutValueNoLocalFastPathPolymorphic:
7134+ helperMethod = IR::HelperOp_PatchPutValueNoLocalFastPathPolymorphicCheckLayout;
7135+ break;
7136+ case IR::HelperOp_PatchPutValueWithThisPtr:
7137+ helperMethod = IR::HelperOp_PatchPutValueWithThisPtrCheckLayout;
7138+ break;
7139+ case IR::HelperOp_PatchPutValueWithThisPtrPolymorphic:
7140+ helperMethod = IR::HelperOp_PatchPutValueWithThisPtrPolymorphicCheckLayout;
7141+ break;
7142+ case IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPath:
7143+ helperMethod = IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPathCheckLayout;
7144+ break;
7145+ case IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPathPolymorphic:
7146+ helperMethod = IR::HelperOp_PatchPutValueWithThisPtrNoLocalFastPathPolymorphicCheckLayout;
7147+ break;
7148+ case IR::HelperOp_PatchInitValue:
7149+ helperMethod = IR::HelperOp_PatchInitValueCheckLayout;
7150+ break;
7151+ case IR::HelperOp_PatchInitValuePolymorphic:
7152+ helperMethod = IR::HelperOp_PatchInitValuePolymorphicCheckLayout;
7153+ break;
7154+ default:
7155+ AssertOrFailFast(false);
7156+ break;
7157+ }
7158+ }
7159+ }
7160+
71107161 IR::Opnd * inlineCacheOpnd = nullptr;
71117162 if (withInlineCache)
71127163 {
@@ -7153,7 +7204,20 @@ Lowerer::LowerStFld(
71537204 }
71547205
71557206 IR::RegOpnd *opndBase = dst->AsSymOpnd()->CreatePropertyOwnerOpnd(m_func);
7156- m_lowererMD.ChangeToHelperCall(stFldInstr, helperMethod, labelBailOut, opndBase, dst->AsSymOpnd()->IsPropertySymOpnd() ? dst->AsSymOpnd()->AsPropertySymOpnd() : nullptr, isHelper);
7207+
7208+ IR::Instr * callInstr =
7209+ m_lowererMD.ChangeToHelperCall(stFldInstr, helperMethod, labelBailOut, opndBase, propertySymOpnd, isHelper);
7210+
7211+ if (doCheckLayout)
7212+ {
7213+ callInstr->SetDst(IR::RegOpnd::New(TyUint8, bailOutInfo->bailOutFunc));
7214+ IR::Instr * bailOutInstr = IR::BailOutInstr::New(Js::OpCode::BailOnNotEqual, IR::BailOutFailedTypeCheck, bailOutInfo, bailOutInfo->bailOutFunc);
7215+ bailOutInstr->SetSrc1(callInstr->GetDst());
7216+ bailOutInstr->SetSrc2(IR::IntConstOpnd::New(0, TyUint8, bailOutInfo->bailOutFunc));
7217+ callInstr->InsertAfter(bailOutInstr);
7218+ bailOutInfo->polymorphicCacheIndex = propertySymOpnd->m_inlineCacheIndex;
7219+ LowerBailOnEqualOrNotEqual(bailOutInstr, nullptr, nullptr, nullptr, isHelper);
7220+ }
71577221
71587222 return instrPrev;
71597223}
@@ -24950,9 +25014,9 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)
2495025014 Func *func = instr->m_func;
2495125015
2495225016 IR::LabelInstr *labelDone = IR::LabelInstr::New(Js::OpCode::Label, func, false);
24953- IR::LabelInstr *labelInlineFunc = IR::LabelInstr::New(Js::OpCode::Label, func, false);
2495425017 IR::LabelInstr *testLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
2495525018 IR::LabelInstr *scriptFuncLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
25019+ LABELNAMESET(scriptFuncLabel, "ScriptFunctionWithHomeObj");
2495625020 IR::Opnd *opndUndefAddress = this->LoadLibraryValueOpnd(instr, LibraryValue::ValueUndefined);
2495725021
2495825022 IR::RegOpnd *instanceRegOpnd = IR::RegOpnd::New(TyMachPtr, func);
@@ -24973,23 +25037,30 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)
2497325037
2497425038 if (func->GetJITFunctionBody()->HasHomeObj())
2497525039 {
24976- // Is this an function with inline cache and home obj??
24977- IR::Opnd * vtableAddressInlineFuncHomObjOpnd = this->LoadVTableValueOpnd(instr, VTableValue::VtableScriptFunctionWithInlineCacheAndHomeObj);
24978- IR::BranchInstr* inlineFuncHomObjOpndBr = InsertCompareBranch(IR::IndirOpnd::New(instanceRegOpnd, 0, TyMachPtr, func), vtableAddressInlineFuncHomObjOpnd, Js::OpCode::BrNeq_A, labelInlineFunc, instr);
24979- InsertObjectPoison(instanceRegOpnd, inlineFuncHomObjOpndBr, instr, false);
24980- IR::IndirOpnd *indirInlineFuncHomeObjOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>::GetOffsetOfHomeObj(), TyMachPtr, func);
24981- Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjOpnd, instr);
24982- InsertBranch(Js::OpCode::Br, testLabel, instr);
25040+ IR::RegOpnd* funcObjHasInlineCachesOpnd = IR::RegOpnd::New(TyUint8, instr->m_func);
25041+ this->InsertMove(funcObjHasInlineCachesOpnd, IR::IndirOpnd::New(instanceRegOpnd, Js::ScriptFunction::GetOffsetOfHasInlineCaches(), TyUint8, instr->m_func), instr);
2498325042
24984- instr->InsertBefore(labelInlineFunc);
24985-
24986- // Is this a function with inline cache, home obj and computed name??
24987- IR::Opnd * vtableAddressInlineFuncHomObjCompNameOpnd = this->LoadVTableValueOpnd(instr, VTableValue::VtableScriptFunctionWithInlineCacheHomeObjAndComputedName);
24988- IR::BranchInstr* inlineFuncHomObjCompNameBr = InsertCompareBranch(IR::IndirOpnd::New(instanceRegOpnd, 0, TyMachPtr, func), vtableAddressInlineFuncHomObjCompNameOpnd, Js::OpCode::BrNeq_A, scriptFuncLabel, instr);
25043+ IR::BranchInstr* inlineFuncHomObjCompNameBr = InsertTestBranch(funcObjHasInlineCachesOpnd, funcObjHasInlineCachesOpnd, Js::OpCode::BrEq_A, scriptFuncLabel, instr);
2498925044 InsertObjectPoison(instanceRegOpnd, inlineFuncHomObjCompNameBr, instr, false);
24990- IR::IndirOpnd *indirInlineFuncHomeObjCompNameOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithComputedName<Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>>::GetOffsetOfHomeObj(), TyMachPtr, func);
24991- Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjCompNameOpnd, instr);
24992- InsertBranch(Js::OpCode::Br, testLabel, instr);
25045+
25046+ if (func->GetJITFunctionBody()->HasComputedName())
25047+ {
25048+ // Is this a function with inline cache, home obj and computed name?
25049+ {
25050+ IR::IndirOpnd* indirInlineFuncHomeObjCompNameOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithComputedName<Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>>::GetOffsetOfHomeObj(), TyMachPtr, func);
25051+ Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjCompNameOpnd, instr);
25052+ InsertBranch(Js::OpCode::Br, testLabel, instr);
25053+ }
25054+ }
25055+ else
25056+ {
25057+ // Is this a function with inline cache and home obj?
25058+ {
25059+ IR::IndirOpnd* indirInlineFuncHomeObjOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::FunctionWithHomeObj<Js::ScriptFunctionWithInlineCache>::GetOffsetOfHomeObj(), TyMachPtr, func);
25060+ Lowerer::InsertMove(instanceRegOpnd, indirInlineFuncHomeObjOpnd, instr);
25061+ InsertBranch(Js::OpCode::Br, testLabel, instr);
25062+ }
25063+ }
2499325064
2499425065 instr->InsertBefore(scriptFuncLabel);
2499525066 IR::IndirOpnd *indirOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::ScriptFunctionWithHomeObj::GetOffsetOfHomeObj(), TyMachPtr, func);
0 commit comments