Changeset 37653 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Oct 17, 2008, 4:55:09 AM (17 years ago)
Author:
[email protected]
Message:

2008-10-17 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.


  • speed up transitions that resize the property storage a fair bit


~3% speedup on v8 RayTrace benchmark, ~1% on DeltaBlue

  • VM/CTI.cpp: (JSC::resizePropertyStorage): renamed from transitionObject, and reduced to just resize the object's property storage with one inline call. (JSC::CTI::privateCompilePutByIdTransition): Use a separate function for property storage resize, but still do all the rest of the work in assembly in that case, and pass the known compile-time constants of old and new size rather than structureIDs, saving a bunch of redundant memory access.
  • kjs/JSObject.cpp: (JSC::JSObject::allocatePropertyStorage): Just call the inline version.
  • kjs/JSObject.h: (JSC::JSObject::allocatePropertyStorageInline): Inline version of allocatePropertyStorage
  • masm/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::pushl_i32): Add code to assmeble push of a constant; code originally by Cameron Zwarich.
Location:
trunk/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r37652 r37653  
     12008-10-17  Maciej Stachowiak  <[email protected]>
     2
     3        Reviewed by Cameron Zwarich.
     4       
     5        - speed up transitions that resize the property storage a fair bit
     6       
     7        ~3% speedup on v8 RayTrace benchmark, ~1% on DeltaBlue
     8
     9        * VM/CTI.cpp:
     10        (JSC::resizePropertyStorage): renamed from transitionObject, and reduced to just resize
     11        the object's property storage with one inline call.
     12        (JSC::CTI::privateCompilePutByIdTransition): Use a separate function for property storage
     13        resize, but still do all the rest of the work in assembly in that case, and pass the known
     14        compile-time constants of old and new size rather than structureIDs, saving a bunch of
     15        redundant memory access.
     16        * kjs/JSObject.cpp:
     17        (JSC::JSObject::allocatePropertyStorage): Just call the inline version.
     18        * kjs/JSObject.h:
     19        (JSC::JSObject::allocatePropertyStorageInline): Inline version of allocatePropertyStorage
     20        * masm/X86Assembler.h:
     21        (JSC::X86Assembler::):
     22        (JSC::X86Assembler::pushl_i32): Add code to assmeble push of a constant; code originally by Cameron Zwarich.
     23
    1242008-10-17  Cameron Zwarich  <[email protected]>
    225
  • trunk/JavaScriptCore/VM/CTI.cpp

    r37651 r37653  
    28762876extern "C" {
    28772877
    2878 static JSValue* transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value)
    2879 {
    2880     baseObject->transitionTo(newStructureID);
    2881     baseObject->putDirectOffset(cachedOffset, value);
    2882     return baseObject;
    2883 }
     2878    static JSValue* resizePropertyStorage(JSObject* baseObject, size_t oldSize, size_t newSize)
     2879    {
     2880        baseObject->allocatePropertyStorageInline(oldSize, newSize);
     2881        return baseObject;
     2882    }
    28842883
    28852884}
     
    29282927
    29292928    X86Assembler::JmpSrc callTarget;
    2930     // Fast case, don't need to do any heavy lifting, so don't bother making a call.
    2931     if (!transitionWillNeedStorageRealloc(oldStructureID, newStructureID)) {
    2932         // Assumes m_refCount can be decremented easily, refcount decrement is safe as
    2933         // codeblock should ensure oldStructureID->m_refCount > 0
    2934         m_jit.subl_i8m(1, reinterpret_cast<void*>(oldStructureID));
    2935         m_jit.addl_i8m(1, reinterpret_cast<void*>(newStructureID));
    2936         m_jit.movl_i32m(reinterpret_cast<uint32_t>(newStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
    2937 
    2938         // write the value
    2939         m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
    2940         m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
    2941     } else {
    2942         // Slow case transition -- we're going to need to quite a bit of work,
    2943         // so just make a call
     2929
     2930    // emit a call only if storage realloc is needed
     2931    if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID)) {
    29442932        m_jit.pushl_r(X86::edx);
    2945         m_jit.pushl_r(X86::eax);
    2946         m_jit.movl_i32r(cachedOffset, X86::eax);
    2947         m_jit.pushl_r(X86::eax);
    2948         m_jit.movl_i32r(reinterpret_cast<uint32_t>(newStructureID), X86::eax);
     2933        m_jit.pushl_i32(newStructureID->propertyStorageCapacity());
     2934        m_jit.pushl_i32(oldStructureID->propertyStorageCapacity());
    29492935        m_jit.pushl_r(X86::eax);
    29502936        callTarget = m_jit.emitCall();
    2951         m_jit.addl_i32r(4 * sizeof(void*), X86::esp);
     2937        m_jit.addl_i32r(3 * sizeof(void*), X86::esp);
     2938        m_jit.popl_r(X86::edx);
    29522939    }
     2940
     2941    // Assumes m_refCount can be decremented easily, refcount decrement is safe as
     2942    // codeblock should ensure oldStructureID->m_refCount > 0
     2943    m_jit.subl_i8m(1, reinterpret_cast<void*>(oldStructureID));
     2944    m_jit.addl_i8m(1, reinterpret_cast<void*>(newStructureID));
     2945    m_jit.movl_i32m(reinterpret_cast<uint32_t>(newStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
     2946
     2947    // write the value
     2948    m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
     2949    m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
     2950
    29532951    m_jit.ret();
    29542952   
     
    29682966
    29692967    if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID))
    2970         X86Assembler::link(code, callTarget, reinterpret_cast<void*>(transitionObject));
     2968        X86Assembler::link(code, callTarget, reinterpret_cast<void*>(resizePropertyStorage));
    29712969   
    29722970    m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
  • trunk/JavaScriptCore/kjs/JSObject.cpp

    r37645 r37653  
    512512void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
    513513{
    514     ASSERT(newSize > oldSize);
    515 
    516     JSValue** oldPropertStorage = m_propertyStorage;
    517     m_propertyStorage = new JSValue*[newSize];
    518 
    519     for (unsigned i = 0; i < oldSize; ++i)
    520         m_propertyStorage[i] = oldPropertStorage[i];
    521 
    522     if (oldPropertStorage != m_inlineStorage)
    523         delete [] oldPropertStorage;
     514    allocatePropertyStorageInline(oldSize, newSize);
    524515}
    525516
  • trunk/JavaScriptCore/kjs/JSObject.h

    r37645 r37653  
    178178
    179179        void allocatePropertyStorage(size_t oldSize, size_t newSize);
     180        void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
    180181        bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
    181182
     
    507508}
    508509
     510ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_t newSize)
     511{
     512    ASSERT(newSize > oldSize);
     513
     514    JSValue** oldPropertStorage = m_propertyStorage;
     515    m_propertyStorage = new JSValue*[newSize];
     516
     517    for (unsigned i = 0; i < oldSize; ++i)
     518        m_propertyStorage[i] = oldPropertStorage[i];
     519
     520    if (oldPropertStorage != m_inlineStorage)
     521        delete [] oldPropertStorage;
     522}
     523
    509524} // namespace JSC
    510525
  • trunk/JavaScriptCore/masm/X86Assembler.h

    r37652 r37653  
    197197        PRE_OPERAND_SIZE                = 0x66,
    198198        PRE_SSE_66                      = 0x66,
     199        OP_PUSH_Iz                      = 0x68,
    199200        OP_IMUL_GvEvIz                  = 0x69,
    200201        OP_GROUP1_EvIz                  = 0x81,
     
    293294        emitModRm_opm(GROUP5_OP_PUSH, base, offset);
    294295    }
     296
     297    void pushl_i32(int imm)
     298    {
     299        m_buffer->putByte(OP_PUSH_Iz);
     300        m_buffer->putInt(imm);
     301    }
    295302   
    296303    void popl_r(RegisterID reg)
Note: See TracChangeset for help on using the changeset viewer.