Indexing should only be computed when the new structure has an indexing header.
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Dec 2017 18:20:04 +0000 (18:20 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Dec 2017 18:20:04 +0000 (18:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180895

Reviewed by Saam Barati.

If we don't have an indexing header then we point the butterfly
sizeof(IndexingHeader) past the end of the butterfly. This makes
the computation of the offset simpler since it doesn't depend on
the indexing headeriness of the butterfly.

* jit/JITOperations.cpp:
* runtime/JSObject.cpp:
(JSC::JSObject::createInitialUndecided):
(JSC::JSObject::createInitialInt32):
(JSC::JSObject::createInitialDouble):
(JSC::JSObject::createInitialContiguous):
(JSC::JSObject::createArrayStorage):
(JSC::JSObject::convertUndecidedToArrayStorage):
(JSC::JSObject::convertInt32ToArrayStorage):
(JSC::JSObject::convertDoubleToArrayStorage):
* runtime/JSObject.h:
(JSC::JSObject::setButterfly):
(JSC::JSObject::nukeStructureAndSetButterfly):
* runtime/JSObjectInlines.h:
(JSC::JSObject::prepareToPutDirectWithoutTransition):
(JSC::JSObject::putDirectInternal):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226000 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSObjectInlines.h

index a0aba9c7dbdd5a6d075f978e36bd783726e01fd0..c54a9bd9b2b088f576c8dfc591837e6f0d3c086a 100644 (file)
@@ -1,3 +1,32 @@
+2017-12-16  Keith Miller  <keith_miller@apple.com>
+
+        Indexing should only be computed when the new structure has an indexing header.
+        https://bugs.webkit.org/show_bug.cgi?id=180895
+
+        Reviewed by Saam Barati.
+
+        If we don't have an indexing header then we point the butterfly
+        sizeof(IndexingHeader) past the end of the butterfly. This makes
+        the computation of the offset simpler since it doesn't depend on
+        the indexing headeriness of the butterfly.
+
+        * jit/JITOperations.cpp:
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::createInitialUndecided):
+        (JSC::JSObject::createInitialInt32):
+        (JSC::JSObject::createInitialDouble):
+        (JSC::JSObject::createInitialContiguous):
+        (JSC::JSObject::createArrayStorage):
+        (JSC::JSObject::convertUndecidedToArrayStorage):
+        (JSC::JSObject::convertInt32ToArrayStorage):
+        (JSC::JSObject::convertDoubleToArrayStorage):
+        * runtime/JSObject.h:
+        (JSC::JSObject::setButterfly):
+        (JSC::JSObject::nukeStructureAndSetButterfly):
+        * runtime/JSObjectInlines.h:
+        (JSC::JSObject::prepareToPutDirectWithoutTransition):
+        (JSC::JSObject::putDirectInternal):
+
 2017-12-15  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r225941.
index 6a3b16dc4d8e38def3fb3334e172d399c1eea18f..fa544d2600e85438c3384404a0677dd2dfe00c4a 100644 (file)
@@ -2311,7 +2311,7 @@ char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitial
 
     ASSERT(!object->structure()->outOfLineCapacity());
     Butterfly* result = object->allocateMoreOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
-    object->nukeStructureAndSetButterfly(vm, object->structureID(), result);
+    object->nukeStructureAndSetButterfly(vm, object->structureID(), result, object->indexingType());
     return reinterpret_cast<char*>(result);
 }
 
@@ -2321,7 +2321,7 @@ char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*
     NativeCallFrameTracer tracer(&vm, exec);
 
     Butterfly* result = object->allocateMoreOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
-    object->nukeStructureAndSetButterfly(vm, object->structureID(), result);
+    object->nukeStructureAndSetButterfly(vm, object->structureID(), result, object->indexingType());
     return reinterpret_cast<char*>(result);
 }
 
index 50c77f73a4e8978d528f0b6f26ee22e93d641c73..6e6779b337cb05149c8fa09cfc653de959c90b42 100644 (file)
@@ -1040,7 +1040,7 @@ Butterfly* JSObject::createInitialUndecided(VM& vm, unsigned length)
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, NonPropertyTransition::AllocateUndecided);
-    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly);
+    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly, newStructure->indexingType());
     setStructure(vm, newStructure);
     return newButterfly;
 }
@@ -1055,7 +1055,7 @@ ContiguousJSValues JSObject::createInitialInt32(VM& vm, unsigned length)
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, NonPropertyTransition::AllocateInt32);
-    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly);
+    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly, newStructure->indexingType());
     setStructure(vm, newStructure);
     return newButterfly->contiguousInt32();
 }
@@ -1070,7 +1070,7 @@ ContiguousDoubles JSObject::createInitialDouble(VM& vm, unsigned length)
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, NonPropertyTransition::AllocateDouble);
-    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly);
+    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly, newStructure->indexingType());
     setStructure(vm, newStructure);
     return newButterfly->contiguousDouble();
 }
@@ -1085,7 +1085,7 @@ ContiguousJSValues JSObject::createInitialContiguous(VM& vm, unsigned length)
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, NonPropertyTransition::AllocateContiguous);
-    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly);
+    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly, newStructure->indexingType());
     setStructure(vm, newStructure);
     return newButterfly->contiguous();
 }
@@ -1120,7 +1120,7 @@ ArrayStorage* JSObject::createArrayStorage(VM& vm, unsigned length, unsigned vec
     Butterfly* newButterfly = createArrayStorageButterfly(vm, this, oldStructure, length, vectorLength, butterfly());
     ArrayStorage* result = newButterfly->arrayStorage();
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, suggestedArrayStorageTransition());
-    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly);
+    nukeStructureAndSetButterfly(vm, oldStructureID, newButterfly, newStructure->indexingType());
     setStructure(vm, newStructure);
     return result;
 }
@@ -1207,7 +1207,7 @@ ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransi
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition);
-    nukeStructureAndSetButterfly(vm, oldStructureID, storage->butterfly());
+    nukeStructureAndSetButterfly(vm, oldStructureID, storage->butterfly(), newStructure->indexingType());
     setStructure(vm, newStructure);
     return storage;
 }
@@ -1265,7 +1265,7 @@ ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition);
-    nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly());
+    nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly(), newStructure->indexingType());
     setStructure(vm, newStructure);
     return newStorage;
 }
@@ -1318,7 +1318,7 @@ ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransitio
     StructureID oldStructureID = this->structureID();
     Structure* oldStructure = vm.getStructure(oldStructureID);
     Structure* newStructure = Structure::nonPropertyTransition(vm, oldStructure, transition);
-    nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly());
+    nukeStructureAndSetButterfly(vm, oldStructureID, newStorage->butterfly(), newStructure->indexingType());
     setStructure(vm, newStructure);
     return newStorage;
 }
index 79fe444333fe43c29834edf1b4e5996674262e37..c589defa615e1aad895717a9622176f4bdb14818 100644 (file)
@@ -769,7 +769,7 @@ public:
     
     // Call this if you do need to change the structure, or if you changed something about a structure
     // in-place.
-    void nukeStructureAndSetButterfly(VM&, StructureID, Butterfly*);
+    void nukeStructureAndSetButterfly(VM&, StructureID oldStructureID, Butterfly*, IndexingType newIndexingType);
 
     // Call this only if you are a JSGenericTypedArrayView or are clearing the butterfly.
     void setButterflyWithIndexingMask(VM&, Butterfly*, uint32_t indexingMask);
@@ -1265,7 +1265,7 @@ inline void JSObject::setButterflyWithIndexingMask(VM& vm, Butterfly* butterfly,
 
 inline void JSObject::setButterfly(VM& vm, Butterfly* butterfly)
 {
-    if (LIKELY(!structure(vm)->hijacksIndexingHeader())) {
+    if (hasIndexedProperties(indexingType())) {
         m_butterflyIndexingMask = butterfly->computeIndexingMask();
         ASSERT(m_butterflyIndexingMask >= butterfly->vectorLength());
     }
@@ -1280,9 +1280,9 @@ inline void JSObject::setButterfly(VM& vm, Butterfly* butterfly)
     m_butterfly.set(vm, this, butterfly);
 }
 
-inline void JSObject::nukeStructureAndSetButterfly(VM& vm, StructureID oldStructureID, Butterfly* butterfly)
+inline void JSObject::nukeStructureAndSetButterfly(VM& vm, StructureID oldStructureID, Butterfly* butterfly, IndexingType newIndexingType)
 {
-    if (LIKELY(!vm.getStructure(oldStructureID)->hijacksIndexingHeader())) {
+    if (hasIndexedProperties(newIndexingType)) {
         m_butterflyIndexingMask = butterfly->computeIndexingMask();
         ASSERT(m_butterflyIndexingMask >= butterfly->vectorLength());
     }
index 29cb941bf0e284f77a36a12990f7c62e1ee714ba..892e2ca45f97dd6f32a6a0e68a192e26ee53180b 100644 (file)
@@ -185,7 +185,7 @@ ALWAYS_INLINE PropertyOffset JSObject::prepareToPutDirectWithoutTransition(VM& v
             unsigned newOutOfLineCapacity = Structure::outOfLineCapacity(newLastOffset);
             if (newOutOfLineCapacity != oldOutOfLineCapacity) {
                 Butterfly* butterfly = allocateMoreOutOfLineStorage(vm, oldOutOfLineCapacity, newOutOfLineCapacity);
-                nukeStructureAndSetButterfly(vm, structureID, butterfly);
+                nukeStructureAndSetButterfly(vm, structureID, butterfly, structure->indexingType());
                 structure->setLastOffset(newLastOffset);
                 WTF::storeStoreFence();
                 setStructureIDDirectly(structureID);
@@ -312,7 +312,7 @@ ALWAYS_INLINE bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName
         if (currentCapacity != newStructure->outOfLineCapacity()) {
             ASSERT(newStructure != this->structure());
             newButterfly = allocateMoreOutOfLineStorage(vm, currentCapacity, newStructure->outOfLineCapacity());
-            nukeStructureAndSetButterfly(vm, structureID, newButterfly);
+            nukeStructureAndSetButterfly(vm, structureID, newButterfly, newStructure->indexingType());
         }
 
         validateOffset(offset);
@@ -366,7 +366,7 @@ ALWAYS_INLINE bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName
     ASSERT(oldCapacity <= newCapacity);
     if (oldCapacity != newCapacity) {
         Butterfly* newButterfly = allocateMoreOutOfLineStorage(vm, oldCapacity, newCapacity);
-        nukeStructureAndSetButterfly(vm, structureID, newButterfly);
+        nukeStructureAndSetButterfly(vm, structureID, newButterfly, newStructure->indexingType());
     }
     putDirect(vm, offset, value);
     setStructure(vm, newStructure);