Changeset 160919 in webkit


Ignore:
Timestamp:
Dec 20, 2013 12:19:59 PM (10 years ago)
Author:
mhahnenberg@apple.com
Message:

Clean up DFG write barriers
https://bugs.webkit.org/show_bug.cgi?id=126047

Reviewed by Filip Pizlo.

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::storeToWriteBarrierBuffer): Use the register allocator to
determine which registers need saving instead of saving every single one of them.
(JSC::DFG::SpeculativeJIT::osrWriteBarrier): We don't need to save live register state
because the write barriers during OSR execute when there are no live registers. Also we
don't need to use pushes to pad the stack pointer for pokes on x86; we can just use an add.
(JSC::DFG::SpeculativeJIT::writeBarrier):

  • dfg/DFGSpeculativeJIT.h:
  • jit/Repatch.cpp:

(JSC::emitPutReplaceStub):
(JSC::emitPutTransitionStub):

  • runtime/VM.h: Get rid of writeBarrierRegisterBuffer since it's no longer used.
Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r160913 r160919  
     12013-12-19  Mark Hahnenberg  <mhahnenberg@apple.com>
     2
     3        Clean up DFG write barriers
     4        https://bugs.webkit.org/show_bug.cgi?id=126047
     5
     6        Reviewed by Filip Pizlo.
     7
     8        * dfg/DFGSpeculativeJIT.cpp:
     9        (JSC::DFG::SpeculativeJIT::storeToWriteBarrierBuffer): Use the register allocator to
     10        determine which registers need saving instead of saving every single one of them.
     11        (JSC::DFG::SpeculativeJIT::osrWriteBarrier): We don't need to save live register state
     12        because the write barriers during OSR execute when there are no live registers. Also we 
     13        don't need to use pushes to pad the stack pointer for pokes on x86; we can just use an add.
     14        (JSC::DFG::SpeculativeJIT::writeBarrier):
     15        * dfg/DFGSpeculativeJIT.h:
     16        * jit/Repatch.cpp:
     17        (JSC::emitPutReplaceStub):
     18        (JSC::emitPutTransitionStub):
     19        * runtime/VM.h: Get rid of writeBarrierRegisterBuffer since it's no longer used.
     20
    1212013-12-20  Balazs Kilvady  <kilvadyb@homejinni.com>
    222
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r160796 r160919  
    3838#include "JSCJSValueInlines.h"
    3939#include "LinkBuffer.h"
     40#include "ScratchRegisterAllocator.h"
    4041#include "WriteBarrierBuffer.h"
    4142#include <wtf/MathExtras.h>
     
    54805481}
    54815482
    5482 MacroAssembler::Call SpeculativeJIT::storeToWriteBarrierBuffer(CCallHelpers& jit, GPRReg cell, GPRReg scratch1, GPRReg scratch2)
    5483 {
    5484     ASSERT(scratch1 != scratch2);
    5485     // Load WriteBarrierBuffer from Heap
    5486     WriteBarrierBuffer* writeBarrierBuffer = &jit.vm()->heap.m_writeBarrierBuffer;
    5487     jit.move(TrustedImmPtr(writeBarrierBuffer), scratch1);
    5488     // Load currentIndex
    5489     jit.load32(MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()), scratch2);
    5490     // Branch if currentIndex >= capacity
    5491     JITCompiler::Jump needToFlush = jit.branch32(MacroAssembler::AboveOrEqual, scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::capacityOffset()));
    5492 
    5493     // Store new currentIndex
    5494     jit.add32(TrustedImm32(1), scratch2);
    5495     jit.store32(scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()));
    5496 
    5497     // Load buffer
    5498     jit.loadPtr(MacroAssembler::Address(scratch1, WriteBarrierBuffer::bufferOffset()), scratch1);
    5499     // Store cell into buffer. We use an offset of -sizeof(void*) because we already added 1 to scratch2.
    5500     jit.storePtr(cell, MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::ScalePtr, static_cast<int32_t>(-sizeof(void*))));
    5501 
    5502     // Jump to done
    5503     JITCompiler::Jump done = jit.jump();
    5504     // Link from branch
    5505     needToFlush.link(&jit);
    5506 
    5507     // Call C slow path.
    5508     for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
    5509         jit.storePtr(GPRInfo::toRegister(i), &jit.vm()->writeBarrierRegisterBuffer[i]);
    5510 
    5511 #if CPU(X86)
    5512     jit.push(scratch1);
    5513     jit.push(scratch1);
    5514 #endif
    5515 
    5516     jit.setupArgumentsWithExecState(cell);
    5517     MacroAssembler::Call call = jit.call();
    5518 
    5519 #if CPU(X86)
    5520     jit.pop(scratch1);
    5521     jit.pop(scratch1);
    5522 #endif
    5523 
    5524     for (unsigned i = GPRInfo::numberOfRegisters; i--;)
    5525         jit.loadPtr(&jit.vm()->writeBarrierRegisterBuffer[i], GPRInfo::toRegister(i));
    5526 
    5527     // Link Done
    5528     done.link(&jit);
    5529 
    5530     return call;
    5531 }
    5532 
    55335483void SpeculativeJIT::storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2)
    55345484{
     
    55945544void SpeculativeJIT::osrWriteBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
    55955545{
    5596     UNUSED_PARAM(jit);
    5597     UNUSED_PARAM(owner);
    5598     UNUSED_PARAM(scratch1);
    5599     UNUSED_PARAM(scratch2);
    5600     ASSERT(owner != scratch1);
    5601     ASSERT(owner != scratch2);
    5602 
    56035546    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(jit, owner, scratch1, scratch2);
    5604 
    5605     for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
    5606         jit.storePtr(GPRInfo::toRegister(i), &jit.vm()->writeBarrierRegisterBuffer[i]);
    56075547
    56085548    // We need these extra slots because setupArgumentsWithExecState will use poke on x86.
    56095549#if CPU(X86)
    5610     jit.push(scratch1);
    5611     jit.push(scratch1);
    5612     jit.push(scratch1);
     5550    jit.subPtr(TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
    56135551#endif
    56145552
     
    56185556
    56195557#if CPU(X86)
    5620     jit.pop(scratch1);
    5621     jit.pop(scratch1);
    5622     jit.pop(scratch1);
     5558    jit.addPtr(TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
    56235559#endif
    5624     for (unsigned i = GPRInfo::numberOfRegisters; i--;)
    5625         jit.loadPtr(&jit.vm()->writeBarrierRegisterBuffer[i], GPRInfo::toRegister(i));
    56265560
    56275561    definitelyNotMarked.link(&jit);
    5628 }
    5629 
    5630 MacroAssembler::Call SpeculativeJIT::writeBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
    5631 {
    5632     ASSERT(owner != scratch1);
    5633     ASSERT(owner != scratch2);
    5634 
    5635     JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(jit, owner, scratch1, scratch2);
    5636     MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2);
    5637     definitelyNotMarked.link(&jit);
    5638     return call;
    56395562}
    56405563
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r160796 r160919  
    291291
    292292#if ENABLE(GGC)
    293     static MacroAssembler::Call storeToWriteBarrierBuffer(CCallHelpers& jit, GPRReg cell, GPRReg scratch1, GPRReg scratch2);
    294293    void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
    295294    void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2);
     
    298297    static JITCompiler::Jump genericWriteBarrier(CCallHelpers& jit, JSCell* owner);
    299298    static void osrWriteBarrier(CCallHelpers&, GPRReg owner, GPRReg scratch1, GPRReg scratch2);
    300     static MacroAssembler::Call writeBarrier(CCallHelpers&, GPRReg owner, GPRReg scratch1, GPRReg scratch2);
    301299    void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
    302300    void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2);
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r160796 r160919  
    101101        static uint8_t* addressOfCardFor(JSCell*);
    102102
     103#if ENABLE(GGC)
     104        WriteBarrierBuffer& writeBarrierBuffer() { return m_writeBarrierBuffer; }
     105#endif
    103106        void flushWriteBarrierBuffer(JSCell*);
    104107
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r160878 r160919  
    774774}
    775775
     776#if ENABLE(GGC)
     777static MacroAssembler::Call storeToWriteBarrierBuffer(CCallHelpers& jit, GPRReg cell, GPRReg scratch1, GPRReg scratch2, ScratchRegisterAllocator& allocator)
     778{
     779    ASSERT(scratch1 != scratch2);
     780    WriteBarrierBuffer* writeBarrierBuffer = &jit.vm()->heap.writeBarrierBuffer();
     781    jit.move(MacroAssembler::TrustedImmPtr(writeBarrierBuffer), scratch1);
     782    jit.load32(MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()), scratch2);
     783    MacroAssembler::Jump needToFlush = jit.branch32(MacroAssembler::AboveOrEqual, scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::capacityOffset()));
     784
     785    jit.add32(MacroAssembler::TrustedImm32(1), scratch2);
     786    jit.store32(scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()));
     787
     788    jit.loadPtr(MacroAssembler::Address(scratch1, WriteBarrierBuffer::bufferOffset()), scratch1);
     789    // We use an offset of -sizeof(void*) because we already added 1 to scratch2.
     790    jit.storePtr(cell, MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::ScalePtr, static_cast<int32_t>(-sizeof(void*))));
     791
     792    MacroAssembler::Jump done = jit.jump();
     793    needToFlush.link(&jit);
     794
     795    ScratchBuffer* scratchBuffer = jit.vm()->scratchBufferForSize(allocator.desiredScratchBufferSize());
     796    allocator.preserveUsedRegistersToScratchBuffer(jit, scratchBuffer, scratch1);
     797
     798    // We need these extra slots because setupArgumentsWithExecState will use poke on x86.
     799#if CPU(X86)
     800    jit.subPtr(MacroAssembler::TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
     801#endif
     802
     803    jit.setupArgumentsWithExecState(cell);
     804    MacroAssembler::Call call = jit.call();
     805
     806#if CPU(X86)
     807    jit.addPtr(MacroAssembler::TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
     808#endif
     809    allocator.restoreUsedRegistersFromScratchBuffer(jit, scratchBuffer, scratch1);
     810
     811    done.link(&jit);
     812
     813    return call;
     814}
     815
     816static MacroAssembler::Call writeBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, ScratchRegisterAllocator& allocator)
     817{
     818    ASSERT(owner != scratch1);
     819    ASSERT(owner != scratch2);
     820
     821    MacroAssembler::Jump definitelyNotMarked = DFG::SpeculativeJIT::genericWriteBarrier(jit, owner, scratch1, scratch2);
     822    MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2, allocator);
     823    definitelyNotMarked.link(&jit);
     824    return call;
     825}
     826#endif // ENABLE(GGC)
     827
    776828static void emitPutReplaceStub(
    777829    ExecState* exec,
     
    832884   
    833885#if ENABLE(GGC)
    834     MacroAssembler::Call writeBarrierOperation = DFG::SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR1, scratchGPR2);
     886    MacroAssembler::Call writeBarrierOperation = writeBarrier(stubJit, baseGPR, scratchGPR1, scratchGPR2, allocator);
    835887#endif
    836888   
     
    9991051   
    10001052#if ENABLE(GGC)
    1001     MacroAssembler::Call writeBarrierOperation = DFG::SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR1, scratchGPR2);
     1053    MacroAssembler::Call writeBarrierOperation = writeBarrier(stubJit, baseGPR, scratchGPR1, scratchGPR2, allocator);
    10021054#endif
    10031055   
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r160869 r160919  
    389389        const ClassInfo* const jsFinalObjectClassInfo;
    390390
    391 #if ENABLE(JIT)
    392         void* writeBarrierRegisterBuffer[GPRInfo::numberOfRegisters];
    393 #endif
    394 
    395391        ReturnAddressPtr exceptionLocation;
    396392        JSValue hostCallReturnValue;
Note: See TracChangeset for help on using the changeset viewer.