Skip to content

Commit

Permalink
Fix crash with ObjectStructureWithMap and inline cache
Browse files Browse the repository at this point in the history
If inline cache refers ObjectStructure, ObjectStructure should keep its contents.

Signed-off-by: Seonghyun Kim <[email protected]>
  • Loading branch information
ksh8281 authored and clover2123 committed Jul 20, 2023
1 parent 74735f9 commit 87fda52
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 23 deletions.
3 changes: 3 additions & 0 deletions src/interpreter/ByteCodeInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2410,6 +2410,7 @@ NEVER_INLINE void InterpreterSlowPath::getObjectPrecomputedCaseOperation(Executi

while (true) {
auto s = obj->structure();
s->markReferencedByInlineCache();
cachedhiddenClassChain.push_back(s);
auto result = s->findProperty(propertyName);

Expand Down Expand Up @@ -4139,6 +4140,8 @@ NEVER_INLINE void InterpreterSlowPath::objectDefineOwnPropertyWithNameOperation(
byteCodeBlock->m_otherLiteralData.push_back(newStructure);
code->m_inlineCachedStructureBefore = oldStructure;
code->m_inlineCachedStructureAfter = newStructure;
oldStructure->markReferencedByInlineCache();
newStructure->markReferencedByInlineCache();
} else {
// failed to cache
}
Expand Down
78 changes: 56 additions & 22 deletions src/runtime/ObjectStructure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,24 @@ ObjectStructure* ObjectStructureWithoutTransition::addProperty(const ObjectStruc
bool nameIsSymbol = m_hasSymbolPropertyName ? true : name.isSymbol();
bool hasNonAtomicName = m_hasNonAtomicPropertyName ? true : !name.hasAtomicString();
bool hasEnumerableProperty = m_hasEnumerableProperty ? true : desc.isEnumerable();

ObjectStructure* newStructure;
m_properties->push_back(newItem);
ObjectStructureItemVector* propertiesForNewStructure;
if (m_isReferencedByInlineCache) {
propertiesForNewStructure = new ObjectStructureItemVector(*m_properties, newItem);
} else {
m_properties->push_back(newItem);
propertiesForNewStructure = m_properties;
m_properties = nullptr;
}

if (m_properties->size() + 1 > ESCARGOT_OBJECT_STRUCTURE_ACCESS_CACHE_BUILD_MIN_SIZE) {
newStructure = new ObjectStructureWithMap(m_properties, ObjectStructureWithMap::createPropertyNameMap(m_properties), nameIsIndexString, nameIsSymbol, hasEnumerableProperty);

if (propertiesForNewStructure->size() > ESCARGOT_OBJECT_STRUCTURE_ACCESS_CACHE_BUILD_MIN_SIZE) {
newStructure = new ObjectStructureWithMap(propertiesForNewStructure, ObjectStructureWithMap::createPropertyNameMap(propertiesForNewStructure), nameIsIndexString, nameIsSymbol, hasEnumerableProperty);
} else {
newStructure = new ObjectStructureWithoutTransition(m_properties, nameIsIndexString, nameIsSymbol, hasNonAtomicName, hasEnumerableProperty);
newStructure = new ObjectStructureWithoutTransition(propertiesForNewStructure, nameIsIndexString, nameIsSymbol, hasNonAtomicName, hasEnumerableProperty);
}

m_properties = nullptr;
return newStructure;
}

Expand Down Expand Up @@ -145,16 +153,23 @@ ObjectStructure* ObjectStructureWithoutTransition::removeProperty(size_t pIndex)
}

auto newStructure = new ObjectStructureWithoutTransition(newProperties, hasIndexString, hasSymbol, hasNonAtomicName, hasEnumerableProperty);
m_properties = nullptr;
if (!m_isReferencedByInlineCache) {
m_properties = nullptr;
}
return newStructure;
}

ObjectStructure* ObjectStructureWithoutTransition::replacePropertyDescriptor(size_t idx, const ObjectStructurePropertyDescriptor& newDesc)
{
m_properties->at(idx).m_descriptor = newDesc;
auto newStructure = new ObjectStructureWithoutTransition(m_properties, m_hasIndexPropertyName, m_hasSymbolPropertyName, m_hasNonAtomicPropertyName, m_hasEnumerableProperty);
m_properties = nullptr;
return newStructure;
ObjectStructureItemVector* newProperties = m_properties;

if (m_isReferencedByInlineCache) {
newProperties = new ObjectStructureItemVector(*m_properties);
} else {
m_properties = nullptr;
}
newProperties->at(idx).m_descriptor = newDesc;
return new ObjectStructureWithoutTransition(newProperties, m_hasIndexPropertyName, m_hasSymbolPropertyName, m_hasNonAtomicPropertyName, m_hasEnumerableProperty);
}

ObjectStructure* ObjectStructureWithoutTransition::convertToNonTransitionStructure()
Expand Down Expand Up @@ -381,11 +396,20 @@ ObjectStructure* ObjectStructureWithMap::addProperty(const ObjectStructureProper
bool hasSymbol = m_hasSymbolPropertyName ? true : name.isSymbol();
bool hasEnumerableProperty = m_hasEnumerableProperty ? true : desc.isEnumerable();

m_propertyNameMap->insert(std::make_pair(name, m_properties->size()));
m_properties->push_back(newItem);
ObjectStructure* newStructure = new ObjectStructureWithMap(m_properties, m_propertyNameMap, nameIsIndexString, hasSymbol, hasEnumerableProperty);
m_properties = nullptr;
m_propertyNameMap = nullptr;
ObjectStructureItemVector* newProperties = m_properties;
PropertyNameMap* newPropertyNameMap = m_propertyNameMap;

if (m_isReferencedByInlineCache) {
newProperties = new ObjectStructureItemVector(*m_properties);
newPropertyNameMap = new (GC) PropertyNameMap(*m_propertyNameMap);
} else {
m_properties = nullptr;
m_propertyNameMap = nullptr;
}

newPropertyNameMap->insert(std::make_pair(name, newProperties->size()));
newProperties->push_back(newItem);
ObjectStructure* newStructure = new ObjectStructureWithMap(newProperties, newPropertyNameMap, nameIsIndexString, hasSymbol, hasEnumerableProperty);
return newStructure;
}

Expand All @@ -412,8 +436,10 @@ ObjectStructure* ObjectStructureWithMap::removeProperty(size_t pIndex)
newIdx++;
}

m_properties = nullptr;
m_propertyNameMap = nullptr;
if (!m_isReferencedByInlineCache) {
m_properties = nullptr;
m_propertyNameMap = nullptr;
}
if (newProperties->size() > ESCARGOT_OBJECT_STRUCTURE_ACCESS_CACHE_BUILD_MIN_SIZE) {
return new ObjectStructureWithMap(newProperties, ObjectStructureWithMap::createPropertyNameMap(newProperties), hasIndexString, hasSymbol, hasEnumerableProperty);
} else {
Expand All @@ -423,11 +449,19 @@ ObjectStructure* ObjectStructureWithMap::removeProperty(size_t pIndex)

ObjectStructure* ObjectStructureWithMap::replacePropertyDescriptor(size_t idx, const ObjectStructurePropertyDescriptor& newDesc)
{
m_properties->at(idx).m_descriptor = newDesc;
ObjectStructure* newStructure = new ObjectStructureWithMap(m_properties, m_propertyNameMap, m_hasIndexPropertyName, m_hasSymbolPropertyName, m_hasEnumerableProperty);
m_properties = nullptr;
m_propertyNameMap = nullptr;
return newStructure;
ObjectStructureItemVector* newProperties = m_properties;
PropertyNameMap* newPropertyNameMap = m_propertyNameMap;

if (m_isReferencedByInlineCache) {
newProperties = new ObjectStructureItemVector(*m_properties);
newPropertyNameMap = new (GC) PropertyNameMap(*m_propertyNameMap);
} else {
m_properties = nullptr;
m_propertyNameMap = nullptr;
}

newProperties->at(idx).m_descriptor = newDesc;
return new ObjectStructureWithMap(newProperties, newPropertyNameMap, m_hasIndexPropertyName, m_hasSymbolPropertyName, m_hasEnumerableProperty);
}

ObjectStructure* ObjectStructureWithMap::convertToNonTransitionStructure()
Expand Down
13 changes: 13 additions & 0 deletions src/runtime/ObjectStructure.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ class ObjectStructure : public gc {
virtual ObjectStructure* convertToNonTransitionStructure() = 0;
virtual bool inTransitionMode() = 0;

void markReferencedByInlineCache()
{
m_isReferencedByInlineCache = true;
}

bool hasIndexPropertyName() const
{
return m_hasIndexPropertyName;
Expand All @@ -163,6 +168,11 @@ class ObjectStructure : public gc {
return m_hasEnumerableProperty;
}

bool isReferencedByInlineCache() const
{
return m_isReferencedByInlineCache;
}

protected:
ObjectStructure(bool hasIndexPropertyName,
bool hasSymbolPropertyName, bool hasEnumerableProperty)
Expand All @@ -171,6 +181,7 @@ class ObjectStructure : public gc {
, m_hasSymbolPropertyName(hasSymbolPropertyName)
, m_hasNonAtomicPropertyName(false)
, m_hasEnumerableProperty(hasEnumerableProperty)
, m_isReferencedByInlineCache(false)
, m_transitionTableVectorBufferSize(0)
, m_transitionTableVectorBufferCapacity(0)
{
Expand All @@ -183,6 +194,7 @@ class ObjectStructure : public gc {
, m_hasSymbolPropertyName(hasSymbolPropertyName)
, m_hasNonAtomicPropertyName(hasNonAtomicPropertyName)
, m_hasEnumerableProperty(hasEnumerableProperty)
, m_isReferencedByInlineCache(false)
, m_transitionTableVectorBufferSize(0)
, m_transitionTableVectorBufferCapacity(0)
{
Expand All @@ -195,6 +207,7 @@ class ObjectStructure : public gc {
bool m_hasSymbolPropertyName : 1;
bool m_hasNonAtomicPropertyName : 1;
bool m_hasEnumerableProperty : 1;
bool m_isReferencedByInlineCache : 1;
uint8_t m_transitionTableVectorBufferSize : 8;
uint8_t m_transitionTableVectorBufferCapacity : 8;
};
Expand Down
2 changes: 1 addition & 1 deletion test/vendortest

0 comments on commit 87fda52

Please sign in to comment.