@@ -208,7 +208,7 @@ void GlobOpt::KillLiveFields(BVSparse<JitArenaAllocator> *const fieldsToKill, BV
208208}
209209
210210void
211- GlobOpt::KillLiveElems (IR::IndirOpnd * indirOpnd, BVSparse<JitArenaAllocator> * bv, bool inGlobOpt, Func *func)
211+ GlobOpt::KillLiveElems (IR::IndirOpnd * indirOpnd, IR::Opnd * valueOpnd, BVSparse<JitArenaAllocator> * bv, bool inGlobOpt, Func *func)
212212{
213213 IR::RegOpnd *indexOpnd = indirOpnd->GetIndexOpnd ();
214214
@@ -225,14 +225,7 @@ GlobOpt::KillLiveElems(IR::IndirOpnd * indirOpnd, BVSparse<JitArenaAllocator> *
225225 // - We check the type specialization status for the sym as well. For the purpose of doing kills, we can assume that
226226 // if type specialization happened, that fields don't need to be killed. Note that they may be killed in the next
227227 // pass based on the value.
228- if (func->GetThisOrParentInlinerHasArguments () ||
229- (
230- indexOpnd &&
231- (
232- indexOpnd->m_sym ->m_isNotNumber ||
233- (inGlobOpt && !indexOpnd->GetValueType ().IsNumber () && !currentBlock->globOptData .IsTypeSpecialized (indexOpnd->m_sym ))
234- )
235- ))
228+ if (func->GetThisOrParentInlinerHasArguments () || this ->IsNonNumericRegOpnd (indexOpnd, inGlobOpt))
236229 {
237230 this ->KillAllFields (bv); // This also kills all property type values, as the same bit-vector tracks those stack syms
238231 SetAnyPropertyMayBeWrittenTo ();
@@ -248,6 +241,23 @@ GlobOpt::KillLiveElems(IR::IndirOpnd * indirOpnd, BVSparse<JitArenaAllocator> *
248241 // Write/delete to a non-integer numeric index can't alias a name on the RHS of a dot, but it change object layout
249242 this ->KillAllObjectTypes (bv);
250243 }
244+ else if ((!valueOpnd || valueOpnd->IsVar ()) && this ->objectTypeSyms != nullptr )
245+ {
246+ // If we wind up converting a native array, block final-type opt at this point, because we could evolve
247+ // to a type with the wrong type ID. Do this by noting that we may have evolved any type and so must
248+ // check it before evolving it further.
249+ IR::RegOpnd *baseOpnd = indirOpnd->GetBaseOpnd ();
250+ Value * baseValue = baseOpnd ? this ->currentBlock ->globOptData .FindValue (baseOpnd->m_sym ) : nullptr ;
251+ ValueInfo * baseValueInfo = baseValue ? baseValue->GetValueInfo () : nullptr ;
252+ if (!baseValueInfo || !baseValueInfo->IsNotNativeArray ())
253+ {
254+ if (this ->currentBlock ->globOptData .maybeWrittenTypeSyms == nullptr )
255+ {
256+ this ->currentBlock ->globOptData .maybeWrittenTypeSyms = JitAnew (this ->alloc , BVSparse<JitArenaAllocator>, this ->alloc );
257+ }
258+ this ->currentBlock ->globOptData .maybeWrittenTypeSyms ->Or (this ->objectTypeSyms );
259+ }
260+ }
251261 }
252262}
253263
@@ -340,7 +350,7 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
340350 case Js::OpCode::StElemI_A_Strict:
341351 Assert (dstOpnd != nullptr );
342352 KillLiveFields (this ->lengthEquivBv , bv);
343- KillLiveElems (dstOpnd->AsIndirOpnd (), bv, inGlobOpt, instr->m_func );
353+ KillLiveElems (dstOpnd->AsIndirOpnd (), instr-> GetSrc1 (), bv, inGlobOpt, instr->m_func );
344354 if (inGlobOpt)
345355 {
346356 KillObjectHeaderInlinedTypeSyms (this ->currentBlock , false );
@@ -350,7 +360,7 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
350360 case Js::OpCode::InitComputedProperty:
351361 case Js::OpCode::InitGetElemI:
352362 case Js::OpCode::InitSetElemI:
353- KillLiveElems (dstOpnd->AsIndirOpnd (), bv, inGlobOpt, instr->m_func );
363+ KillLiveElems (dstOpnd->AsIndirOpnd (), instr-> GetSrc1 (), bv, inGlobOpt, instr->m_func );
354364 if (inGlobOpt)
355365 {
356366 KillObjectHeaderInlinedTypeSyms (this ->currentBlock , false );
@@ -360,7 +370,7 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
360370 case Js::OpCode::DeleteElemI_A:
361371 case Js::OpCode::DeleteElemIStrict_A:
362372 Assert (dstOpnd != nullptr );
363- KillLiveElems (instr->GetSrc1 ()->AsIndirOpnd (), bv, inGlobOpt, instr->m_func );
373+ KillLiveElems (instr->GetSrc1 ()->AsIndirOpnd (), nullptr , bv, inGlobOpt, instr->m_func );
364374 break ;
365375
366376 case Js::OpCode::DeleteFld:
0 commit comments