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 a0aba9c..c54a9bd 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 6a3b16d..fa544d2 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 50c77f7..6e6779b 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 79fe444..c589def 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 29cb941..892e2ca 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);