|
|
@@ -720,7 +720,7 @@ BackwardPass::MergeSuccBlocksInfo(BasicBlock * block)
|
|
|
this->func->GetDebugNumberSet(debugStringBuffer),
|
|
|
block->GetBlockNum(), blockSucc->GetBlockNum());
|
|
|
|
|
|
- auto fixupFrom = [block, blockSucc, this](Bucket<AddPropertyCacheBucket> &bucket)
|
|
|
+ auto fixupFrom = [block, blockSucc, upwardExposedUses, this](Bucket<AddPropertyCacheBucket> &bucket)
|
|
|
{
|
|
|
AddPropertyCacheBucket *fromData = &bucket.element;
|
|
|
if (fromData->GetInitialType() == nullptr ||
|
|
|
@@ -729,10 +729,10 @@ BackwardPass::MergeSuccBlocksInfo(BasicBlock * block)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this->InsertTypeTransitionsAtPriorSuccessors(block, blockSucc, bucket.value, fromData);
|
|
|
+ this->InsertTypeTransitionsAtPriorSuccessors(block, blockSucc, bucket.value, fromData, upwardExposedUses);
|
|
|
};
|
|
|
|
|
|
- auto fixupTo = [blockSucc, this](Bucket<AddPropertyCacheBucket> &bucket)
|
|
|
+ auto fixupTo = [blockSucc, upwardExposedUses, this](Bucket<AddPropertyCacheBucket> &bucket)
|
|
|
{
|
|
|
AddPropertyCacheBucket *toData = &bucket.element;
|
|
|
if (toData->GetInitialType() == nullptr ||
|
|
|
@@ -741,7 +741,7 @@ BackwardPass::MergeSuccBlocksInfo(BasicBlock * block)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this->InsertTypeTransitionAtBlock(blockSucc, bucket.value, toData);
|
|
|
+ this->InsertTypeTransitionAtBlock(blockSucc, bucket.value, toData, upwardExposedUses);
|
|
|
};
|
|
|
|
|
|
if (blockSucc->stackSymToFinalType != nullptr)
|
|
|
@@ -4614,7 +4614,7 @@ BackwardPass::ProcessNewScObject(IR::Instr* instr)
|
|
|
Assert(pBucket->GetInitialType() == ctorCache->GetType());
|
|
|
if (!this->IsPrePass())
|
|
|
{
|
|
|
- this->InsertTypeTransition(instr->m_next, objSym, pBucket);
|
|
|
+ this->InsertTypeTransition(instr->m_next, objSym, pBucket, block->upwardExposedUses);
|
|
|
}
|
|
|
#if DBG
|
|
|
pBucket->deadStoreUnavailableInitialType = pBucket->GetInitialType();
|
|
|
@@ -5192,7 +5192,7 @@ BackwardPass::ProcessPropertySymOpndUse(IR::PropertySymOpnd * opnd)
|
|
|
pBucket->GetFinalType() != nullptr &&
|
|
|
pBucket->GetFinalType() != pBucket->GetInitialType())
|
|
|
{
|
|
|
- this->InsertTypeTransition(this->currentInstr->m_next, baseSym, pBucket);
|
|
|
+ this->InsertTypeTransition(this->currentInstr->m_next, baseSym, pBucket, block->upwardExposedUses);
|
|
|
pBucket->SetFinalType(pBucket->GetInitialType());
|
|
|
}
|
|
|
}
|
|
|
@@ -5211,9 +5211,6 @@ BackwardPass::ProcessPropertySymOpndUse(IR::PropertySymOpnd * opnd)
|
|
|
void
|
|
|
BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *block)
|
|
|
{
|
|
|
- StackSym *auxSlotPtrSym = nullptr;
|
|
|
- bool auxSlotPtrUpwardExposed = false;
|
|
|
-
|
|
|
Assert(tag == Js::DeadStorePhase);
|
|
|
Assert(opnd->IsTypeCheckSeqCandidate());
|
|
|
|
|
|
@@ -5280,7 +5277,6 @@ BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *
|
|
|
#endif
|
|
|
|
|
|
bucket->AddToGuardedPropertyOps(opnd->GetObjTypeSpecFldId());
|
|
|
- auxSlotPtrUpwardExposed = PHASE_ON(Js::ReuseAuxSlotPtrPhase, this->func) && opnd->UsesAuxSlot() && !opnd->IsLoadedFromProto() && opnd->IsTypeChecked();
|
|
|
|
|
|
if (opnd->NeedsMonoCheck())
|
|
|
{
|
|
|
@@ -5327,12 +5323,6 @@ BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *
|
|
|
bucket->SetGuardedPropertyOps(nullptr);
|
|
|
JitAdelete(this->tempAlloc, guardedPropertyOps);
|
|
|
block->stackSymToGuardedProperties->Clear(objSym->m_id);
|
|
|
- auxSlotPtrSym = opnd->GetAuxSlotPtrSym();
|
|
|
- if (auxSlotPtrSym)
|
|
|
- {
|
|
|
- this->currentBlock->upwardExposedUses->Clear(auxSlotPtrSym->m_id);
|
|
|
- }
|
|
|
- auxSlotPtrUpwardExposed = false;
|
|
|
}
|
|
|
}
|
|
|
#if DBG
|
|
|
@@ -5351,11 +5341,25 @@ BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *
|
|
|
opnd->SetGuardedPropOp(opnd->GetObjTypeSpecFldId());
|
|
|
}
|
|
|
|
|
|
- if (auxSlotPtrUpwardExposed)
|
|
|
+ if (opnd->UsesAuxSlot() && opnd->IsTypeCheckSeqParticipant() && !opnd->HasTypeMismatch() && !opnd->IsLoadedFromProto())
|
|
|
{
|
|
|
- // This is an upward-exposed use of the aux slot pointer.
|
|
|
- auxSlotPtrSym = opnd->EnsureAuxSlotPtrSym(this->func);
|
|
|
- this->currentBlock->upwardExposedUses->Set(auxSlotPtrSym->m_id);
|
|
|
+ bool auxSlotPtrUpwardExposed = false;
|
|
|
+ StackSym *auxSlotPtrSym = opnd->GetAuxSlotPtrSym();
|
|
|
+ if (opnd->IsAuxSlotPtrSymAvailable())
|
|
|
+ {
|
|
|
+ // This is an upward-exposed use of the aux slot pointer.
|
|
|
+ Assert(auxSlotPtrSym);
|
|
|
+ auxSlotPtrUpwardExposed = this->currentBlock->upwardExposedUses->TestAndSet(auxSlotPtrSym->m_id);
|
|
|
+ }
|
|
|
+ else if (auxSlotPtrSym != nullptr)
|
|
|
+ {
|
|
|
+ // The aux slot pointer is not upward-exposed at this point.
|
|
|
+ auxSlotPtrUpwardExposed = this->currentBlock->upwardExposedUses->TestAndClear(auxSlotPtrSym->m_id);
|
|
|
+ }
|
|
|
+ if (!this->IsPrePass() && auxSlotPtrUpwardExposed)
|
|
|
+ {
|
|
|
+ opnd->SetProducesAuxSlotPtr(true);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -5611,16 +5615,18 @@ BackwardPass::TrackAddPropertyTypes(IR::PropertySymOpnd *opnd, BasicBlock *block
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, int symId, AddPropertyCacheBucket *data)
|
|
|
+BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
|
|
|
{
|
|
|
StackSym *objSym = this->func->m_symTable->FindStackSym(symId);
|
|
|
Assert(objSym);
|
|
|
- this->InsertTypeTransition(instrInsertBefore, objSym, data);
|
|
|
+ this->InsertTypeTransition(instrInsertBefore, objSym, data, upwardExposedUses);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSym, AddPropertyCacheBucket *data)
|
|
|
+BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSym, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
|
|
|
{
|
|
|
+ Assert(!this->IsPrePass());
|
|
|
+
|
|
|
IR::RegOpnd *baseOpnd = IR::RegOpnd::New(objSym, TyMachReg, this->func);
|
|
|
baseOpnd->SetIsJITOptimizedReg(true);
|
|
|
|
|
|
@@ -5637,7 +5643,7 @@ BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSy
|
|
|
IR::Instr *adjustTypeInstr =
|
|
|
IR::Instr::New(Js::OpCode::AdjustObjType, finalTypeOpnd, baseOpnd, initialTypeOpnd, this->func);
|
|
|
|
|
|
- if (this->currentBlock->upwardExposedUses)
|
|
|
+ if (upwardExposedUses)
|
|
|
{
|
|
|
// If this type change causes a slot adjustment, the aux slot pointer (if any) will be reloaded here, so take it out of upwardExposedUses.
|
|
|
int oldCount;
|
|
|
@@ -5651,7 +5657,10 @@ BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSy
|
|
|
StackSym *auxSlotPtrSym = baseOpnd->m_sym->GetAuxSlotPtrSym();
|
|
|
if (auxSlotPtrSym)
|
|
|
{
|
|
|
- this->currentBlock->upwardExposedUses->Clear(auxSlotPtrSym->m_id);
|
|
|
+ if (upwardExposedUses->Test(auxSlotPtrSym->m_id))
|
|
|
+ {
|
|
|
+ adjustTypeInstr->m_opcode = Js::OpCode::AdjustObjTypeReloadAuxSlotPtr;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -5660,7 +5669,7 @@ BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSy
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPropertyCacheBucket *data)
|
|
|
+BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
|
|
|
{
|
|
|
if (!this->IsPrePass())
|
|
|
{
|
|
|
@@ -5669,11 +5678,11 @@ BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPro
|
|
|
{
|
|
|
// The instr with the bailout is something like a branch that may not fall through.
|
|
|
// Insert the transitions instead at the beginning of each successor block.
|
|
|
- this->InsertTypeTransitionsAtPriorSuccessors(this->currentBlock, nullptr, symId, data);
|
|
|
+ this->InsertTypeTransitionsAtPriorSuccessors(this->currentBlock, nullptr, symId, data, upwardExposedUses);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- this->InsertTypeTransition(instr->m_next, symId, data);
|
|
|
+ this->InsertTypeTransition(instr->m_next, symId, data, upwardExposedUses);
|
|
|
}
|
|
|
}
|
|
|
// Note: we could probably clear this entry out of the table, but I don't know
|
|
|
@@ -5682,7 +5691,7 @@ BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPro
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPropertyCacheBucket *data)
|
|
|
+BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
|
|
|
{
|
|
|
bool inserted = false;
|
|
|
FOREACH_INSTR_IN_BLOCK(instr, block)
|
|
|
@@ -5705,7 +5714,7 @@ BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPrope
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- this->InsertTypeTransition(instr, symId, data);
|
|
|
+ this->InsertTypeTransition(instr, symId, data, upwardExposedUses);
|
|
|
inserted = true;
|
|
|
break;
|
|
|
}
|
|
|
@@ -5715,7 +5724,7 @@ BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPrope
|
|
|
if (!inserted)
|
|
|
{
|
|
|
Assert(block->GetLastInstr()->m_next);
|
|
|
- this->InsertTypeTransition(block->GetLastInstr()->m_next, symId, data);
|
|
|
+ this->InsertTypeTransition(block->GetLastInstr()->m_next, symId, data, upwardExposedUses);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -5724,7 +5733,8 @@ BackwardPass::InsertTypeTransitionsAtPriorSuccessors(
|
|
|
BasicBlock *block,
|
|
|
BasicBlock *blockSucc,
|
|
|
int symId,
|
|
|
- AddPropertyCacheBucket *data)
|
|
|
+ AddPropertyCacheBucket *data,
|
|
|
+ BVSparse<JitArenaAllocator>* upwardExposedUses)
|
|
|
{
|
|
|
// For each successor of block prior to blockSucc, adjust the type.
|
|
|
FOREACH_SUCCESSOR_BLOCK(blockFix, block)
|
|
|
@@ -5734,7 +5744,7 @@ BackwardPass::InsertTypeTransitionsAtPriorSuccessors(
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this->InsertTypeTransitionAtBlock(blockFix, symId, data);
|
|
|
+ this->InsertTypeTransitionAtBlock(blockFix, symId, data, upwardExposedUses);
|
|
|
}
|
|
|
NEXT_SUCCESSOR_BLOCK;
|
|
|
}
|
|
|
@@ -5752,7 +5762,7 @@ BackwardPass::InsertTypeTransitionsAtPotentialKills()
|
|
|
// Also do this for ctor cache updates, to avoid putting a type in the ctor cache that extends past
|
|
|
// the end of the ctor that the cache covers.
|
|
|
this->ForEachAddPropertyCacheBucket([&](int symId, AddPropertyCacheBucket *data)->bool {
|
|
|
- this->InsertTypeTransitionAfterInstr(instr, symId, data);
|
|
|
+ this->InsertTypeTransitionAfterInstr(instr, symId, data, this->currentBlock->upwardExposedUses);
|
|
|
return false;
|
|
|
});
|
|
|
}
|
|
|
@@ -5778,7 +5788,7 @@ BackwardPass::InsertTypeTransitionsAtPotentialKills()
|
|
|
if (this->TransitionUndoesObjectHeaderInlining(data))
|
|
|
{
|
|
|
// We're transitioning from inlined to non-inlined, so we can't push it up any farther.
|
|
|
- this->InsertTypeTransitionAfterInstr(instr, symId, data);
|
|
|
+ this->InsertTypeTransitionAfterInstr(instr, symId, data, this->currentBlock->upwardExposedUses);
|
|
|
}
|
|
|
return false;
|
|
|
});
|