Changeset 94445 in webkit


Ignore:
Timestamp:
Sep 2, 2011 1:41:59 PM (13 years ago)
Author:
oliver@apple.com
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.

(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):

Location:
trunk/Source/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r94376 r94445  
     12011-09-02  Oliver Hunt  <oliver@apple.com>
     2
     3        Use bump allocator for initial property storage
     4        https://bugs.webkit.org/show_bug.cgi?id=67494
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        Switch to a bump allocator for the initial out of line
     9        property storage.  This gives us slightly faster allocation
     10        for short lived objects that need out of line storage at
     11        the cost of an additional memcpy when the object survives
     12        a GC pass.
     13
     14        No performance impact.
     15
     16        * JavaScriptCore.exp:
     17        * heap/Heap.cpp:
     18        (JSC::Heap::collect):
     19        * heap/Heap.h:
     20        (JSC::Heap::allocatePropertyStorage):
     21        (JSC::Heap::inPropertyStorageNursary):
     22        * heap/NewSpace.cpp:
     23        (JSC::NewSpace::NewSpace):
     24        * heap/NewSpace.h:
     25        (JSC::NewSpace::resetPropertyStorageNursary):
     26        (JSC::NewSpace::allocatePropertyStorage):
     27        (JSC::NewSpace::inPropertyStorageNursary):
     28        * jit/JITStubs.cpp:
     29        (JSC::DEFINE_STUB_FUNCTION):
     30        * runtime/JSObject.cpp:
     31        (JSC::JSObject::allocatePropertyStorage):
     32        * runtime/JSObject.h:
     33        (JSC::JSObject::~JSObject):
     34        (JSC::JSObject::putDirectInternal):
     35        (JSC::JSObject::putDirectWithoutTransition):
     36        (JSC::JSObject::putDirectFunctionWithoutTransition):
     37        (JSC::JSObject::transitionTo):
     38        (JSC::JSObject::visitChildrenDirect):
     39
    1402011-09-01  Mark Rowe  <mrowe@apple.com>
    241
  • trunk/Source/JavaScriptCore/JavaScriptCore.exp

    r94376 r94445  
    217217__ZN3JSC22objectConstructorTableE
    218218__ZN3JSC23AbstractSamplingCounter4dumpEv
     219__ZN3JSC23AbstractSamplingCounter30s_abstractSamplingCounterChainE
    219220__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
    220221__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
     
    323324__ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
    324325__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_16WriteBarrierBaseINS_7UnknownEEE
    325 __ZN3JSC8JSObject23allocatePropertyStorageEmm
     326__ZN3JSC8JSObject23allocatePropertyStorageERNS_12JSGlobalDataEmm
    326327__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
    327328__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r94364 r94445  
    5555    ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
    5656    ?allocate@Heap@JSC@@QAEPAXAAUSizeClass@NewSpace@2@@Z
    57     ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
     57    ?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
    5858    ?allocateSlowCase@Heap@JSC@@AAEPAXAAUSizeClass@NewSpace@2@@Z
    5959    ?append@StringBuilder@WTF@@QAEXPBDI@Z
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r93918 r94445  
    684684    size_t proportionalBytes = 2 * size();
    685685    m_newSpace.setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
    686 
     686    m_newSpace.resetPropertyStorageNursery();
    687687    JAVASCRIPTCORE_GC_END();
    688688
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r93918 r94445  
    9292        void collectAllGarbage();
    9393
     94        inline void* allocatePropertyStorage(size_t);
     95        inline bool inPropertyStorageNursery(void*);
     96
    9497        void reportExtraMemoryCost(size_t cost);
    9598
     
    359362    }
    360363
     364    inline void* Heap::allocatePropertyStorage(size_t bytes)
     365    {
     366        ASSERT(!(bytes % sizeof(JSValue)));
     367        if (bytes >= NewSpace::PropertyStorageNurserySize)
     368            return fastMalloc(bytes);
     369        if (void* result = m_newSpace.allocatePropertyStorage(bytes))
     370            return result;
     371        collect(DoNotSweep);
     372        return m_newSpace.allocatePropertyStorage(bytes);
     373    }
     374   
     375    inline bool Heap::inPropertyStorageNursery(void* ptr)
     376    {
     377        return m_newSpace.inPropertyStorageNursery(ptr);
     378    }
     379
    361380} // namespace JSC
    362381
  • trunk/Source/JavaScriptCore/heap/NewSpace.cpp

    r92251 r94445  
    3333
    3434NewSpace::NewSpace(Heap* heap)
    35     : m_waterMark(0)
     35    : m_propertyStorageNursery(static_cast<char*>(fastMalloc(PropertyStorageNurserySize)))
     36    , m_propertyStorageAllocationPoint(m_propertyStorageNursery)
     37    , m_waterMark(0)
    3638    , m_highWaterMark(0)
    3739    , m_heap(heap)
  • trunk/Source/JavaScriptCore/heap/NewSpace.h

    r92146 r94445  
    4747    public:
    4848        static const size_t maxCellSize = 1024;
     49        static const ptrdiff_t PropertyStorageNurserySize = 1024 * 1024 * 4;
    4950
    5051        struct SizeClass {
     
    6465        SizeClass& sizeClassFor(size_t);
    6566        void* allocate(SizeClass&);
     67        inline void* allocatePropertyStorage(size_t);
     68        inline bool inPropertyStorageNursery(void* ptr);
     69        inline void resetPropertyStorageNursery();
     70       
    6671        void resetAllocator();
    6772
     
    9297        SizeClass m_preciseSizeClasses[preciseCount];
    9398        SizeClass m_impreciseSizeClasses[impreciseCount];
     99        char* m_propertyStorageNursery;
     100        char* m_propertyStorageAllocationPoint;
    94101        size_t m_waterMark;
    95102        size_t m_highWaterMark;
     
    161168    }
    162169
     170    inline void NewSpace::resetPropertyStorageNursery()
     171    {
     172        m_propertyStorageAllocationPoint = m_propertyStorageNursery;
     173    }
     174   
     175    inline void* NewSpace::allocatePropertyStorage(size_t size)
     176    {
     177        char* result = m_propertyStorageAllocationPoint;
     178        if (size > static_cast<size_t>(PropertyStorageNurserySize))
     179            CRASH();
     180        m_propertyStorageAllocationPoint += size;
     181        if ((m_propertyStorageAllocationPoint - m_propertyStorageNursery) > PropertyStorageNurserySize) {
     182            m_propertyStorageAllocationPoint = result;
     183            return 0;
     184        }
     185        return result;
     186    }
     187
     188    inline bool NewSpace::inPropertyStorageNursery(void* ptr)
     189    {
     190        char* addr = static_cast<char*>(ptr);
     191        return static_cast<uintptr_t>(addr - m_propertyStorageNursery) < PropertyStorageNurserySize;
     192    }
     193   
    163194    template <typename Functor> inline typename Functor::ReturnType NewSpace::forEachBlock(Functor& functor)
    164195    {
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r94336 r94445  
    14821482    ASSERT(baseValue.isObject());
    14831483    JSObject* base = asObject(baseValue);
    1484     base->allocatePropertyStorage(oldSize, newSize);
     1484    base->allocatePropertyStorage(*stackFrame.globalData, oldSize, newSize);
    14851485
    14861486    return base;
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r92618 r94445  
    595595}
    596596
    597 void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
     597void JSObject::allocatePropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
    598598{
    599599    ASSERT(newSize > oldSize);
     
    601601    // It's important that this function not rely on m_structure, since
    602602    // we might be in the middle of a transition.
    603     bool wasInline = (oldSize < JSObject::baseExternalStorageCapacity);
    604 
    605603    PropertyStorage oldPropertyStorage = m_propertyStorage;
    606     PropertyStorage newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
     604    PropertyStorage newPropertyStorage = static_cast<PropertyStorage>(globalData.heap.allocatePropertyStorage(newSize * sizeof(WriteBarrierBase<Unknown>)));
     605    ASSERT(newPropertyStorage);
    607606
    608607    for (unsigned i = 0; i < oldSize; ++i)
    609608       newPropertyStorage[i] = oldPropertyStorage[i];
    610609
    611     if (!wasInline)
     610    if (!isUsingInlineStorage() && !globalData.heap.inPropertyStorageNursery(oldPropertyStorage))
    612611        delete [] oldPropertyStorage;
    613612
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r94035 r94445  
    222222        virtual ComplType exceptionType() const { return Throw; }
    223223
    224         void allocatePropertyStorage(size_t oldSize, size_t newSize);
     224        void allocatePropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
    225225        bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
    226226
     
    464464inline JSObject::~JSObject()
    465465{
    466     if (!isUsingInlineStorage())
     466    if (!isUsingInlineStorage() && !Heap::heap(this)->inPropertyStorageNursery(m_propertyStorage))
    467467        delete [] m_propertyStorage;
    468468}
     
    658658        offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
    659659        if (currentCapacity != m_structure->propertyStorageCapacity())
    660             allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
     660            allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
    661661
    662662        ASSERT(offset < m_structure->propertyStorageCapacity());
     
    672672    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(m_structure.get(), propertyName, attributes, specificFunction, offset)) {   
    673673        if (currentCapacity != structure->propertyStorageCapacity())
    674             allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
     674            allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
    675675
    676676        ASSERT(offset < structure->propertyStorageCapacity());
     
    722722
    723723    if (currentCapacity != structure->propertyStorageCapacity())
    724         allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
     724        allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
    725725
    726726    ASSERT(offset < structure->propertyStorageCapacity());
     
    783783    size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, 0);
    784784    if (currentCapacity != m_structure->propertyStorageCapacity())
    785         allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
     785        allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
    786786    putDirectOffset(globalData, offset, value);
    787787}
     
    792792    size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, value);
    793793    if (currentCapacity != m_structure->propertyStorageCapacity())
    794         allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
     794        allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
    795795    putDirectOffset(globalData, offset, value);
    796796}
     
    799799{
    800800    if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
    801         allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
     801        allocatePropertyStorage(globalData, m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
    802802    setStructure(globalData, newStructure);
    803803}
     
    890890
    891891    PropertyStorage storage = propertyStorage();
     892    if (Heap::heap(this)->inPropertyStorageNursery(storage)) {
     893        m_propertyStorage = new WriteBarrierBase<Unknown>[structure()->propertyStorageCapacity()];
     894        memcpy(m_propertyStorage, storage, m_structure->propertyStorageSize() * sizeof(WriteBarrierBase<Unknown>));
     895    }
    892896    size_t storageSize = m_structure->propertyStorageSize();
    893897    visitor.appendValues(storage, storageSize);
Note: See TracChangeset for help on using the changeset viewer.