Fast path of storage resize should be removed from property storage reallocation, since it is only useful for arrays
https://bugs.webkit.org/show_bug.cgi?id=91796

Reviewed by Geoffrey Garen.

* dfg/DFGRepatch.cpp:
(JSC::DFG::emitPutTransitionStub):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
* runtime/JSObject.cpp:
(JSC::JSObject::growOutOfLineStorage):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@123164 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 5e29b0d..b9b0ae6 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,17 @@
+2012-07-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Fast path of storage resize should be removed from property storage reallocation, since it is only useful for arrays
+        https://bugs.webkit.org/show_bug.cgi?id=91796
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGRepatch.cpp:
+        (JSC::DFG::emitPutTransitionStub):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::growOutOfLineStorage):
+
 2012-07-19  Mark Lam  <mark.lam@apple.com>
 
         Bug fixes and enhancements for OfflineASM annotation system.
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 7d5432d..19e064f 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -829,21 +829,8 @@
             size_t oldSize = oldStructure->outOfLineCapacity() * sizeof(JSValue);
             ASSERT(newSize > oldSize);
             
-            // Optimistically assume that the old storage was the very last thing
-            // allocated.
             stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR3);
-            stubJit.loadPtr(&copiedAllocator->m_currentPayloadEnd, scratchGPR2);
             stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1);
-            stubJit.subPtr(scratchGPR1, scratchGPR2);
-            stubJit.subPtr(MacroAssembler::TrustedImm32(oldSize), scratchGPR2);
-            MacroAssembler::Jump needFullRealloc =
-                stubJit.branchPtr(MacroAssembler::NotEqual, scratchGPR2, scratchGPR3);
-            slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize - oldSize), scratchGPR1));
-            stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining);
-            stubJit.move(scratchGPR2, scratchGPR1);
-            MacroAssembler::Jump doneRealloc = stubJit.jump();
-            
-            needFullRealloc.link(&stubJit);
             slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1));
             stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining);
             stubJit.negPtr(scratchGPR1);
@@ -854,8 +841,6 @@
                 stubJit.loadPtr(MacroAssembler::Address(scratchGPR3, offset), scratchGPR2);
                 stubJit.storePtr(scratchGPR2, MacroAssembler::Address(scratchGPR1, offset));
             }
-            
-            doneRealloc.link(&stubJit);
         }
         
         stubJit.storePtr(scratchGPR1, MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()));
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index fdee5b2..47777f1 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -3177,26 +3177,15 @@
     GPRReg scratchGPR1 = scratch1.gpr();
     GPRReg scratchGPR2 = scratch2.gpr();
         
-    JITCompiler::JumpList slowPath;
+    JITCompiler::Jump slowPath;
         
     size_t oldSize = node.structureTransitionData().previousStructure->outOfLineCapacity() * sizeof(JSValue);
     size_t newSize = oldSize * outOfLineGrowthFactor;
     ASSERT(newSize == node.structureTransitionData().newStructure->outOfLineCapacity() * sizeof(JSValue));
     CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator();
         
-    m_jit.loadPtr(&copiedAllocator->m_currentPayloadEnd, scratchGPR1);
     m_jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR2);
-    m_jit.subPtr(scratchGPR2, scratchGPR1);
-    m_jit.subPtr(JITCompiler::TrustedImm32(oldSize), scratchGPR1);
-    JITCompiler::Jump needFullRealloc = m_jit.branchPtr(JITCompiler::NotEqual, scratchGPR1, oldStorageGPR);
-    
-    slowPath.append(m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize - oldSize), scratchGPR2));
-    m_jit.storePtr(scratchGPR2, &copiedAllocator->m_currentRemaining);
-    m_jit.move(oldStorageGPR, scratchGPR2);
-    JITCompiler::Jump doneRealloc = m_jit.jump();
-        
-    needFullRealloc.link(&m_jit);
-    slowPath.append(m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize), scratchGPR2));
+    slowPath = m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize), scratchGPR2);
     m_jit.storePtr(scratchGPR2, &copiedAllocator->m_currentRemaining);
     m_jit.negPtr(scratchGPR2);
     m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR2);
@@ -3210,9 +3199,7 @@
         m_jit.storePtr(scratchGPR1, JITCompiler::Address(scratchGPR2, offset));
     }
     m_jit.storePtr(scratchGPR2, JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()));
-        
-    doneRealloc.link(&m_jit);
-        
+    
     storageResult(scratchGPR2, m_compileIndex);
 }
 
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index ccc49fd..587929f 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -599,19 +599,13 @@
     PropertyStorage oldPropertyStorage = m_outOfLineStorage.get();
     PropertyStorage newPropertyStorage = 0;
 
-    if (!oldPropertyStorage) {
-        // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
-        void* temp = newPropertyStorage;
-        if (!globalData.heap.tryAllocateStorage(sizeof(WriteBarrierBase<Unknown>) * newSize, &temp))
-            CRASH();
-        newPropertyStorage = static_cast<PropertyStorage>(temp);
-    } else {
-        // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
-        void* temp = oldPropertyStorage;
-        if (!globalData.heap.tryReallocateStorage(&temp, sizeof(WriteBarrierBase<Unknown>) * oldSize, sizeof(WriteBarrierBase<Unknown>) * newSize))
-            CRASH();
-        newPropertyStorage = static_cast<PropertyStorage>(temp);
-    }
+    // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
+    void* temp = newPropertyStorage;
+    if (!globalData.heap.tryAllocateStorage(sizeof(WriteBarrierBase<Unknown>) * newSize, &temp))
+        CRASH();
+    newPropertyStorage = static_cast<PropertyStorage>(temp);
+    
+    memcpy(newPropertyStorage, oldPropertyStorage, sizeof(WriteBarrierBase<Unknown>) * oldSize);
 
     ASSERT(newPropertyStorage);
     return newPropertyStorage;