- Source/JavaScriptCore/ChangeLog +24 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
2
3
        Fix write barriers in Repatch.cpp for !ENABLE(DFG_JIT) platforms after r165128
4
        https://bugs.webkit.org/show_bug.cgi?id=129760
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        r165128 disabled the write barrier fast path for inline caches on !ENABLE(DFG_JIT) platforms. 
9
        The fix is to refactor the write barrier code into AssemblyHelpers and use that everywhere.
10
11
        * dfg/DFGSpeculativeJIT.cpp:
12
        (JSC::DFG::SpeculativeJIT::writeBarrier):
13
        * dfg/DFGSpeculativeJIT.h:
14
        * dfg/DFGSpeculativeJIT32_64.cpp:
15
        (JSC::DFG::SpeculativeJIT::writeBarrier):
16
        * dfg/DFGSpeculativeJIT64.cpp:
17
        (JSC::DFG::SpeculativeJIT::writeBarrier):
18
        * jit/AssemblyHelpers.h:
19
        (JSC::AssemblyHelpers::checkMarkByte):
20
        * jit/JIT.h:
21
        * jit/JITPropertyAccess.cpp:
22
        * jit/Repatch.cpp:
23
        (JSC::writeBarrier):
24
1
2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
25
2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
2
26
3
        Web Inspector: Prevent possible deadlock in view indication
27
        Web Inspector: Prevent possible deadlock in view indication
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp -2 / +2 lines
Lines 4726-4732 void SpeculativeJIT::writeBarrier(GPRReg Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec1
4726
    if (!isKnownCell(valueUse.node()))
4726
    if (!isKnownCell(valueUse.node()))
4727
        isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
4727
        isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
4728
4728
4729
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
4729
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
4730
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
4730
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
4731
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
4731
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
4732
4732
Lines 4740-4746 void SpeculativeJIT::writeBarrier(JSCell Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec2
4740
    if (!isKnownCell(valueUse.node()))
4740
    if (!isKnownCell(valueUse.node()))
4741
        isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
4741
        isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
4742
4742
4743
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, owner);
4743
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(owner);
4744
    storeToWriteBarrierBuffer(owner, scratch1, scratch2);
4744
    storeToWriteBarrierBuffer(owner, scratch1, scratch2);
4745
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
4745
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
4746
4746
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp -2 / +2 lines
Lines 5060-5066 void SpeculativeJIT::writeBarrier(GPRReg Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec1
5060
    if (!isKnownCell(valueUse.node()))
5060
    if (!isKnownCell(valueUse.node()))
5061
        isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
5061
        isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
5062
5062
5063
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
5063
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
5064
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
5064
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
5065
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5065
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5066
5066
Lines 5074-5080 void SpeculativeJIT::writeBarrier(JSCell Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec2
5074
    if (!isKnownCell(valueUse.node()))
5074
    if (!isKnownCell(valueUse.node()))
5075
        isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
5075
        isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
5076
5076
5077
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, owner);
5077
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(owner);
5078
    storeToWriteBarrierBuffer(owner, scratch1, scratch2);
5078
    storeToWriteBarrierBuffer(owner, scratch1, scratch2);
5079
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5079
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5080
5080
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp -13 / +2 lines
Lines 5469-5485 void SpeculativeJIT::compileStoreBarrier Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
5469
    noResult(node);
5469
    noResult(node);
5470
}
5470
}
5471
5471
5472
JITCompiler::Jump SpeculativeJIT::checkMarkByte(CCallHelpers& jit, GPRReg owner)
5473
{
5474
    return jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::Address(owner, JSCell::gcDataOffset()));
5475
}
5476
5477
JITCompiler::Jump SpeculativeJIT::checkMarkByte(CCallHelpers& jit, JSCell* owner)
5478
{
5479
    uint8_t* address = reinterpret_cast<uint8_t*>(owner) + JSCell::gcDataOffset();
5480
    return jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(address));
5481
}
5482
5483
void SpeculativeJIT::storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2)
5472
void SpeculativeJIT::storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2)
5484
{
5473
{
5485
    ASSERT(scratch1 != scratch2);
5474
    ASSERT(scratch1 != scratch2);
Lines 5536-5549 void SpeculativeJIT::writeBarrier(GPRReg Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec2
5536
    if (Heap::isMarked(value))
5525
    if (Heap::isMarked(value))
5537
        return;
5526
        return;
5538
5527
5539
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
5528
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
5540
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
5529
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
5541
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5530
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5542
}
5531
}
5543
5532
5544
void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg scratch1, GPRReg scratch2)
5533
void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg scratch1, GPRReg scratch2)
5545
{
5534
{
5546
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
5535
    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
5547
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
5536
    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
5548
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5537
    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
5549
}
5538
}
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h -2 lines
Lines 296-303 public: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec1
296
    void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
296
    void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
297
    void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2);
297
    void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2);
298
298
299
    static JITCompiler::Jump checkMarkByte(CCallHelpers& jit, GPRReg owner);
300
    static JITCompiler::Jump checkMarkByte(CCallHelpers& jit, JSCell* owner);
301
    void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
299
    void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
302
    void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2);
300
    void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2);
303
301
- Source/JavaScriptCore/jit/AssemblyHelpers.h -17 / +8 lines
Lines 387-397 public: Source/JavaScriptCore/jit/AssemblyHelpers.h_sec1
387
    void jitAssertArgumentCountSane() { }
387
    void jitAssertArgumentCountSane() { }
388
#endif
388
#endif
389
389
390
    Jump checkMarkByte(GPRReg owner)
391
    {
392
        return branchTest8(NonZero, Address(owner, JSCell::gcDataOffset()));
393
    }
394
395
    // These methods convert between doubles, and doubles boxed and JSValues.
390
    // These methods convert between doubles, and doubles boxed and JSValues.
396
#if USE(JSVALUE64)
391
#if USE(JSVALUE64)
397
    GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
392
    GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
Lines 620-638 public: Source/JavaScriptCore/jit/AssemblyHelpers.h_sec2
620
#endif
615
#endif
621
    }
616
    }
622
617
623
    void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
618
    Jump checkMarkByte(GPRReg cell)
624
    {
619
    {
625
        UNUSED_PARAM(owner);
620
        return branchTest8(MacroAssembler::NonZero, MacroAssembler::Address(cell, JSCell::gcDataOffset()));
626
        UNUSED_PARAM(scratch1);
621
    }
627
        UNUSED_PARAM(scratch2);
622
628
        UNUSED_PARAM(useKind);
623
    Jump checkMarkByte(JSCell* cell)
629
        ASSERT(owner != scratch1);
624
    {
630
        ASSERT(owner != scratch2);
625
        uint8_t* address = reinterpret_cast<uint8_t*>(cell) + JSCell::gcDataOffset();
631
        ASSERT(scratch1 != scratch2);
626
        return branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(address));
632
        
633
#if ENABLE(WRITE_BARRIER_PROFILING)
634
        emitCount(WriteBarrierCounters::jitCounterFor(useKind));
635
#endif
636
    }
627
    }
637
628
638
    Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
629
    Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
- Source/JavaScriptCore/jit/JIT.h -2 lines
Lines 314-321 namespace JSC { Source/JavaScriptCore/jit/JIT.h_sec1
314
        enum WriteBarrierMode { UnconditionalWriteBarrier, ShouldFilterValue, ShouldFilterBaseAndValue };
314
        enum WriteBarrierMode { UnconditionalWriteBarrier, ShouldFilterValue, ShouldFilterBaseAndValue };
315
        // value register in write barrier is used before any scratch registers
315
        // value register in write barrier is used before any scratch registers
316
        // so may safely be the same as either of the scratch registers.
316
        // so may safely be the same as either of the scratch registers.
317
        Jump checkMarkByte(RegisterID owner);
318
        Jump checkMarkByte(JSCell* owner);
319
        void emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode);
317
        void emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode);
320
        void emitWriteBarrier(JSCell* owner, unsigned value, WriteBarrierMode);
318
        void emitWriteBarrier(JSCell* owner, unsigned value, WriteBarrierMode);
321
        void emitWriteBarrier(JSCell* owner);
319
        void emitWriteBarrier(JSCell* owner);
- Source/JavaScriptCore/jit/JITPropertyAccess.cpp -11 lines
Lines 879-895 void JIT::emit_op_init_global_const(Inst Source/JavaScriptCore/jit/JITPropertyAccess.cpp_sec1
879
879
880
#endif // USE(JSVALUE64)
880
#endif // USE(JSVALUE64)
881
881
882
JIT::Jump JIT::checkMarkByte(RegisterID owner)
883
{
884
    return branchTest8(NonZero, Address(owner, JSCell::gcDataOffset()));
885
}
886
887
JIT::Jump JIT::checkMarkByte(JSCell* owner)
888
{
889
    uint8_t* address = reinterpret_cast<uint8_t*>(owner) + JSCell::gcDataOffset();
890
    return branchTest8(NonZero, AbsoluteAddress(address));
891
}
892
893
#if USE(JSVALUE64)
882
#if USE(JSVALUE64)
894
void JIT::emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode mode)
883
void JIT::emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode mode)
895
{
884
{
- Source/JavaScriptCore/jit/Repatch.cpp -5 / +2 lines
Lines 824-836 static MacroAssembler::Call writeBarrier Source/JavaScriptCore/jit/Repatch.cpp_sec1
824
    ASSERT(owner != scratch1);
824
    ASSERT(owner != scratch1);
825
    ASSERT(owner != scratch2);
825
    ASSERT(owner != scratch2);
826
826
827
#if ENABLE(DFG_JIT)
827
    MacroAssembler::Jump ownerNotMarkedOrAlreadyRemembered = jit.checkMarkByte(owner);
828
    MacroAssembler::Jump ownerNotMarkedOrAlreadyRemembered = DFG::SpeculativeJIT::checkMarkByte(jit, owner);
829
#endif
830
    MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2, allocator);
828
    MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2, allocator);
831
#if ENABLE(DFG_JIT)
832
    ownerNotMarkedOrAlreadyRemembered.link(&jit);
829
    ownerNotMarkedOrAlreadyRemembered.link(&jit);
833
#endif
830
834
    return call;
831
    return call;
835
}
832
}
836
#endif // ENABLE(GGC)
833
#endif // ENABLE(GGC)

Return to Bug 129760