@@ -208,7 +208,7 @@ void GlobOpt::KillLiveFields(BVSparse<JitArenaAllocator> *const fieldsToKill, BV
208
208
}
209
209
210
210
void
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)
212
212
{
213
213
IR::RegOpnd *indexOpnd = indirOpnd->GetIndexOpnd ();
214
214
@@ -241,6 +241,23 @@ GlobOpt::KillLiveElems(IR::IndirOpnd * indirOpnd, BVSparse<JitArenaAllocator> *
241
241
// Write/delete to a non-integer numeric index can't alias a name on the RHS of a dot, but it change object layout
242
242
this ->KillAllObjectTypes (bv);
243
243
}
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
+ }
244
261
}
245
262
}
246
263
@@ -333,7 +350,7 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
333
350
case Js::OpCode::StElemI_A_Strict:
334
351
Assert (dstOpnd != nullptr );
335
352
KillLiveFields (this ->lengthEquivBv , bv);
336
- KillLiveElems (dstOpnd->AsIndirOpnd (), bv, inGlobOpt, instr->m_func );
353
+ KillLiveElems (dstOpnd->AsIndirOpnd (), instr-> GetSrc1 (), bv, inGlobOpt, instr->m_func );
337
354
if (inGlobOpt)
338
355
{
339
356
KillObjectHeaderInlinedTypeSyms (this ->currentBlock , false );
@@ -343,7 +360,7 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
343
360
case Js::OpCode::InitComputedProperty:
344
361
case Js::OpCode::InitGetElemI:
345
362
case Js::OpCode::InitSetElemI:
346
- KillLiveElems (dstOpnd->AsIndirOpnd (), bv, inGlobOpt, instr->m_func );
363
+ KillLiveElems (dstOpnd->AsIndirOpnd (), instr-> GetSrc1 (), bv, inGlobOpt, instr->m_func );
347
364
if (inGlobOpt)
348
365
{
349
366
KillObjectHeaderInlinedTypeSyms (this ->currentBlock , false );
@@ -353,7 +370,7 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
353
370
case Js::OpCode::DeleteElemI_A:
354
371
case Js::OpCode::DeleteElemIStrict_A:
355
372
Assert (dstOpnd != nullptr );
356
- KillLiveElems (instr->GetSrc1 ()->AsIndirOpnd (), bv, inGlobOpt, instr->m_func );
373
+ KillLiveElems (instr->GetSrc1 ()->AsIndirOpnd (), nullptr , bv, inGlobOpt, instr->m_func );
357
374
break ;
358
375
359
376
case Js::OpCode::DeleteFld:
0 commit comments