@@ -2033,9 +2033,12 @@ IRBuilder::BuildProfiledReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot ds
20332033
20342034 Js::OpCodeUtil::ConvertNonCallOpToNonProfiled (newOpcode);
20352035
2036+ Assert (newOpcode == Js::OpCode::BeginSwitch);
2037+
20362038 IR::RegOpnd * src1Opnd = this ->BuildSrcOpnd (srcRegSlot);
20372039 IR::RegOpnd * dstOpnd;
2038- if (newOpcode == Js::OpCode::BeginSwitch && srcRegSlot == dstRegSlot)
2040+
2041+ if (srcRegSlot == dstRegSlot)
20392042 {
20402043 // if the operands are the same for BeginSwitch, don't build a new operand in IR.
20412044 dstOpnd = src1Opnd;
@@ -2045,51 +2048,12 @@ IRBuilder::BuildProfiledReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot ds
20452048 dstOpnd = this ->BuildDstOpnd (dstRegSlot);
20462049 }
20472050
2048- bool isProfiled = true ;
2049- const Js::LdElemInfo *ldElemInfo = nullptr ;
2050- if (newOpcode == Js::OpCode::BeginSwitch)
2051- {
2052- m_switchBuilder.BeginSwitch ();
2053- switchFound = true ;
2054- newOpcode = Js::OpCode::Ld_A; // BeginSwitch is originally equivalent to Ld_A
2055- }
2056- else
2057- {
2058- Assert (newOpcode == Js::OpCode::LdLen_A);
2059- if (m_func->HasProfileInfo ())
2060- {
2061- ldElemInfo = m_func->GetReadOnlyProfileInfo ()->GetLdElemInfo (profileId);
2062- ValueType arrayType (ldElemInfo->GetArrayType ());
2063- if (arrayType.IsLikelyNativeArray () &&
2064- (
2065- (!(m_func->GetTopFunc ()->HasTry () && !m_func->GetTopFunc ()->DoOptimizeTry ()) && m_func->GetWeakFuncRef () && !m_func->HasArrayInfo ()) ||
2066- m_func->IsJitInDebugMode ()
2067- ))
2068- {
2069- arrayType = arrayType.SetArrayTypeId (Js::TypeIds_Array);
2070-
2071- // An opnd's value type will get replaced in the forward phase when it is not fixed. Store the array type in the
2072- // ProfiledInstr.
2073- Js::LdElemInfo *const newLdElemInfo = JitAnew (m_func->m_alloc , Js::LdElemInfo, *ldElemInfo);
2074- newLdElemInfo->arrayType = arrayType;
2075- ldElemInfo = newLdElemInfo;
2076- }
2077- src1Opnd->SetValueType (arrayType);
2078-
2079- if (m_func->GetTopFunc ()->HasTry () && !m_func->GetTopFunc ()->DoOptimizeTry ())
2080- {
2081- isProfiled = false ;
2082- }
2083- }
2084- else
2085- {
2086- isProfiled = false ;
2087- }
2088- }
2051+ m_switchBuilder.BeginSwitch ();
2052+ switchFound = true ;
2053+ newOpcode = Js::OpCode::Ld_A; // BeginSwitch is originally equivalent to Ld_A
20892054
20902055 IR::Instr *instr;
20912056
2092-
20932057 if (m_func->DoSimpleJitDynamicProfile ())
20942058 {
20952059 // Since we're in simplejit, we want to keep track of the profileid:
@@ -2098,35 +2062,15 @@ IRBuilder::BuildProfiledReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot ds
20982062 profiledInstr->isBeginSwitch = newOpcode == Js::OpCode::Ld_A;
20992063 instr = profiledInstr;
21002064 }
2101- else if (isProfiled)
2065+ else
21022066 {
21032067 IR::ProfiledInstr *profiledInstr = IR::ProfiledInstr::New (newOpcode, dstOpnd, src1Opnd, m_func);
21042068 instr = profiledInstr;
2105-
2106- switch (newOpcode) {
2107- case Js::OpCode::Ld_A:
2108- profiledInstr->u .FldInfo () = Js::FldInfo ();
2109- break ;
2110- case Js::OpCode::LdLen_A:
2111- profiledInstr->u .ldElemInfo = ldElemInfo;
2112- break ;
2113- default :
2114- Assert (false );
2115- __assume (false );
2116- }
2117- }
2118- else
2119- {
2120- instr = IR::Instr::New (newOpcode, dstOpnd, src1Opnd, m_func);
2069+ profiledInstr->u .FldInfo () = Js::FldInfo ();
21212070 }
21222071
21232072 this ->AddInstr (instr, offset);
21242073
2125- if (newOpcode == Js::OpCode::LdLen_A && ldElemInfo && !ldElemInfo->WasProfiled () && DoBailOnNoProfile ())
2126- {
2127- InsertBailOnNoProfile (instr);
2128- }
2129-
21302074 if (switchFound && instr->IsProfiledInstr ())
21312075 {
21322076 m_switchBuilder.SetProfiledInstruction (instr, profileId);
@@ -4502,6 +4446,109 @@ IRBuilder::BuildElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot insta
45024446 }
45034447}
45044448
4449+ template <typename SizePolicy>
4450+ void
4451+ IRBuilder::BuildProfiledElementCP (Js::OpCode newOpcode, uint32 offset)
4452+ {
4453+ Assert (OpCodeAttr::HasMultiSizeLayout (newOpcode));
4454+ auto layout = m_jnReader.GetLayout <Js::OpLayoutDynamicProfile<Js::OpLayoutT_ElementCP<SizePolicy>>>();
4455+
4456+ if (!PHASE_OFF (Js::ClosureRegCheckPhase, m_func))
4457+ {
4458+ this ->DoClosureRegCheck (layout->Value );
4459+ this ->DoClosureRegCheck (layout->Instance );
4460+ }
4461+
4462+ BuildProfiledElementCP (newOpcode, offset, layout->Instance , layout->Value , layout->inlineCacheIndex , layout->profileId );
4463+ }
4464+
4465+ void
4466+ IRBuilder::BuildProfiledElementCP (Js::OpCode newOpcode, uint32 offset, Js::RegSlot instance, Js::RegSlot regSlot, Js::CacheId inlineCacheIndex, Js::ProfileId profileId)
4467+ {
4468+ Assert (OpCodeAttr::HasMultiSizeLayout (newOpcode));
4469+
4470+ bool isProfiled = OpCodeAttr::IsProfiledOp (newOpcode);
4471+
4472+ if (isProfiled)
4473+ {
4474+ Js::OpCodeUtil::ConvertNonCallOpToNonProfiled (newOpcode);
4475+ }
4476+
4477+ Assert (newOpcode == Js::OpCode::LdLen_A);
4478+
4479+ Js::PropertyId propertyId = m_func->GetJITFunctionBody ()->GetPropertyIdFromCacheId (inlineCacheIndex);
4480+ IR::SymOpnd * fieldSymOpnd = this ->BuildFieldOpnd (newOpcode, instance, propertyId, (Js::PropertyIdIndexType) - 1 , PropertyKindData, inlineCacheIndex);
4481+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (regSlot);
4482+
4483+ ValueType arrayType = ValueType::Uninitialized;
4484+
4485+ if (m_func->HasProfileInfo ())
4486+ {
4487+ const Js::LdLenInfo * ldLenInfo = m_func->GetReadOnlyProfileInfo ()->GetLdLenInfo (profileId);
4488+ arrayType = (ldLenInfo->GetArrayType ());
4489+ if (arrayType.IsLikelyNativeArray () &&
4490+ (
4491+ (!(m_func->GetTopFunc ()->HasTry () && !m_func->GetTopFunc ()->DoOptimizeTry ()) && m_func->GetWeakFuncRef () && !m_func->HasArrayInfo ()) ||
4492+ m_func->IsJitInDebugMode ()
4493+ ))
4494+ {
4495+ // An opnd's value type will get replaced in the forward phase when it is not fixed. Store the array type in the ProfiledInstr.
4496+ arrayType = arrayType.SetArrayTypeId (Js::TypeIds_Array);
4497+ }
4498+ fieldSymOpnd->SetValueType (arrayType);
4499+
4500+ if (m_func->GetTopFunc ()->HasTry () && !m_func->GetTopFunc ()->DoOptimizeTry ())
4501+ {
4502+ isProfiled = false ;
4503+ }
4504+ }
4505+ else
4506+ {
4507+ isProfiled = false ;
4508+ }
4509+
4510+ bool wasNotProfiled = false ;
4511+ IR::Instr *instr = nullptr ;
4512+
4513+ if (m_func->DoSimpleJitDynamicProfile ())
4514+ {
4515+ // Since we're in simplejit, we want to keep track of the profileid:
4516+ IR::JitProfilingInstr * profiledInstr = IR::JitProfilingInstr::New (newOpcode, dstOpnd, fieldSymOpnd, m_func);
4517+ instr = profiledInstr;
4518+ profiledInstr->profileId = profileId;
4519+ }
4520+ else if (isProfiled)
4521+ {
4522+ IR::ProfiledInstr * profiledInstr = IR::ProfiledInstr::New (newOpcode, dstOpnd, fieldSymOpnd, m_func);
4523+ instr = profiledInstr;
4524+ profiledInstr->u .FldInfo () = *(m_func->GetReadOnlyProfileInfo ()->GetFldInfo (inlineCacheIndex));
4525+ profiledInstr->u .LdLenArrayType () = arrayType;
4526+ wasNotProfiled = !profiledInstr->u .FldInfo ().WasLdFldProfiled ();
4527+ dstOpnd->SetValueType (instr->AsProfiledInstr ()->u .FldInfo ().valueType );
4528+ #if ENABLE_DEBUG_CONFIG_OPTIONS
4529+ if (Js::Configuration::Global.flags .TestTrace .IsEnabled (Js::DynamicProfilePhase))
4530+ {
4531+ const ValueType valueType (profiledInstr->u .FldInfo ().valueType );
4532+ char valueTypeStr[VALUE_TYPE_MAX_STRING_SIZE];
4533+ valueType.ToString (valueTypeStr);
4534+ char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE];
4535+ Output::Print (_u (" TestTrace function %s (%s) ValueType = %i " ), m_func->GetJITFunctionBody ()->GetDisplayName (), m_func->GetDebugNumberSet (debugStringBuffer), valueTypeStr);
4536+ instr->DumpTestTrace ();
4537+ }
4538+ #endif
4539+ }
4540+ else
4541+ {
4542+ instr = IR::Instr::New (newOpcode, dstOpnd, fieldSymOpnd, m_func);
4543+ }
4544+
4545+ this ->AddInstr (instr, offset);
4546+
4547+ if (wasNotProfiled && DoBailOnNoProfile ())
4548+ {
4549+ InsertBailOnNoProfile (instr);
4550+ }
4551+ }
45054552
45064553// /----------------------------------------------------------------------------
45074554// /
0 commit comments