Ignore:
Timestamp:
Jan 2, 2014, 4:24:14 PM (11 years ago)
Author:
[email protected]
Message:

Add support for StoreBarrier and friends to the FTL
https://bugs.webkit.org/show_bug.cgi?id=126040

Reviewed by Filip Pizlo.

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileStoreBarrier):
(JSC::FTL::LowerDFGToLLVM::compileConditionalStoreBarrier):
(JSC::FTL::LowerDFGToLLVM::compileStoreBarrierWithNullCheck):
(JSC::FTL::LowerDFGToLLVM::loadMarkByte):
(JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):

  • heap/Heap.cpp:

(JSC::Heap::Heap):

  • heap/Heap.h:

(JSC::Heap::writeBarrierBuffer):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r161218 r161240  
    467467            compileInt52ToValue();
    468468            break;
     469        case StoreBarrier:
     470            compileStoreBarrier();
     471            break;
     472        case ConditionalStoreBarrier:
     473            compileConditionalStoreBarrier();
     474            break;
     475        case StoreBarrierWithNullCheck:
     476            compileStoreBarrierWithNullCheck();
     477            break;
    469478        case Flush:
    470479        case PhantomLocal:
     
    583592    {
    584593        setJSValue(lowJSValue(m_node->child1()));
     594    }
     595
     596    void compileStoreBarrier()
     597    {
     598        emitStoreBarrier(lowCell(m_node->child1()));
     599    }
     600
     601    void compileConditionalStoreBarrier()
     602    {
     603        LValue base = lowCell(m_node->child1());
     604        LValue value = lowJSValue(m_node->child2());
     605        emitStoreBarrier(base, value, m_node->child2());
     606    }
     607
     608    void compileStoreBarrierWithNullCheck()
     609    {
     610#if ENABLE(GGC)
     611        LBasicBlock isNotNull = FTL_NEW_BLOCK(m_out, ("Store barrier with null check value not null"));
     612        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
     613
     614        LValue base = lowJSValue(m_node->child1());
     615        m_out.branch(m_out.isZero64(base), continuation, isNotNull);
     616        LBasicBlock lastNext = m_out.appendTo(isNotNull, continuation);
     617        emitStoreBarrier(base);
     618        m_out.appendTo(continuation, lastNext);
     619#else
     620        speculate(m_node->child1());
     621#endif
    585622    }
    586623
     
    39483985    }
    39493986   
     3987    LValue loadMarkByte(LValue base)
     3988    {
     3989        LValue markedBlock = m_out.bitAnd(base, m_out.constInt64(MarkedBlock::blockMask));
     3990        LValue baseOffset = m_out.bitAnd(base, m_out.constInt64(~MarkedBlock::blockMask));
     3991        LValue markByteIndex = m_out.lShr(baseOffset, m_out.constInt64(MarkedBlock::atomShiftAmount + MarkedBlock::markByteShiftAmount));
     3992        return m_out.load8(m_out.baseIndex(m_heaps.MarkedBlock_markBits, markedBlock, markByteIndex, ScaleOne, MarkedBlock::offsetOfMarks()));
     3993    }
     3994
     3995    void emitStoreBarrier(LValue base, LValue value, Edge& valueEdge)
     3996    {
     3997#if ENABLE(GGC)
     3998        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
     3999        LBasicBlock isCell = FTL_NEW_BLOCK(m_out, ("Store barrier is cell block"));
     4000
     4001        if (m_state.forNode(valueEdge.node()).couldBeType(SpecCell))
     4002            m_out.branch(isNotCell(value), continuation, isCell);
     4003        else
     4004            m_out.jump(isCell);
     4005
     4006        LBasicBlock lastNext = m_out.appendTo(isCell, continuation);
     4007        emitStoreBarrier(base);
     4008        m_out.jump(continuation);
     4009
     4010        m_out.appendTo(continuation, lastNext);
     4011#else
     4012        UNUSED_PARAM(base);
     4013        UNUSED_PARAM(value);
     4014        UNUSED_PARAM(valueEdge);
     4015#endif
     4016    }
     4017
     4018    void emitStoreBarrier(LValue base)
     4019    {
     4020#if ENABLE(GGC)
     4021        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
     4022        LBasicBlock isMarked = FTL_NEW_BLOCK(m_out, ("Store barrier is marked block"));
     4023        LBasicBlock bufferHasSpace = FTL_NEW_BLOCK(m_out, ("Store barrier buffer is full"));
     4024        LBasicBlock bufferIsFull = FTL_NEW_BLOCK(m_out, ("Store barrier buffer is full"));
     4025
     4026        // Check the mark byte.
     4027        m_out.branch(m_out.isZero8(loadMarkByte(base)), continuation, isMarked);
     4028
     4029        // Append to the write barrier buffer.
     4030        LBasicBlock lastNext = m_out.appendTo(isMarked, bufferHasSpace);
     4031        LValue currentBufferIndex = m_out.load32(m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
     4032        LValue bufferCapacity = m_out.load32(m_out.absolute(&vm().heap.writeBarrierBuffer().m_capacity));
     4033        m_out.branch(m_out.lessThan(currentBufferIndex, bufferCapacity), bufferHasSpace, bufferIsFull);
     4034
     4035        // Buffer has space, store to it.
     4036        m_out.appendTo(bufferHasSpace, bufferIsFull);
     4037        LValue writeBarrierBufferBase = m_out.loadPtr(m_out.absolute(&vm().heap.writeBarrierBuffer().m_buffer));
     4038        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExt(currentBufferIndex, m_out.intPtr), ScalePtr));
     4039        m_out.store32(m_out.add(currentBufferIndex, m_out.constInt32(1)), m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
     4040        m_out.jump(continuation);
     4041
     4042        // Buffer is out of space, flush it.
     4043        m_out.appendTo(bufferIsFull, continuation);
     4044        vmCall(m_out.operation(operationFlushWriteBarrierBuffer), m_callFrame, base);
     4045        m_out.jump(continuation);
     4046
     4047        m_out.appendTo(continuation, lastNext);
     4048#else
     4049        UNUSED_PARAM(base);
     4050#endif
     4051    }
     4052
    39504053    enum ExceptionCheckMode { NoExceptions, CheckExceptions };
    39514054   
Note: See TracChangeset for help on using the changeset viewer.