WebKit Bugzilla
Attachment 342843 Details for
Bug 186692
: Properly zero unused property storage offsets
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186692-20180615140430.patch (text/plain), 26.16 KB, created by
Keith Miller
on 2018-06-15 14:04:31 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Keith Miller
Created:
2018-06-15 14:04:31 PDT
Size:
26.16 KB
patch
obsolete
>Subversion Revision: 232801 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 206fcc33552f73f7f4e382aeb7c5c358d8a8af6b..61c1562c687aeb75cf6a39408673daa1705a5814 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,50 @@ >+2018-06-15 Keith Miller <keith_miller@apple.com> >+ >+ Properly zero unused property storage offsets >+ https://bugs.webkit.org/show_bug.cgi?id=186692 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Since the concurrent GC might see a property slot before the mutator has actually >+ stored the value there, we need to ensure that slot doesn't have garbage in it. >+ Right now when calling constructConvertedArrayStorageWithoutCopyingElements we never >+ cleared the unused proprety storage. This patch fixes that issue and gets most users >+ of the Butterfly::createUninitialized API to pass an ObjectInitializationScope. >+ >+ ObjectIntializationScope has also been upgraded to look for our invariants around >+ property storage. Additionally, a new assertion has been added to check for JSValue() >+ when adding a new property. >+ >+ Lastly, we used to put undefined into deleted property offsets. To >+ make things simpler, this patch causes us to store JSValue() there >+ instead. >+ >+ * dfg/DFGOperations.cpp: >+ * runtime/Butterfly.h: >+ * runtime/ButterflyInlines.h: >+ (JSC::Butterfly::createUninitialized): >+ (JSC::Butterfly::tryCreate): >+ (JSC::Butterfly::create): >+ (JSC::Butterfly::createOrGrowPropertyStorage): >+ (JSC::Butterfly::createOrGrowArrayRight): >+ (JSC::Butterfly::growArrayRight): >+ (JSC::Butterfly::resizeArray): >+ * runtime/JSArray.cpp: >+ (JSC::createArrayButterflyInDictionaryIndexingMode): Deleted. >+ * runtime/JSArray.h: >+ (JSC::tryCreateArrayButterfly): >+ * runtime/JSObject.cpp: >+ (JSC::JSObject::createArrayStorageButterfly): >+ (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements): >+ (JSC::JSObject::convertFromCopyOnWrite): >+ (JSC::JSObject::deleteProperty): >+ (JSC::JSObject::shiftButterflyAfterFlattening): >+ * runtime/JSObject.h: >+ * runtime/JSObjectInlines.h: >+ (JSC::JSObject::prepareToPutDirectWithoutTransition): >+ * runtime/ObjectInitializationScope.cpp: >+ (JSC::ObjectInitializationScope::verifyPropertiesAreInitialized): >+ > 2018-06-13 Keith Miller <keith_miller@apple.com> > > AutomaticThread should have a way to provide a thread name >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp >index 7c9e70b6bd78b9993fd6dd4ae1e00614dd2a61ae..e409efda367761026fd569bdd67d7c391040b4f7 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -1849,7 +1849,7 @@ char* JIT_OPERATION operationAllocateSimplePropertyStorageWithInitialCapacity(Ex > NativeCallFrameTracer tracer(&vm, exec); > > return reinterpret_cast<char*>( >- Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0)); >+ Butterfly::createUninitialized(vm, nullptr, nullptr, 0, initialOutOfLineCapacity, false, 0)); > } > > char* JIT_OPERATION operationAllocateSimplePropertyStorage(ExecState* exec, size_t newSize) >@@ -1858,7 +1858,7 @@ char* JIT_OPERATION operationAllocateSimplePropertyStorage(ExecState* exec, size > NativeCallFrameTracer tracer(&vm, exec); > > return reinterpret_cast<char*>( >- Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0)); >+ Butterfly::createUninitialized(vm, nullptr, nullptr, 0, newSize, false, 0)); > } > > char* JIT_OPERATION operationAllocateComplexPropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object) >diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h >index 6485890d9b798b302fac7a4b5c87213887b22345..13cf23b9620a9c531d6771e95842a1807b034c26 100644 >--- a/Source/JavaScriptCore/runtime/Butterfly.h >+++ b/Source/JavaScriptCore/runtime/Butterfly.h >@@ -35,6 +35,7 @@ namespace JSC { > > class VM; > class CopyVisitor; >+class ObjectInitializationScope; > struct ArrayStorage; > > template <typename T> >@@ -160,11 +161,11 @@ public: > static ptrdiff_t offsetOfPublicLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfPublicLength(); } > static ptrdiff_t offsetOfVectorLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfVectorLength(); } > >- static Butterfly* createUninitialized(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); >+ static Butterfly* createUninitialized(VM&, ObjectInitializationScope*, JSObject* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); > >- static Butterfly* tryCreate(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes); >- static Butterfly* create(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes); >- static Butterfly* create(VM&, JSCell* intendedOwner, Structure*); >+ static Butterfly* tryCreate(VM& vm, JSObject*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes); >+ static Butterfly* create(VM&, JSObject* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes); >+ static Butterfly* create(VM&, JSObject* intendedOwner, Structure*); > > IndexingHeader* indexingHeader() { return IndexingHeader::from(this); } > const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); } >@@ -203,7 +204,7 @@ public: > void* base(Structure*); > > static Butterfly* createOrGrowArrayRight( >- Butterfly*, VM&, JSCell* intendedOwner, Structure* oldStructure, >+ Butterfly*, VM&, JSObject* intendedOwner, Structure* oldStructure, > size_t propertyCapacity, bool hadIndexingHeader, > size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); > >@@ -212,11 +213,11 @@ public: > // methods is not exhaustive and is not intended to encapsulate all possible allocation > // modes of butterflies - there are code paths that allocate butterflies by calling > // directly into Heap::tryAllocateStorage. >- static Butterfly* createOrGrowPropertyStorage(Butterfly*, VM&, JSCell* intendedOwner, Structure*, size_t oldPropertyCapacity, size_t newPropertyCapacity); >- Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much. >- Butterfly* growArrayRight(VM&, JSCell* intendedOwner, Structure*, size_t newIndexingPayloadSizeInBytes); >- Butterfly* resizeArray(VM&, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes); >- Butterfly* resizeArray(VM&, JSCell* intendedOwner, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header. >+ static Butterfly* createOrGrowPropertyStorage(Butterfly*, VM&, JSObject* intendedOwner, Structure*, size_t oldPropertyCapacity, size_t newPropertyCapacity); >+ Butterfly* growArrayRight(VM&, JSObject* intendedOwner, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much. >+ Butterfly* growArrayRight(VM&, JSObject* intendedOwner, Structure*, size_t newIndexingPayloadSizeInBytes); >+ Butterfly* resizeArray(VM&, JSObject* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes); >+ Butterfly* resizeArray(VM&, JSObject* intendedOwner, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header. > Butterfly* unshift(Structure*, size_t numberOfSlots); > Butterfly* shift(Structure*, size_t numberOfSlots); > }; >diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h >index 6a89a0d384f1e1c76a0486dc9c9707bf14d930e6..d5481a26b3e23f5cee0d6893212bcea8d4985fd1 100644 >--- a/Source/JavaScriptCore/runtime/ButterflyInlines.h >+++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h >@@ -28,8 +28,9 @@ > #include "ArrayStorage.h" > #include "Butterfly.h" > #include "JSObject.h" >-#include "VM.h" >+#include "ObjectInitializationScope.h" > #include "Structure.h" >+#include "VM.h" > > namespace JSC { > >@@ -74,15 +75,21 @@ ALWAYS_INLINE unsigned Butterfly::optimalContiguousVectorLength(Structure* struc > return optimalContiguousVectorLength(structure ? structure->outOfLineCapacity() : 0, vectorLength); > } > >-inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) >+inline Butterfly* Butterfly::createUninitialized(VM& vm, ObjectInitializationScope* initializationScope, JSObject* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) > { > size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); > void* base = vm.jsValueGigacageAuxiliarySpace.allocateNonVirtual(vm, size, nullptr, AllocationFailureMode::Assert); > Butterfly* result = fromBase(base, preCapacity, propertyCapacity); >+ >+ const bool wasCreatedUnitializated = true; >+ >+ if (initializationScope) >+ initializationScope->notifyAllocated(intendedOwner, wasCreatedUnitializated); >+ > return result; > } > >-inline Butterfly* Butterfly::tryCreate(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) >+inline Butterfly* Butterfly::tryCreate(VM& vm, JSObject*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) > { > size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); > void* base = vm.jsValueGigacageAuxiliarySpace.allocateNonVirtual(vm, size, nullptr, AllocationFailureMode::ReturnNull); >@@ -95,7 +102,7 @@ inline Butterfly* Butterfly::tryCreate(VM& vm, JSCell*, size_t preCapacity, size > return result; > } > >-inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) >+inline Butterfly* Butterfly::create(VM& vm, JSObject* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) > { > Butterfly* result = tryCreate(vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader, indexingHeader, indexingPayloadSizeInBytes); > >@@ -103,7 +110,7 @@ inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCap > return result; > } > >-inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, Structure* structure) >+inline Butterfly* Butterfly::create(VM& vm, JSObject* intendedOwner, Structure* structure) > { > return create( > vm, intendedOwner, 0, structure->outOfLineCapacity(), >@@ -116,17 +123,18 @@ inline void* Butterfly::base(Structure* structure) > } > > inline Butterfly* Butterfly::createOrGrowPropertyStorage( >- Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity) >+ Butterfly* oldButterfly, VM& vm, JSObject* intendedOwner, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity) > { > RELEASE_ASSERT(newPropertyCapacity > oldPropertyCapacity); > if (!oldButterfly) > return create(vm, intendedOwner, 0, newPropertyCapacity, false, IndexingHeader(), 0); > >+ ObjectInitializationScope scope(vm); >+ > size_t preCapacity = oldButterfly->indexingHeader()->preCapacity(structure); > size_t indexingPayloadSizeInBytes = oldButterfly->indexingHeader()->indexingPayloadSizeInBytes(structure); > bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner); >- Butterfly* result = createUninitialized( >- vm, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); >+ Butterfly* result = createUninitialized(vm, &scope, intendedOwner, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); > memcpy( > result->propertyStorage() - oldPropertyCapacity, > oldButterfly->propertyStorage() - oldPropertyCapacity, >@@ -139,7 +147,7 @@ inline Butterfly* Butterfly::createOrGrowPropertyStorage( > } > > inline Butterfly* Butterfly::createOrGrowArrayRight( >- Butterfly* oldButterfly, VM& vm, JSCell* intendedOwner, Structure* oldStructure, >+ Butterfly* oldButterfly, VM& vm, JSObject* intendedOwner, Structure* oldStructure, > size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, > size_t newIndexingPayloadSizeInBytes) > { >@@ -154,7 +162,7 @@ inline Butterfly* Butterfly::createOrGrowArrayRight( > } > > inline Butterfly* Butterfly::growArrayRight( >- VM& vm, JSCell* intendedOwner, Structure* oldStructure, size_t propertyCapacity, >+ VM& vm, JSObject* intendedOwner, Structure* oldStructure, size_t propertyCapacity, > bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, > size_t newIndexingPayloadSizeInBytes) > { >@@ -172,7 +180,7 @@ inline Butterfly* Butterfly::growArrayRight( > } > > inline Butterfly* Butterfly::growArrayRight( >- VM& vm, JSCell* intendedOwner, Structure* oldStructure, >+ VM& vm, JSObject* intendedOwner, Structure* oldStructure, > size_t newIndexingPayloadSizeInBytes) > { > return growArrayRight( >@@ -183,12 +191,14 @@ inline Butterfly* Butterfly::growArrayRight( > } > > inline Butterfly* Butterfly::resizeArray( >- VM& vm, JSCell* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, >+ VM& vm, JSObject* intendedOwner, size_t propertyCapacity, bool oldHasIndexingHeader, > size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, > size_t newIndexingPayloadSizeInBytes) > { >+ ObjectInitializationScope scope(vm); >+ > Butterfly* result = createUninitialized( >- vm, intendedOwner, newPreCapacity, propertyCapacity, newHasIndexingHeader, >+ vm, &scope, intendedOwner, newPreCapacity, propertyCapacity, newHasIndexingHeader, > newIndexingPayloadSizeInBytes); > // FIXME: This could be made much more efficient if we used the property size, > // not the capacity. >@@ -202,7 +212,7 @@ inline Butterfly* Butterfly::resizeArray( > } > > inline Butterfly* Butterfly::resizeArray( >- VM& vm, JSCell* intendedOwner, Structure* structure, size_t newPreCapacity, >+ VM& vm, JSObject* intendedOwner, Structure* structure, size_t newPreCapacity, > size_t newIndexingPayloadSizeInBytes) > { > bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner); >diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp >index 1ad6eb3edf2182d29b074a333a06f7cf8ce212ae..536c705523913a676cdfa717fd7dc917fa704008 100644 >--- a/Source/JavaScriptCore/runtime/JSArray.cpp >+++ b/Source/JavaScriptCore/runtime/JSArray.cpp >@@ -43,20 +43,6 @@ STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSArray); > > const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSArray)}; > >-Butterfly* createArrayButterflyInDictionaryIndexingMode( >- VM& vm, JSCell* intendedOwner, unsigned initialLength) >-{ >- Butterfly* butterfly = Butterfly::create( >- vm, intendedOwner, 0, 0, true, IndexingHeader(), ArrayStorage::sizeFor(0)); >- ArrayStorage* storage = butterfly->arrayStorage(); >- storage->setLength(initialLength); >- storage->setVectorLength(0); >- storage->m_indexBias = 0; >- storage->m_sparseMap.clear(); >- storage->m_numValuesInVector = 0; >- return butterfly; >-} >- > JSArray* JSArray::tryCreateUninitializedRestricted(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength) > { > VM& vm = scope.vm(); >diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h >index 7150bbfc450f0a1d824aa65f9919ee67223ab10e..602f2a0a0729a1d1a5d00bd962bb3ca2c4e2959c 100644 >--- a/Source/JavaScriptCore/runtime/JSArray.h >+++ b/Source/JavaScriptCore/runtime/JSArray.h >@@ -203,7 +203,7 @@ private: > void setLengthWritable(ExecState*, bool writable); > }; > >-inline Butterfly* tryCreateArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength) >+inline Butterfly* tryCreateArrayButterfly(VM& vm, JSObject* intendedOwner, unsigned initialLength) > { > Butterfly* butterfly = Butterfly::tryCreate( > vm, intendedOwner, 0, 0, true, baseIndexingHeaderForArrayStorage(initialLength), >@@ -217,9 +217,6 @@ inline Butterfly* tryCreateArrayButterfly(VM& vm, JSCell* intendedOwner, unsigne > return butterfly; > } > >-Butterfly* createArrayButterflyInDictionaryIndexingMode( >- VM&, JSCell* intendedOwner, unsigned initialLength); >- > inline JSArray* JSArray::tryCreate(VM& vm, Structure* structure, unsigned initialLength, unsigned vectorLengthHint) > { > ASSERT(vectorLengthHint >= initialLength); >diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp >index 696a146ecb5c9d29dda63e730c24a4eef1a242bc..0d981d90630f6abd9195c4d0a2cfa4ee1a8efcba 100644 >--- a/Source/JavaScriptCore/runtime/JSObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSObject.cpp >@@ -1089,7 +1089,7 @@ ContiguousJSValues JSObject::createInitialContiguous(VM& vm, unsigned length) > return newButterfly->contiguous(); > } > >-Butterfly* JSObject::createArrayStorageButterfly(VM& vm, JSCell* intendedOwner, Structure* structure, unsigned length, unsigned vectorLength, Butterfly* oldButterfly) >+Butterfly* JSObject::createArrayStorageButterfly(VM& vm, JSObject* intendedOwner, Structure* structure, unsigned length, unsigned vectorLength, Butterfly* oldButterfly) > { > Butterfly* newButterfly = Butterfly::createOrGrowArrayRight( > oldButterfly, vm, intendedOwner, structure, structure->outOfLineCapacity(), false, 0, >@@ -1172,16 +1172,17 @@ ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(VM& > Structure* structure = this->structure(vm); > unsigned publicLength = m_butterfly->publicLength(); > unsigned propertyCapacity = structure->outOfLineCapacity(); >- unsigned propertySize = structure->outOfLineSize(); >- >+ >+ ObjectInitializationScope scope(vm); >+ > Butterfly* newButterfly = Butterfly::createUninitialized( >- vm, this, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength)); >+ vm, &scope, this, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength)); > > memcpy( >- newButterfly->propertyStorage() - propertySize, >- m_butterfly->propertyStorage() - propertySize, >- propertySize * sizeof(EncodedJSValue)); >- >+ newButterfly->base(0, propertyCapacity), >+ m_butterfly->base(0, propertyCapacity), >+ propertyCapacity * sizeof(EncodedJSValue)); >+ > ArrayStorage* newStorage = newButterfly->arrayStorage(); > newStorage->setVectorLength(neededLength); > newStorage->setLength(publicLength); >@@ -1426,11 +1427,13 @@ void JSObject::convertFromCopyOnWrite(VM& vm) > ASSERT(isCopyOnWrite(indexingMode())); > ASSERT(structure(vm)->indexingMode() == indexingMode()); > >+ ObjectInitializationScope scope(vm); >+ > const bool hasIndexingHeader = true; > Butterfly* oldButterfly = butterfly(); > size_t propertyCapacity = 0; > unsigned newVectorLength = Butterfly::optimalContiguousVectorLength(propertyCapacity, std::min(oldButterfly->vectorLength() * 2, MAX_STORAGE_VECTOR_LENGTH)); >- Butterfly* newButterfly = Butterfly::createUninitialized(vm, this, 0, propertyCapacity, hasIndexingHeader, newVectorLength * sizeof(JSValue)); >+ Butterfly* newButterfly = Butterfly::createUninitialized(vm, &scope, this, 0, propertyCapacity, hasIndexingHeader, newVectorLength * sizeof(JSValue)); > > memcpy(newButterfly->propertyStorage(), oldButterfly->propertyStorage(), oldButterfly->vectorLength() * sizeof(JSValue) + sizeof(IndexingHeader)); > >@@ -1912,7 +1915,7 @@ bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName proper > thisObject->setStructure(vm, Structure::removePropertyTransition(vm, structure, propertyName, offset)); > > if (offset != invalidOffset) >- thisObject->putDirectUndefined(offset); >+ thisObject->locationForOffset(offset)->clear(); > } > > return true; >@@ -3629,7 +3632,8 @@ void JSObject::shiftButterflyAfterFlattening(const GCSafeConcurrentJSLocker&, VM > // This could interleave visitChildren because some old structure could have been a non > // dictionary structure. We have to be crazy careful. But, we are guaranteed to be holding > // the structure's lock right now, and that helps a bit. >- >+ >+ ObjectInitializationScope scope(vm); > Butterfly* oldButterfly = this->butterfly(); > size_t preCapacity; > size_t indexingPayloadSizeInBytes; >@@ -3642,7 +3646,7 @@ void JSObject::shiftButterflyAfterFlattening(const GCSafeConcurrentJSLocker&, VM > indexingPayloadSizeInBytes = 0; > } > >- Butterfly* newButterfly = Butterfly::createUninitialized(vm, this, preCapacity, outOfLineCapacityAfter, hasIndexingHeader, indexingPayloadSizeInBytes); >+ Butterfly* newButterfly = Butterfly::createUninitialized(vm, &scope, this, preCapacity, outOfLineCapacityAfter, hasIndexingHeader, indexingPayloadSizeInBytes); > > // No need to copy the precapacity. > void* currentBase = oldButterfly->base(0, outOfLineCapacityAfter); >diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h >index faabc5d6c6e414e68d56c5adcbd5d637da5b8c77..88bb6e0b3efd2f5652b8d605c0559b9c4294adb7 100644 >--- a/Source/JavaScriptCore/runtime/JSObject.h >+++ b/Source/JavaScriptCore/runtime/JSObject.h >@@ -943,7 +943,7 @@ protected: > void convertDoubleForValue(VM&, JSValue); > void convertFromCopyOnWrite(VM&); > >- static Butterfly* createArrayStorageButterfly(VM&, JSCell* intendedOwner, Structure*, unsigned length, unsigned vectorLength, Butterfly* oldButterfly = nullptr); >+ static Butterfly* createArrayStorageButterfly(VM&, JSObject* intendedOwner, Structure*, unsigned length, unsigned vectorLength, Butterfly* oldButterfly = nullptr); > ArrayStorage* createArrayStorage(VM&, unsigned length, unsigned vectorLength); > ArrayStorage* createInitialArrayStorage(VM&); > >diff --git a/Source/JavaScriptCore/runtime/JSObjectInlines.h b/Source/JavaScriptCore/runtime/JSObjectInlines.h >index efb0f53534624bffef984c4139f999b27823fbb6..ba480e39edc25a5be13aed280dd6ef1dc42aa790 100644 >--- a/Source/JavaScriptCore/runtime/JSObjectInlines.h >+++ b/Source/JavaScriptCore/runtime/JSObjectInlines.h >@@ -203,6 +203,7 @@ ALWAYS_INLINE PropertyOffset JSObject::prepareToPutDirectWithoutTransition(VM& v > setStructureIDDirectly(structureID); > } else > structure->setLastOffset(newLastOffset); >+ ASSERT(!getDirect(offset)); > result = offset; > }); > return result; >diff --git a/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp b/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp >index 9818a4cfba7eb72a21e1bcdb4bfe25d50952829f..1480531ca2cc09ac8a216dec075a7ae51da1247e 100644 >--- a/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp >+++ b/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp >@@ -60,7 +60,8 @@ void ObjectInitializationScope::notifyAllocated(JSObject* object, bool wasCreate > void ObjectInitializationScope::verifyPropertiesAreInitialized(JSObject* object) > { > Butterfly* butterfly = object->butterfly(); >- IndexingType indexingType = object->structure(m_vm)->indexingType(); >+ Structure* structure = object->structure(m_vm); >+ IndexingType indexingType = structure->indexingType(); > unsigned vectorLength = butterfly->vectorLength(); > if (UNLIKELY(hasUndecided(indexingType))) { > // Nothing to verify. >@@ -68,7 +69,7 @@ void ObjectInitializationScope::verifyPropertiesAreInitialized(JSObject* object) > auto data = butterfly->contiguous().data(); > for (unsigned i = 0; i < vectorLength; ++i) { > if (isScribbledValue(data[i].get())) { >- dataLog("Found scribbled value at i = ", i, "\n"); >+ dataLogLn("Found scribbled value at i = ", i); > ASSERT_NOT_REACHED(); > } > } >@@ -76,11 +77,21 @@ void ObjectInitializationScope::verifyPropertiesAreInitialized(JSObject* object) > ArrayStorage* storage = butterfly->arrayStorage(); > for (unsigned i = 0; i < vectorLength; ++i) { > if (isScribbledValue(storage->m_vector[i].get())) { >- dataLog("Found scribbled value at i = ", i, "\n"); >+ dataLogLn("Found scribbled value at i = ", i); > ASSERT_NOT_REACHED(); > } > } > } >+ >+ for (int64_t i = 0; i < static_cast<int64_t>(structure->outOfLineCapacity()); i++) { >+ // We rely on properties past the last offset be zero for concurrent GC. >+ if (i + firstOutOfLineOffset > structure->lastOffset()) >+ ASSERT(!butterfly->propertyStorage()[-i - 1].get()); >+ else if (isScribbledValue(butterfly->propertyStorage()[-i - 1].get())) { >+ dataLogLn("Found scribbled property at i = ", -i - 1); >+ ASSERT_NOT_REACHED(); >+ } >+ } > } > #endif >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186692
:
342843
|
342851
|
342854
|
342859
|
342865
|
342872
|
342873
|
342875
|
342876
|
342959
|
342967
|
342972
|
342981
|
342983