X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..4be4e30906bcb8ee30b4d189205cb70bad6707ce:/runtime/JSObject.cpp?ds=inline diff --git a/runtime/JSObject.cpp b/runtime/JSObject.cpp index a39daff..d18b4e2 100644 --- a/runtime/JSObject.cpp +++ b/runtime/JSObject.cpp @@ -595,7 +595,7 @@ void JSObject::notifyPresenceOfIndexedAccessors(VM& vm) if (mayInterceptIndexedAccesses()) return; - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AddIndexedAccessors)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AddIndexedAccessors), m_butterfly); if (!vm.prototypeMap.isPrototype(this)) return; @@ -681,7 +681,7 @@ ArrayStorage* JSObject::createInitialArrayStorage(VM& vm) ContiguousJSValues JSObject::convertUndecidedToInt32(VM& vm) { ASSERT(hasUndecided(structure()->indexingType())); - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateInt32)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateInt32), m_butterfly); return m_butterfly->contiguousInt32(); } @@ -692,14 +692,14 @@ ContiguousDoubles JSObject::convertUndecidedToDouble(VM& vm) for (unsigned i = m_butterfly->vectorLength(); i--;) m_butterfly->contiguousDouble()[i] = QNaN; - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateDouble)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateDouble), m_butterfly); return m_butterfly->contiguousDouble(); } ContiguousJSValues JSObject::convertUndecidedToContiguous(VM& vm) { ASSERT(hasUndecided(structure()->indexingType())); - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous), m_butterfly); return m_butterfly->contiguous(); } @@ -765,7 +765,7 @@ ContiguousDoubles JSObject::convertInt32ToDouble(VM& vm) *currentAsDouble = v.asInt32(); } - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateDouble)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateDouble), m_butterfly); return m_butterfly->contiguousDouble(); } @@ -773,7 +773,7 @@ ContiguousJSValues JSObject::convertInt32ToContiguous(VM& vm) { ASSERT(hasInt32(structure()->indexingType())); - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous), m_butterfly); return m_butterfly->contiguous(); } @@ -831,7 +831,7 @@ ContiguousJSValues JSObject::genericConvertDoubleToContiguous(VM& vm) currentAsValue->setWithoutWriteBarrier(v); } - setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous)); + setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous), m_butterfly); return m_butterfly->contiguous(); } @@ -1129,7 +1129,7 @@ void JSObject::switchToSlowPutArrayStorage(VM& vm) case NonArrayWithArrayStorage: case ArrayWithArrayStorage: { Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), SwitchToSlowPutArrayStorage); - setStructure(vm, newStructure); + setStructure(vm, newStructure, m_butterfly); break; } @@ -1153,7 +1153,7 @@ void JSObject::setPrototype(VM& vm, JSValue prototype) vm.prototypeMap.addPrototype(asObject(prototype)); Structure* newStructure = Structure::changePrototypeTransition(vm, structure(), prototype); - setStructure(vm, newStructure); + setStructure(vm, newStructure, m_butterfly); if (!newStructure->anyObjectInChainMayInterceptIndexedAccesses()) return; @@ -1213,7 +1213,7 @@ void JSObject::putDirectAccessor(ExecState* exec, PropertyName propertyName, JSV // getters and setters, though, we also need to change our Structure // if we override an existing non-getter or non-setter. if (slot.type() != PutPropertySlot::NewProperty) - setStructure(vm, Structure::attributeChangeTransition(vm, structure(), propertyName, attributes)); + setStructure(vm, Structure::attributeChangeTransition(vm, structure(), propertyName, attributes), m_butterfly); if (attributes & ReadOnly) structure()->setContainsReadOnlyProperties(); @@ -1570,7 +1570,7 @@ void JSObject::seal(VM& vm) if (isSealed(vm)) return; preventExtensions(vm); - setStructure(vm, Structure::sealTransition(vm, structure())); + setStructure(vm, Structure::sealTransition(vm, structure()), m_butterfly); } void JSObject::freeze(VM& vm) @@ -1578,14 +1578,14 @@ void JSObject::freeze(VM& vm) if (isFrozen(vm)) return; preventExtensions(vm); - setStructure(vm, Structure::freezeTransition(vm, structure())); + setStructure(vm, Structure::freezeTransition(vm, structure()), m_butterfly); } void JSObject::preventExtensions(VM& vm) { enterDictionaryIndexingMode(vm); if (isExtensible()) - setStructure(vm, Structure::preventExtensionsTransition(vm, structure())); + setStructure(vm, Structure::preventExtensionsTransition(vm, structure()), m_butterfly); } // This presently will flatten to an uncachable dictionary; this is suitable @@ -1603,7 +1603,7 @@ void JSObject::reifyStaticFunctionsForDelete(ExecState* exec) } if (!structure()->isUncacheableDictionary()) - setStructure(vm, Structure::toUncacheableDictionaryTransition(vm, structure())); + setStructure(vm, Structure::toUncacheableDictionaryTransition(vm, structure()), m_butterfly); for (const ClassInfo* info = classInfo(); info; info = info->parentClass) { const HashTable* hashTable = info->propHashTable(globalObject()->globalExec()); @@ -1633,7 +1633,7 @@ bool JSObject::removeDirect(VM& vm, PropertyName propertyName) return true; } - setStructure(vm, Structure::removePropertyTransition(vm, structure(), propertyName, offset)); + setStructure(vm, Structure::removePropertyTransition(vm, structure(), propertyName, offset), m_butterfly); if (offset == invalidOffset) return false; putDirectUndefined(offset); @@ -1872,7 +1872,8 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un if (i >= MAX_ARRAY_INDEX - 1 || (i >= MIN_SPARSE_ARRAY_INDEX - && !isDenseEnoughForVector(i, countElements(m_butterfly)))) { + && !isDenseEnoughForVector(i, countElements(m_butterfly))) + || indexIsSufficientlyBeyondLengthForSparseMap(i, m_butterfly->vectorLength())) { ASSERT(i <= MAX_ARRAY_INDEX); ensureArrayStorageSlow(vm); SparseArrayValueMap* map = allocateSparseIndexMap(vm); @@ -1920,7 +1921,7 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns // First, handle cases where we don't currently have a sparse map. if (LIKELY(!map)) { - // If the array is not extensible, we should have entered dictionary mode, and created the spare map. + // If the array is not extensible, we should have entered dictionary mode, and created the sparse map. ASSERT(isExtensible()); // Update m_length if necessary. @@ -1928,7 +1929,9 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns storage->setLength(i + 1); // Check that it is sensible to still be using a vector, and then try to grow the vector. - if (LIKELY((isDenseEnoughForVector(i, storage->m_numValuesInVector)) && increaseVectorLength(vm, i + 1))) { + if (LIKELY(!indexIsSufficientlyBeyondLengthForSparseMap(i, storage->vectorLength()) + && isDenseEnoughForVector(i, storage->m_numValuesInVector) + && increaseVectorLength(vm, i + 1))) { // success! - reread m_storage since it has likely been reallocated, and store to the vector. storage = arrayStorage(); storage->m_vector[i].set(vm, this, value); @@ -1995,7 +1998,7 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue ensureArrayStorageExistsAndEnterDictionaryIndexingMode(vm)); break; } - if (i >= MIN_SPARSE_ARRAY_INDEX) { + if (indexIsSufficientlyBeyondLengthForSparseMap(i, 0) || i >= MIN_SPARSE_ARRAY_INDEX) { putByIndexBeyondVectorLengthWithArrayStorage( exec, i, value, shouldThrow, createArrayStorage(vm, 0, 0)); break; @@ -2075,7 +2078,8 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, if (LIKELY( !attributes && (isDenseEnoughForVector(i, storage->m_numValuesInVector)) - && increaseVectorLength(vm, i + 1))) { + && !indexIsSufficientlyBeyondLengthForSparseMap(i, storage->vectorLength())) + && increaseVectorLength(vm, i + 1)) { // success! - reread m_storage since it has likely been reallocated, and store to the vector. storage = arrayStorage(); storage->m_vector[i].set(vm, this, value);