hasIndexingHeader() ought really to be a property of an object and its structure, not just its structure
https://bugs.webkit.org/show_bug.cgi?id=119470

Reviewed by Oliver Hunt.
        
Structure can still tell you if the object "could" (in the conservative sense)
have an indexing header; that's used by the compiler.
        
Most of the time if you want to know if there's an indexing header, you ask the
JSObject.
        
In some cases, the JSObject wants to know if it would have an indexing header if
it had a different structure; then it uses Structure::hasIndexingHeader(JSCell*).

* dfg/DFGRepatch.cpp:
(JSC::DFG::tryCachePutByID):
(JSC::DFG::tryBuildPutByIdList):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
(JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
* runtime/ButterflyInlines.h:
(JSC::Butterfly::create):
(JSC::Butterfly::growPropertyStorage):
(JSC::Butterfly::growArrayRight):
(JSC::Butterfly::resizeArray):
* runtime/JSObject.cpp:
(JSC::JSObject::copyButterfly):
(JSC::JSObject::visitButterfly):
* runtime/JSObject.h:
(JSC::JSObject::hasIndexingHeader):
(JSC::JSObject::setButterfly):
* runtime/Structure.h:
(JSC::Structure::couldHaveIndexingHeader):
(JSC::Structure::hasIndexingHeader):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153691 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 652d63a..c69ac63 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,40 @@
+2013-08-03  Filip Pizlo  <fpizlo@apple.com>
+
+        hasIndexingHeader() ought really to be a property of an object and its structure, not just its structure
+        https://bugs.webkit.org/show_bug.cgi?id=119470
+
+        Reviewed by Oliver Hunt.
+        
+        Structure can still tell you if the object "could" (in the conservative sense)
+        have an indexing header; that's used by the compiler.
+        
+        Most of the time if you want to know if there's an indexing header, you ask the
+        JSObject.
+        
+        In some cases, the JSObject wants to know if it would have an indexing header if
+        it had a different structure; then it uses Structure::hasIndexingHeader(JSCell*).
+
+        * dfg/DFGRepatch.cpp:
+        (JSC::DFG::tryCachePutByID):
+        (JSC::DFG::tryBuildPutByIdList):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+        (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+        * runtime/ButterflyInlines.h:
+        (JSC::Butterfly::create):
+        (JSC::Butterfly::growPropertyStorage):
+        (JSC::Butterfly::growArrayRight):
+        (JSC::Butterfly::resizeArray):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::copyButterfly):
+        (JSC::JSObject::visitButterfly):
+        * runtime/JSObject.h:
+        (JSC::JSObject::hasIndexingHeader):
+        (JSC::JSObject::setButterfly):
+        * runtime/Structure.h:
+        (JSC::Structure::couldHaveIndexingHeader):
+        (JSC::Structure::hasIndexingHeader):
+
 2013-08-02  Chris Curtis  <chris_curtis@apple.com>
 
         Give the error object's stack property accessor attributes.
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 5573066..154f3dd 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -965,7 +965,7 @@
             
             // Skip optimizing the case where we need realloc, and the structure has
             // indexing storage.
-            if (oldStructure->hasIndexingHeader())
+            if (oldStructure->couldHaveIndexingHeader())
                 return false;
             
             if (normalizePrototypeChain(exec, baseCell) == InvalidPrototypeChain)
@@ -1040,7 +1040,7 @@
             
             // Skip optimizing the case where we need realloc, and the structure has
             // indexing storage.
-            if (oldStructure->hasIndexingHeader())
+            if (oldStructure->couldHaveIndexingHeader())
                 return false;
             
             if (normalizePrototypeChain(exec, baseCell) == InvalidPrototypeChain)
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 8f87089..f16a0e9 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -4259,7 +4259,7 @@
 
 void SpeculativeJIT::compileAllocatePropertyStorage(Node* node)
 {
-    if (node->structureTransitionData().previousStructure->hasIndexingHeader()) {
+    if (node->structureTransitionData().previousStructure->couldHaveIndexingHeader()) {
         SpeculateCellOperand base(this, node->child1());
         
         GPRReg baseGPR = base.gpr();
@@ -4302,7 +4302,7 @@
     size_t newSize = oldSize * outOfLineGrowthFactor;
     ASSERT(newSize == node->structureTransitionData().newStructure->outOfLineCapacity() * sizeof(JSValue));
 
-    if (node->structureTransitionData().previousStructure->hasIndexingHeader()) {
+    if (node->structureTransitionData().previousStructure->couldHaveIndexingHeader()) {
         SpeculateCellOperand base(this, node->child1());
         
         GPRReg baseGPR = base.gpr();
diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h
index d7ce69c..f5439bb 100644
--- a/Source/JavaScriptCore/runtime/ButterflyInlines.h
+++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h
@@ -58,7 +58,7 @@
 {
     return create(
         vm, intendedOwner, 0, structure->outOfLineCapacity(),
-        structure->hasIndexingHeader(), IndexingHeader(), 0);
+        structure->hasIndexingHeader(intendedOwner), IndexingHeader(), 0);
 }
 
 inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
@@ -96,7 +96,7 @@
 {
     return growPropertyStorage(
         vm, intendedOwner, indexingHeader()->preCapacity(structure), oldPropertyCapacity,
-        structure->hasIndexingHeader(),
+        structure->hasIndexingHeader(intendedOwner),
         indexingHeader()->indexingPayloadSizeInBytes(structure), newPropertyCapacity);
 }
 
@@ -129,7 +129,7 @@
     size_t newIndexingPayloadSizeInBytes)
 {
     ASSERT_UNUSED(oldStructure, !indexingHeader()->preCapacity(oldStructure));
-    ASSERT_UNUSED(oldStructure, hadIndexingHeader == oldStructure->hasIndexingHeader());
+    ASSERT_UNUSED(oldStructure, hadIndexingHeader == oldStructure->hasIndexingHeader(intendedOwner));
     void* theBase = base(0, propertyCapacity);
     size_t oldSize = totalSize(0, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes);
     size_t newSize = totalSize(0, propertyCapacity, true, newIndexingPayloadSizeInBytes);
@@ -144,7 +144,7 @@
 {
     return growArrayRight(
         vm, intendedOwner, oldStructure, oldStructure->outOfLineCapacity(),
-        oldStructure->hasIndexingHeader(), 
+        oldStructure->hasIndexingHeader(intendedOwner), 
         indexingHeader()->indexingPayloadSizeInBytes(oldStructure),
         newIndexingPayloadSizeInBytes);
 }
@@ -172,7 +172,7 @@
     VM& vm, JSCell* intendedOwner, Structure* structure, size_t newPreCapacity,
     size_t newIndexingPayloadSizeInBytes)
 {
-    bool hasIndexingHeader = structure->hasIndexingHeader();
+    bool hasIndexingHeader = structure->hasIndexingHeader(intendedOwner);
     return resizeArray(
         vm, intendedOwner, structure->outOfLineCapacity(), hasIndexingHeader,
         indexingHeader()->indexingPayloadSizeInBytes(structure), newPreCapacity,
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index bfb1789..33108f5 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -102,7 +102,7 @@
     size_t propertyCapacity = structure->outOfLineCapacity();
     size_t preCapacity;
     size_t indexingPayloadSizeInBytes;
-    bool hasIndexingHeader = structure->hasIndexingHeader();
+    bool hasIndexingHeader = this->hasIndexingHeader();
     if (UNLIKELY(hasIndexingHeader)) {
         preCapacity = butterfly->indexingHeader()->preCapacity(structure);
         indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure);
@@ -173,7 +173,7 @@
     size_t propertyCapacity = structure->outOfLineCapacity();
     size_t preCapacity;
     size_t indexingPayloadSizeInBytes;
-    bool hasIndexingHeader = structure->hasIndexingHeader();
+    bool hasIndexingHeader = this->hasIndexingHeader();
     if (UNLIKELY(hasIndexingHeader)) {
         preCapacity = butterfly->indexingHeader()->preCapacity(structure);
         indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure);
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index dd8f7dd..9241ce1 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -189,6 +189,11 @@
     // A non-throwing version of putDirect and putDirectIndex.
     JS_EXPORT_PRIVATE void putDirectMayBeIndex(ExecState*, PropertyName, JSValue);
         
+    bool hasIndexingHeader() const
+    {
+        return structure()->hasIndexingHeader(this);
+    }
+    
     bool canGetIndexQuickly(unsigned i)
     {
         switch (structure()->indexingType()) {
@@ -1107,7 +1112,7 @@
 inline void JSObject::setButterfly(VM& vm, Butterfly* butterfly, Structure* structure)
 {
     ASSERT(structure);
-    ASSERT(!butterfly == (!structure->outOfLineCapacity() && !structure->hasIndexingHeader()));
+    ASSERT(!butterfly == (!structure->outOfLineCapacity() && !structure->hasIndexingHeader(this)));
     setStructure(vm, structure);
     m_butterfly = butterfly;
 }
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index e917bc9..220f17c 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -228,11 +228,16 @@
             && (offset < m_inlineCapacity || offset >= firstOutOfLineOffset);
     }
     
-    bool hasIndexingHeader() const
+    bool couldHaveIndexingHeader() const
     {
         return hasIndexedProperties(indexingType());
     }
-
+    
+    bool hasIndexingHeader(const JSCell*) const
+    {
+        return hasIndexedProperties(indexingType());
+    }
+    
     bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
 
     PropertyOffset get(VM&, PropertyName);