@@ -7107,6 +7107,57 @@ Lowerer::LowerStFld(
7107
7107
IR::Opnd *dst = stFldInstr->UnlinkDst();
7108
7108
AssertMsg(dst->IsSymOpnd() && dst->AsSymOpnd()->m_sym->IsPropertySym(), "Expected property sym as dst of field store");
7109
7109
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
+
7110
7161
IR::Opnd * inlineCacheOpnd = nullptr;
7111
7162
if (withInlineCache)
7112
7163
{
@@ -7153,7 +7204,20 @@ Lowerer::LowerStFld(
7153
7204
}
7154
7205
7155
7206
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
+ }
7157
7221
7158
7222
return instrPrev;
7159
7223
}
@@ -24950,9 +25014,9 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)
24950
25014
Func *func = instr->m_func;
24951
25015
24952
25016
IR::LabelInstr *labelDone = IR::LabelInstr::New(Js::OpCode::Label, func, false);
24953
- IR::LabelInstr *labelInlineFunc = IR::LabelInstr::New(Js::OpCode::Label, func, false);
24954
25017
IR::LabelInstr *testLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
24955
25018
IR::LabelInstr *scriptFuncLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
25019
+ LABELNAMESET(scriptFuncLabel, "ScriptFunctionWithHomeObj");
24956
25020
IR::Opnd *opndUndefAddress = this->LoadLibraryValueOpnd(instr, LibraryValue::ValueUndefined);
24957
25021
24958
25022
IR::RegOpnd *instanceRegOpnd = IR::RegOpnd::New(TyMachPtr, func);
@@ -24973,23 +25037,30 @@ Lowerer::GenerateLdHomeObj(IR::Instr* instr)
24973
25037
24974
25038
if (func->GetJITFunctionBody()->HasHomeObj())
24975
25039
{
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);
24983
25042
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);
24989
25044
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
+ }
24993
25064
24994
25065
instr->InsertBefore(scriptFuncLabel);
24995
25066
IR::IndirOpnd *indirOpnd = IR::IndirOpnd::New(instanceRegOpnd, Js::ScriptFunctionWithHomeObj::GetOffsetOfHomeObj(), TyMachPtr, func);
0 commit comments