Skip to content

Commit 03a1fb1

Browse files
committed
[1.2>1.3] [MERGE #1530 @akroshg] Address deref issue
Merge pull request #1530 from akroshg:deref During the forward global optimizer pass, given a property store that causes an object layout to go from object-header-inlined to non-object-header-inlined, kill all type syms with object-header-inlined types to protect against aliasing.
2 parents d2eae68 + 4f5fd22 commit 03a1fb1

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

lib/Backend/GlobOptFields.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,7 +2200,7 @@ GlobOpt::FinishOptPropOp(IR::Instr *instr, IR::PropertySymOpnd *opnd, BasicBlock
22002200
isObjTypeSpecialized = ProcessPropOpInTypeCheckSeq<true>(instr, opnd, block, updateExistingValue, emitsTypeCheckOut, changesTypeValueOut, &isObjTypeChecked);
22012201
}
22022202

2203-
if (opnd == instr->GetDst() && this->objectTypeSyms && !isObjTypeChecked)
2203+
if (opnd == instr->GetDst() && this->objectTypeSyms)
22042204
{
22052205
if (block == nullptr)
22062206
{
@@ -2210,26 +2210,29 @@ GlobOpt::FinishOptPropOp(IR::Instr *instr, IR::PropertySymOpnd *opnd, BasicBlock
22102210
// This is a property store that may change the layout of the object that it stores to. This means that
22112211
// it may change any aliased object. Do two things to address this:
22122212
// - Add all object types in this function to the set that may have had a property added. This will prevent
2213-
// final type optimization across this instruction.
2213+
// final type optimization across this instruction. (Only needed here for non-specialized stores.)
22142214
// - Kill all type symbols that currently hold object-header-inlined types. Any of them may have their layout
22152215
// changed by the addition of a property.
22162216

22172217
SymID opndId = opnd->HasObjectTypeSym() ? opnd->GetObjectTypeSym()->m_id : -1;
2218-
if (block->globOptData.maybeWrittenTypeSyms == nullptr)
2219-
{
2220-
block->globOptData.maybeWrittenTypeSyms = JitAnew(this->alloc, BVSparse<JitArenaAllocator>, this->alloc);
2221-
}
2222-
if (isObjTypeSpecialized)
2218+
if (!isObjTypeChecked)
22232219
{
2224-
// The current object will be protected by a type check, unless no further accesses to it are
2225-
// protected by this access.
2226-
Assert(this->objectTypeSyms->Test(opndId));
2227-
this->objectTypeSyms->Clear(opndId);
2228-
}
2229-
block->globOptData.maybeWrittenTypeSyms->Or(this->objectTypeSyms);
2230-
if (isObjTypeSpecialized)
2231-
{
2232-
this->objectTypeSyms->Set(opndId);
2220+
if (block->globOptData.maybeWrittenTypeSyms == nullptr)
2221+
{
2222+
block->globOptData.maybeWrittenTypeSyms = JitAnew(this->alloc, BVSparse<JitArenaAllocator>, this->alloc);
2223+
}
2224+
if (isObjTypeSpecialized)
2225+
{
2226+
// The current object will be protected by a type check, unless no further accesses to it are
2227+
// protected by this access.
2228+
Assert(this->objectTypeSyms->Test(opndId));
2229+
this->objectTypeSyms->Clear(opndId);
2230+
}
2231+
block->globOptData.maybeWrittenTypeSyms->Or(this->objectTypeSyms);
2232+
if (isObjTypeSpecialized)
2233+
{
2234+
this->objectTypeSyms->Set(opndId);
2235+
}
22332236
}
22342237

22352238
if (!isObjTypeSpecialized || opnd->ChangesObjectLayout())

lib/Backend/Opnd.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -833,20 +833,43 @@ PropertySymOpnd::IsObjectHeaderInlined() const
833833
bool
834834
PropertySymOpnd::ChangesObjectLayout() const
835835
{
836+
Js::Type *cachedType = this->IsMono() ? this->GetType() : this->GetFirstEquivalentType();
837+
836838
Js::Type *finalType = this->GetFinalType();
837-
if (finalType == nullptr || !Js::DynamicType::Is(finalType->GetTypeId()))
839+
if (finalType && Js::DynamicType::Is(finalType->GetTypeId()))
840+
{
841+
// This is the case where final type opt may cause pro-active type transition to take place.
842+
843+
Assert(cachedType && Js::DynamicType::Is(cachedType->GetTypeId()));
844+
845+
Js::DynamicTypeHandler * cachedTypeHandler = (static_cast<Js::DynamicType*>(cachedType))->GetTypeHandler();
846+
Js::DynamicTypeHandler * finalTypeHandler = (static_cast<Js::DynamicType*>(finalType))->GetTypeHandler();
847+
848+
return cachedTypeHandler->GetInlineSlotCapacity() != finalTypeHandler->GetInlineSlotCapacity() ||
849+
cachedTypeHandler->GetOffsetOfInlineSlots() != finalTypeHandler->GetOffsetOfInlineSlots();
850+
}
851+
852+
if (!this->HasInitialType())
838853
{
839854
return false;
840855
}
841856

842-
Js::Type *cachedType = this->IsMono() ? this->GetType() : this->GetFirstEquivalentType();
843-
Assert(cachedType && Js::DynamicType::Is(cachedType->GetTypeId()));
857+
Js::Type *initialType = this->GetInitialType();
858+
if (initialType && Js::DynamicType::Is(initialType->GetTypeId()))
859+
{
860+
// This is the case where the type transition actually occurs. (This is the only case that's detectable
861+
// during the loop pre-pass, since final types are not in place yet.)
844862

845-
Js::DynamicTypeHandler * cachedTypeHandler = (static_cast<Js::DynamicType*>(cachedType))->GetTypeHandler();
846-
Js::DynamicTypeHandler * finalTypeHandler = (static_cast<Js::DynamicType*>(finalType))->GetTypeHandler();
863+
Assert(cachedType && Js::DynamicType::Is(cachedType->GetTypeId()));
847864

848-
return cachedTypeHandler->GetInlineSlotCapacity() != finalTypeHandler->GetInlineSlotCapacity() ||
849-
cachedTypeHandler->GetOffsetOfInlineSlots() != finalTypeHandler->GetOffsetOfInlineSlots();
865+
Js::DynamicTypeHandler * cachedTypeHandler = (static_cast<Js::DynamicType*>(cachedType))->GetTypeHandler();
866+
Js::DynamicTypeHandler * initialTypeHandler = (static_cast<Js::DynamicType*>(initialType))->GetTypeHandler();
867+
868+
return cachedTypeHandler->GetInlineSlotCapacity() != initialTypeHandler->GetInlineSlotCapacity() ||
869+
cachedTypeHandler->GetOffsetOfInlineSlots() != initialTypeHandler->GetOffsetOfInlineSlots();
870+
}
871+
872+
return false;
850873
}
851874

852875
void

0 commit comments

Comments
 (0)