summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSObject.h
diff options
context:
space:
mode:
authorMark Hahnenberg <mhahnenberg@apple.com>2014-09-25 11:46:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@digia.com>2014-09-25 18:15:52 +0200
commit3a51e3ee766490fe6f9ab9511d19e16f75e07db8 (patch)
treedd6aac2bd555f718130c07146564957c155d7339 /Source/JavaScriptCore/runtime/JSObject.h
parent405022cf7bba9bb702b9385dbcb983c789c838b1 (diff)
downloadqtwebkit-3a51e3ee766490fe6f9ab9511d19e16f75e07db8.tar.gz
<https://webkit.org/b/120079> Flattening a dictionary can cause CopiedSpace corruption
Reviewed by Oliver Hunt. When we flatten an object in dictionary mode, we compact its properties. If the object had out-of-line storage in the form of a Butterfly prior to this compaction, and after compaction its properties fit inline, the object's Structure "forgets" that the object has a non-zero Butterfly pointer. During GC, we check the Butterfly and reportLiveBytes with bytes = 0, which causes all sorts of badness in CopiedSpace. Instead, after we flatten a dictionary, if properties fit inline we should clear the Butterfly pointer so that the GC doesn't get confused later. This patch does this clearing, and it also adds JSObject::checkStructure, which overrides JSCell::checkStructure to add an ASSERT that makes sure that the Structure being assigned agrees with the whether or not the object has a Butterfly. Also added an ASSERT to check that the number of bytes reported to SlotVisitor::copyLater is non-zero. * heap/SlotVisitorInlines.h: (JSC::SlotVisitor::copyLater): * runtime/JSObject.cpp: (JSC::JSObject::notifyPresenceOfIndexedAccessors): (JSC::JSObject::convertUndecidedToInt32): (JSC::JSObject::convertUndecidedToDouble): (JSC::JSObject::convertUndecidedToContiguous): (JSC::JSObject::convertInt32ToDouble): (JSC::JSObject::convertInt32ToContiguous): (JSC::JSObject::genericConvertDoubleToContiguous): (JSC::JSObject::switchToSlowPutArrayStorage): (JSC::JSObject::setPrototype): (JSC::JSObject::putDirectAccessor): (JSC::JSObject::seal): (JSC::JSObject::freeze): (JSC::JSObject::preventExtensions): (JSC::JSObject::reifyStaticFunctionsForDelete): (JSC::JSObject::removeDirect): * runtime/JSObject.h: (JSC::JSObject::setButterfly): (JSC::JSObject::putDirectInternal): (JSC::JSObject::setStructure): (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): * runtime/Structure.cpp: (JSC::Structure::flattenDictionaryStructure): Change-Id: Idfd8c22555f4373c1104316ff1ee28f5f84ef083 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154366 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSObject.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index c62dc2aec..7a78a46a6 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -595,6 +595,7 @@ public:
void setButterfly(VM&, Butterfly*, Structure*);
void setButterflyWithoutChangingStructure(Butterfly*); // You probably don't want to call this.
+ void setStructure(VM&, Structure*, Butterfly* = 0);
void setStructureAndReallocateStorageIfNecessary(VM&, unsigned oldCapacity, Structure*);
void setStructureAndReallocateStorageIfNecessary(VM&, Structure*);
@@ -1109,7 +1110,7 @@ inline void JSObject::setButterfly(VM& vm, Butterfly* butterfly, Structure* stru
{
ASSERT(structure);
ASSERT(!butterfly == (!structure->outOfLineCapacity() && !hasIndexingHeader(structure->indexingType())));
- setStructure(vm, structure);
+ setStructure(vm, structure, butterfly);
m_butterfly = butterfly;
}
@@ -1316,7 +1317,7 @@ inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSVal
return true;
}
// case (2) Despecify, fall through to (3).
- setStructure(vm, Structure::despecifyFunctionTransition(vm, structure(), propertyName));
+ setStructure(vm, Structure::despecifyFunctionTransition(vm, structure(), propertyName), m_butterfly);
}
// case (3) set the slot, do the put, return.
@@ -1344,12 +1345,18 @@ inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSVal
return true;
}
+inline void JSObject::setStructure(VM& vm, Structure* structure, Butterfly* butterfly)
+{
+ JSCell::setStructure(vm, structure);
+ ASSERT_UNUSED(butterfly, !butterfly == !(structure->outOfLineCapacity() || hasIndexingHeader(structure->indexingType())));
+}
+
inline void JSObject::setStructureAndReallocateStorageIfNecessary(VM& vm, unsigned oldCapacity, Structure* newStructure)
{
ASSERT(oldCapacity <= newStructure->outOfLineCapacity());
if (oldCapacity == newStructure->outOfLineCapacity()) {
- setStructure(vm, newStructure);
+ setStructure(vm, newStructure, m_butterfly);
return;
}