Title: [94445] trunk/Source/_javascript_Core
Revision
94445
Author
[email protected]
Date
2011-09-02 13:41:59 -0700 (Fri, 02 Sep 2011)

Log Message

Use bump allocator for initial property storage
https://bugs.webkit.org/show_bug.cgi?id=67494

Reviewed by Gavin Barraclough.

Switch to a bump allocator for the initial out of line
property storage.  This gives us slightly faster allocation
for short lived objects that need out of line storage at
the cost of an additional memcpy when the object survives
a GC pass.

No performance impact.

* _javascript_Core.exp:
* heap/Heap.cpp:
(JSC::Heap::collect):
* heap/Heap.h:
(JSC::Heap::allocatePropertyStorage):
(JSC::Heap::inPropertyStorageNursary):
* heap/NewSpace.cpp:
(JSC::NewSpace::NewSpace):
* heap/NewSpace.h:
(JSC::NewSpace::resetPropertyStorageNursary):
(JSC::NewSpace::allocatePropertyStorage):
(JSC::NewSpace::inPropertyStorageNursary):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/JSObject.cpp:
(JSC::JSObject::allocatePropertyStorage):
* runtime/JSObject.h:
(JSC::JSObject::~JSObject):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::putDirectWithoutTransition):
(JSC::JSObject::putDirectFunctionWithoutTransition):
(JSC::JSObject::transitionTo):
(JSC::JSObject::visitChildrenDirect):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (94444 => 94445)


--- trunk/Source/_javascript_Core/ChangeLog	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-09-02 20:41:59 UTC (rev 94445)
@@ -1,3 +1,42 @@
+2011-09-02  Oliver Hunt  <[email protected]>
+
+        Use bump allocator for initial property storage
+        https://bugs.webkit.org/show_bug.cgi?id=67494
+
+        Reviewed by Gavin Barraclough.
+
+        Switch to a bump allocator for the initial out of line
+        property storage.  This gives us slightly faster allocation
+        for short lived objects that need out of line storage at
+        the cost of an additional memcpy when the object survives
+        a GC pass.
+
+        No performance impact.
+
+        * _javascript_Core.exp:
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * heap/Heap.h:
+        (JSC::Heap::allocatePropertyStorage):
+        (JSC::Heap::inPropertyStorageNursary):
+        * heap/NewSpace.cpp:
+        (JSC::NewSpace::NewSpace):
+        * heap/NewSpace.h:
+        (JSC::NewSpace::resetPropertyStorageNursary):
+        (JSC::NewSpace::allocatePropertyStorage):
+        (JSC::NewSpace::inPropertyStorageNursary):
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::allocatePropertyStorage):
+        * runtime/JSObject.h:
+        (JSC::JSObject::~JSObject):
+        (JSC::JSObject::putDirectInternal):
+        (JSC::JSObject::putDirectWithoutTransition):
+        (JSC::JSObject::putDirectFunctionWithoutTransition):
+        (JSC::JSObject::transitionTo):
+        (JSC::JSObject::visitChildrenDirect):
+
 2011-09-01  Mark Rowe  <[email protected]>
 
         Fix the build.

Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (94444 => 94445)


--- trunk/Source/_javascript_Core/_javascript_Core.exp	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp	2011-09-02 20:41:59 UTC (rev 94445)
@@ -216,6 +216,7 @@
 __ZN3JSC22globalMemoryStatisticsEv
 __ZN3JSC22objectConstructorTableE
 __ZN3JSC23AbstractSamplingCounter4dumpEv
+__ZN3JSC23AbstractSamplingCounter30s_abstractSamplingCounterChainE
 __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC24DynamicGlobalObjectScopeC1ERNS_12JSGlobalDataEPNS_14JSGlobalObjectE
@@ -322,7 +323,7 @@
 __ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_16WriteBarrierBaseINS_7UnknownEEE
-__ZN3JSC8JSObject23allocatePropertyStorageEmm
+__ZN3JSC8JSObject23allocatePropertyStorageERNS_12JSGlobalDataEmm
 __ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (94444 => 94445)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2011-09-02 20:41:59 UTC (rev 94445)
@@ -54,7 +54,7 @@
     ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
     ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
     ?allocate@Heap@JSC@@QAEPAXAAUSizeClass@NewSpace@2@@Z
-    ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
+    ?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
     ?allocateSlowCase@Heap@JSC@@AAEPAXAAUSizeClass@NewSpace@2@@Z
     ?append@StringBuilder@WTF@@QAEXPBDI@Z
     ?append@StringBuilder@WTF@@QAEXPB_WI@Z

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (94444 => 94445)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2011-09-02 20:41:59 UTC (rev 94445)
@@ -683,7 +683,7 @@
     // new bytes allocated) proportion, and seems to work well in benchmarks.
     size_t proportionalBytes = 2 * size();
     m_newSpace.setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
-
+    m_newSpace.resetPropertyStorageNursery();
     _javascript_CORE_GC_END();
 
     (*m_activityCallback)();

Modified: trunk/Source/_javascript_Core/heap/Heap.h (94444 => 94445)


--- trunk/Source/_javascript_Core/heap/Heap.h	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2011-09-02 20:41:59 UTC (rev 94445)
@@ -91,6 +91,9 @@
         void notifyIsSafeToCollect() { m_isSafeToCollect = true; }
         void collectAllGarbage();
 
+        inline void* allocatePropertyStorage(size_t);
+        inline bool inPropertyStorageNursery(void*);
+
         void reportExtraMemoryCost(size_t cost);
 
         void protect(JSValue);
@@ -358,6 +361,22 @@
         return allocate(sizeClass);
     }
 
+    inline void* Heap::allocatePropertyStorage(size_t bytes)
+    {
+        ASSERT(!(bytes % sizeof(JSValue)));
+        if (bytes >= NewSpace::PropertyStorageNurserySize)
+            return fastMalloc(bytes);
+        if (void* result = m_newSpace.allocatePropertyStorage(bytes))
+            return result;
+        collect(DoNotSweep);
+        return m_newSpace.allocatePropertyStorage(bytes);
+    }
+    
+    inline bool Heap::inPropertyStorageNursery(void* ptr)
+    {
+        return m_newSpace.inPropertyStorageNursery(ptr);
+    }
+
 } // namespace JSC
 
 #endif // Heap_h

Modified: trunk/Source/_javascript_Core/heap/NewSpace.cpp (94444 => 94445)


--- trunk/Source/_javascript_Core/heap/NewSpace.cpp	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/heap/NewSpace.cpp	2011-09-02 20:41:59 UTC (rev 94445)
@@ -32,7 +32,9 @@
 class Structure;
 
 NewSpace::NewSpace(Heap* heap)
-    : m_waterMark(0)
+    : m_propertyStorageNursery(static_cast<char*>(fastMalloc(PropertyStorageNurserySize)))
+    , m_propertyStorageAllocationPoint(m_propertyStorageNursery)
+    , m_waterMark(0)
     , m_highWaterMark(0)
     , m_heap(heap)
 {

Modified: trunk/Source/_javascript_Core/heap/NewSpace.h (94444 => 94445)


--- trunk/Source/_javascript_Core/heap/NewSpace.h	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/heap/NewSpace.h	2011-09-02 20:41:59 UTC (rev 94445)
@@ -46,6 +46,7 @@
         WTF_MAKE_NONCOPYABLE(NewSpace);
     public:
         static const size_t maxCellSize = 1024;
+        static const ptrdiff_t PropertyStorageNurserySize = 1024 * 1024 * 4;
 
         struct SizeClass {
             SizeClass();
@@ -63,6 +64,10 @@
 
         SizeClass& sizeClassFor(size_t);
         void* allocate(SizeClass&);
+        inline void* allocatePropertyStorage(size_t);
+        inline bool inPropertyStorageNursery(void* ptr);
+        inline void resetPropertyStorageNursery();
+        
         void resetAllocator();
 
         void addBlock(SizeClass&, MarkedBlock*);
@@ -91,6 +96,8 @@
 
         SizeClass m_preciseSizeClasses[preciseCount];
         SizeClass m_impreciseSizeClasses[impreciseCount];
+        char* m_propertyStorageNursery;
+        char* m_propertyStorageAllocationPoint;
         size_t m_waterMark;
         size_t m_highWaterMark;
         Heap* m_heap;
@@ -160,6 +167,30 @@
         return firstFreeCell;
     }
 
+    inline void NewSpace::resetPropertyStorageNursery()
+    {
+        m_propertyStorageAllocationPoint = m_propertyStorageNursery;
+    }
+    
+    inline void* NewSpace::allocatePropertyStorage(size_t size)
+    {
+        char* result = m_propertyStorageAllocationPoint;
+        if (size > static_cast<size_t>(PropertyStorageNurserySize))
+            CRASH();
+        m_propertyStorageAllocationPoint += size;
+        if ((m_propertyStorageAllocationPoint - m_propertyStorageNursery) > PropertyStorageNurserySize) {
+            m_propertyStorageAllocationPoint = result;
+            return 0;
+        }
+        return result;
+    }
+
+    inline bool NewSpace::inPropertyStorageNursery(void* ptr)
+    {
+        char* addr = static_cast<char*>(ptr);
+        return static_cast<uintptr_t>(addr - m_propertyStorageNursery) < PropertyStorageNurserySize;
+    }
+    
     template <typename Functor> inline typename Functor::ReturnType NewSpace::forEachBlock(Functor& functor)
     {
         for (size_t i = 0; i < preciseCount; ++i) {

Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (94444 => 94445)


--- trunk/Source/_javascript_Core/jit/JITStubs.cpp	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp	2011-09-02 20:41:59 UTC (rev 94445)
@@ -1481,7 +1481,7 @@
 
     ASSERT(baseValue.isObject());
     JSObject* base = asObject(baseValue);
-    base->allocatePropertyStorage(oldSize, newSize);
+    base->allocatePropertyStorage(*stackFrame.globalData, oldSize, newSize);
 
     return base;
 }

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (94444 => 94445)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2011-09-02 20:41:59 UTC (rev 94445)
@@ -594,21 +594,20 @@
     return m_inheritorID.get();
 }
 
-void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
+void JSObject::allocatePropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
 {
     ASSERT(newSize > oldSize);
 
     // It's important that this function not rely on m_structure, since
     // we might be in the middle of a transition.
-    bool wasInline = (oldSize < JSObject::baseExternalStorageCapacity);
-
     PropertyStorage oldPropertyStorage = m_propertyStorage;
-    PropertyStorage newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
+    PropertyStorage newPropertyStorage = static_cast<PropertyStorage>(globalData.heap.allocatePropertyStorage(newSize * sizeof(WriteBarrierBase<Unknown>)));
+    ASSERT(newPropertyStorage);
 
     for (unsigned i = 0; i < oldSize; ++i)
        newPropertyStorage[i] = oldPropertyStorage[i];
 
-    if (!wasInline)
+    if (!isUsingInlineStorage() && !globalData.heap.inPropertyStorageNursery(oldPropertyStorage))
         delete [] oldPropertyStorage;
 
     m_propertyStorage = newPropertyStorage;

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (94444 => 94445)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2011-09-02 20:33:34 UTC (rev 94444)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2011-09-02 20:41:59 UTC (rev 94445)
@@ -221,7 +221,7 @@
 
         virtual ComplType exceptionType() const { return Throw; }
 
-        void allocatePropertyStorage(size_t oldSize, size_t newSize);
+        void allocatePropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
         bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
 
         void* addressOfPropertyAtOffset(size_t offset)
@@ -463,7 +463,7 @@
 
 inline JSObject::~JSObject()
 {
-    if (!isUsingInlineStorage())
+    if (!isUsingInlineStorage() && !Heap::heap(this)->inPropertyStorageNursery(m_propertyStorage))
         delete [] m_propertyStorage;
 }
 
@@ -657,7 +657,7 @@
         size_t currentCapacity = m_structure->propertyStorageCapacity();
         offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
         if (currentCapacity != m_structure->propertyStorageCapacity())
-            allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+            allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
 
         ASSERT(offset < m_structure->propertyStorageCapacity());
         putDirectOffset(globalData, offset, value);
@@ -671,7 +671,7 @@
     size_t currentCapacity = m_structure->propertyStorageCapacity();
     if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(m_structure.get(), propertyName, attributes, specificFunction, offset)) {    
         if (currentCapacity != structure->propertyStorageCapacity())
-            allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
+            allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
 
         ASSERT(offset < structure->propertyStorageCapacity());
         setStructure(globalData, structure);
@@ -721,7 +721,7 @@
     Structure* structure = Structure::addPropertyTransition(globalData, m_structure.get(), propertyName, attributes, specificFunction, offset);
 
     if (currentCapacity != structure->propertyStorageCapacity())
-        allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
+        allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
 
     ASSERT(offset < structure->propertyStorageCapacity());
     setStructure(globalData, structure);
@@ -782,7 +782,7 @@
     size_t currentCapacity = m_structure->propertyStorageCapacity();
     size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, 0);
     if (currentCapacity != m_structure->propertyStorageCapacity())
-        allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+        allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
     putDirectOffset(globalData, offset, value);
 }
 
@@ -791,14 +791,14 @@
     size_t currentCapacity = m_structure->propertyStorageCapacity();
     size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, value);
     if (currentCapacity != m_structure->propertyStorageCapacity())
-        allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+        allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
     putDirectOffset(globalData, offset, value);
 }
 
 inline void JSObject::transitionTo(JSGlobalData& globalData, Structure* newStructure)
 {
     if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
-        allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
+        allocatePropertyStorage(globalData, m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
     setStructure(globalData, newStructure);
 }
 
@@ -889,6 +889,10 @@
     JSCell::visitChildren(visitor);
 
     PropertyStorage storage = propertyStorage();
+    if (Heap::heap(this)->inPropertyStorageNursery(storage)) {
+        m_propertyStorage = new WriteBarrierBase<Unknown>[structure()->propertyStorageCapacity()];
+        memcpy(m_propertyStorage, storage, m_structure->propertyStorageSize() * sizeof(WriteBarrierBase<Unknown>));
+    }
     size_t storageSize = m_structure->propertyStorageSize();
     visitor.appendValues(storage, storageSize);
     if (m_inheritorID)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to