Title: [165135] trunk/Source/_javascript_Core
Revision
165135
Author
[email protected]
Date
2014-03-05 15:33:21 -0800 (Wed, 05 Mar 2014)

Log Message

JSCell::m_gcData should encode its information differently
https://bugs.webkit.org/show_bug.cgi?id=129741

Reviewed by Geoffrey Garen.

We want to keep track of three GC states for an object:

1. Not marked (which implies not in the remembered set)
2. Marked but not in the remembered set
3. Marked and in the remembered set
        
Currently we only indicate marked vs. not marked in JSCell::m_gcData. During a write 
barrier, we only want to take the slow path if the object being stored to is in state #2. 
We'd like to make the test for state #2 as fast as possible, which means making it a 
compare against 0.

* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::osrWriteBarrier):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::checkMarkByte):
(JSC::DFG::SpeculativeJIT::writeBarrier):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::writeBarrier):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::writeBarrier):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::allocateCell):
(JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
* heap/Heap.cpp:
(JSC::Heap::clearRememberedSet):
(JSC::Heap::addToRememberedSet):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::checkMarkByte):
* jit/JIT.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::checkMarkByte):
(JSC::JIT::emitWriteBarrier):
* jit/Repatch.cpp:
(JSC::writeBarrier):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/JSCell.h:
(JSC::JSCell::mark):
(JSC::JSCell::remember):
(JSC::JSCell::forget):
(JSC::JSCell::isMarked):
(JSC::JSCell::isRemembered):
* runtime/JSCellInlines.h:
(JSC::JSCell::JSCell):
* runtime/StructureIDBlob.h:
(JSC::StructureIDBlob::StructureIDBlob):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (165134 => 165135)


--- trunk/Source/_javascript_Core/ChangeLog	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-03-05 23:33:21 UTC (rev 165135)
@@ -1,3 +1,59 @@
+2014-03-05  Mark Hahnenberg  <[email protected]>
+
+        JSCell::m_gcData should encode its information differently
+        https://bugs.webkit.org/show_bug.cgi?id=129741
+
+        Reviewed by Geoffrey Garen.
+
+        We want to keep track of three GC states for an object:
+
+        1. Not marked (which implies not in the remembered set)
+        2. Marked but not in the remembered set
+        3. Marked and in the remembered set
+        
+        Currently we only indicate marked vs. not marked in JSCell::m_gcData. During a write 
+        barrier, we only want to take the slow path if the object being stored to is in state #2. 
+        We'd like to make the test for state #2 as fast as possible, which means making it a 
+        compare against 0.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::osrWriteBarrier):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::checkMarkByte):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::allocateCell):
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        * heap/Heap.cpp:
+        (JSC::Heap::clearRememberedSet):
+        (JSC::Heap::addToRememberedSet):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::checkMarkByte):
+        * jit/JIT.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::checkMarkByte):
+        (JSC::JIT::emitWriteBarrier):
+        * jit/Repatch.cpp:
+        (JSC::writeBarrier):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSCell.h:
+        (JSC::JSCell::mark):
+        (JSC::JSCell::remember):
+        (JSC::JSCell::forget):
+        (JSC::JSCell::isMarked):
+        (JSC::JSCell::isRemembered):
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::JSCell):
+        * runtime/StructureIDBlob.h:
+        (JSC::StructureIDBlob::StructureIDBlob):
+
 2014-03-05  Filip Pizlo  <[email protected]>
 
         More FTL ARM fixes

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -164,7 +164,7 @@
 #if ENABLE(GGC)
 static void osrWriteBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch)
 {
-    AssemblyHelpers::Jump definitelyNotMarked = jit.genericWriteBarrier(owner);
+    AssemblyHelpers::Jump ownerNotMarkedOrAlreadyRemembered = jit.checkMarkByte(owner);
 
     // We need these extra slots because setupArgumentsWithExecState will use poke on x86.
 #if CPU(X86)
@@ -179,7 +179,7 @@
     jit.addPtr(MacroAssembler::TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
 #endif
 
-    definitelyNotMarked.link(&jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&jit);
 }
 #endif // ENABLE(GGC)
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -5469,15 +5469,15 @@
     noResult(node);
 }
 
-JITCompiler::Jump SpeculativeJIT::genericWriteBarrier(CCallHelpers& jit, GPRReg owner)
+JITCompiler::Jump SpeculativeJIT::checkMarkByte(CCallHelpers& jit, GPRReg owner)
 {
-    return jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(owner, JSCell::gcDataOffset()));
+    return jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::Address(owner, JSCell::gcDataOffset()));
 }
 
-JITCompiler::Jump SpeculativeJIT::genericWriteBarrier(CCallHelpers& jit, JSCell* owner)
+JITCompiler::Jump SpeculativeJIT::checkMarkByte(CCallHelpers& jit, JSCell* owner)
 {
     uint8_t* address = reinterpret_cast<uint8_t*>(owner) + JSCell::gcDataOffset();
-    return jit.branchTest8(MacroAssembler::Zero, MacroAssembler::AbsoluteAddress(address));
+    return jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(address));
 }
 
 void SpeculativeJIT::storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2)
@@ -5536,16 +5536,16 @@
     if (Heap::isMarked(value))
         return;
 
-    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(m_jit, ownerGPR);
+    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    definitelyNotMarked.link(&m_jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
 }
 
 void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg scratch1, GPRReg scratch2)
 {
-    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(m_jit, ownerGPR);
+    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    definitelyNotMarked.link(&m_jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
 }
 #else
 void SpeculativeJIT::compileStoreBarrier(Node* node)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (165134 => 165135)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -296,8 +296,8 @@
     void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
     void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2);
 
-    static JITCompiler::Jump genericWriteBarrier(CCallHelpers& jit, GPRReg owner);
-    static JITCompiler::Jump genericWriteBarrier(CCallHelpers& jit, JSCell* owner);
+    static JITCompiler::Jump checkMarkByte(CCallHelpers& jit, GPRReg owner);
+    static JITCompiler::Jump checkMarkByte(CCallHelpers& jit, JSCell* owner);
     void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
     void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2);
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -4709,9 +4709,9 @@
     if (!isKnownCell(valueUse.node()))
         isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
 
-    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(m_jit, ownerGPR);
+    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    definitelyNotMarked.link(&m_jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
 
     if (!isKnownCell(valueUse.node()))
         isNotCell.link(&m_jit);
@@ -4723,9 +4723,9 @@
     if (!isKnownCell(valueUse.node()))
         isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
 
-    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(m_jit, owner);
+    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, owner);
     storeToWriteBarrierBuffer(owner, scratch1, scratch2);
-    definitelyNotMarked.link(&m_jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
 
     if (!isKnownCell(valueUse.node()))
         isNotCell.link(&m_jit);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -5042,9 +5042,9 @@
     if (!isKnownCell(valueUse.node()))
         isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
 
-    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(m_jit, ownerGPR);
+    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    definitelyNotMarked.link(&m_jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
 
     if (!isKnownCell(valueUse.node()))
         isNotCell.link(&m_jit);
@@ -5056,9 +5056,9 @@
     if (!isKnownCell(valueUse.node()))
         isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
 
-    JITCompiler::Jump definitelyNotMarked = genericWriteBarrier(m_jit, owner);
+    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(m_jit, owner);
     storeToWriteBarrierBuffer(owner, scratch1, scratch2);
-    definitelyNotMarked.link(&m_jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
 
     if (!isKnownCell(valueUse.node()))
         isNotCell.link(&m_jit);

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -4082,7 +4082,7 @@
         m_out.store8(m_out.constInt8(structure->indexingType()), result, m_heaps.JSCell_indexingType);
         m_out.store8(m_out.constInt8(structure->typeInfo().type()), result, m_heaps.JSCell_typeInfoType);
         m_out.store8(m_out.constInt8(structure->typeInfo().inlineTypeFlags()), result, m_heaps.JSCell_typeInfoFlags);
-        m_out.store8(m_out.constInt8(0), result, m_heaps.JSCell_gcData);
+        m_out.store8(m_out.constInt8(JSCell::NotMarked), result, m_heaps.JSCell_gcData);
         
         return result;
     }
@@ -5404,16 +5404,16 @@
     {
 #if ENABLE(GGC)
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
-        LBasicBlock isMarked = FTL_NEW_BLOCK(m_out, ("Store barrier is marked block"));
+        LBasicBlock isMarkedAndNotRemembered = FTL_NEW_BLOCK(m_out, ("Store barrier is marked block"));
         LBasicBlock bufferHasSpace = FTL_NEW_BLOCK(m_out, ("Store barrier buffer is full"));
         LBasicBlock bufferIsFull = FTL_NEW_BLOCK(m_out, ("Store barrier buffer is full"));
 
         // Check the mark byte. 
         m_out.branch(
-            m_out.isZero8(loadMarkByte(base)), usually(continuation), rarely(isMarked));
+            m_out.notZero8(loadMarkByte(base)), usually(continuation), rarely(isMarkedAndNotRemembered));
 
         // Append to the write barrier buffer.
-        LBasicBlock lastNext = m_out.appendTo(isMarked, bufferHasSpace);
+        LBasicBlock lastNext = m_out.appendTo(isMarkedAndNotRemembered, bufferHasSpace);
         LValue currentBufferIndex = m_out.load32(m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
         LValue bufferCapacity = m_out.load32(m_out.absolute(&vm().heap.writeBarrierBuffer().m_capacity));
         m_out.branch(

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -415,7 +415,7 @@
     JSCell** registerRoots = stackRoots.roots();
     for (size_t i = 0; i < stackRootCount; i++) {
         setMarked(registerRoots[i]);
-        registerRoots[i]->mark();
+        registerRoots[i]->setMarked();
         roots.add(registerRoots[i]);
     }
 }
@@ -668,8 +668,10 @@
 {
 #if ENABLE(GGC)
     GCPHASE(ClearRememberedSet);
-    for (auto* cell : rememberedSet)
+    for (auto* cell : rememberedSet) {
         MarkedBlock::blockFor(cell)->clearRemembered(cell);
+        const_cast<JSCell*>(cell)->setRemembered(false);
+    }
 #else
     UNUSED_PARAM(rememberedSet);
 #endif
@@ -826,6 +828,7 @@
     if (isInRememberedSet(cell))
         return;
     MarkedBlock::blockFor(cell)->setRemembered(cell);
+    const_cast<JSCell*>(cell)->setRemembered(true);
     m_slotVisitor.unconditionallyAppend(const_cast<JSCell*>(cell));
 }
 

Modified: trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h (165134 => 165135)


--- trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -113,7 +113,7 @@
         return;
     }
 
-    cell->mark();
+    cell->setMarked();
     m_bytesVisited += MarkedBlock::blockFor(cell)->cellSize();
         
     MARK_LOG_CHILD(*this, cell);

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (165134 => 165135)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -387,9 +387,9 @@
     void jitAssertArgumentCountSane() { }
 #endif
 
-    Jump genericWriteBarrier(GPRReg owner)
+    Jump checkMarkByte(GPRReg owner)
     {
-        return branchTest8(Zero, Address(owner, JSCell::gcDataOffset()));
+        return branchTest8(NonZero, Address(owner, JSCell::gcDataOffset()));
     }
 
     // These methods convert between doubles, and doubles boxed and JSValues.

Modified: trunk/Source/_javascript_Core/jit/JIT.h (165134 => 165135)


--- trunk/Source/_javascript_Core/jit/JIT.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -314,8 +314,8 @@
         enum WriteBarrierMode { UnconditionalWriteBarrier, ShouldFilterValue, ShouldFilterBaseAndValue };
         // value register in write barrier is used before any scratch registers
         // so may safely be the same as either of the scratch registers.
-        Jump checkMarkWord(RegisterID owner);
-        Jump checkMarkWord(JSCell* owner);
+        Jump checkMarkByte(RegisterID owner);
+        Jump checkMarkByte(JSCell* owner);
         void emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode);
         void emitWriteBarrier(JSCell* owner, unsigned value, WriteBarrierMode);
         void emitWriteBarrier(JSCell* owner);

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -879,15 +879,15 @@
 
 #endif // USE(JSVALUE64)
 
-JIT::Jump JIT::checkMarkWord(RegisterID owner)
+JIT::Jump JIT::checkMarkByte(RegisterID owner)
 {
-    return branchTest8(Zero, Address(owner, JSCell::gcDataOffset()));
+    return branchTest8(NonZero, Address(owner, JSCell::gcDataOffset()));
 }
 
-JIT::Jump JIT::checkMarkWord(JSCell* owner)
+JIT::Jump JIT::checkMarkByte(JSCell* owner)
 {
     uint8_t* address = reinterpret_cast<uint8_t*>(owner) + JSCell::gcDataOffset();
-    return branchTest8(Zero, AbsoluteAddress(address));
+    return branchTest8(NonZero, AbsoluteAddress(address));
 }
 
 #if USE(JSVALUE64)
@@ -904,9 +904,9 @@
     if (mode == ShouldFilterBaseAndValue)
         ownerNotCell = branchTest64(NonZero, regT0, tagMaskRegister);
 
-    Jump ownerNotMarked = checkMarkWord(regT0);
+    Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(regT0);
     callOperation(operationUnconditionalWriteBarrier, regT0);
-    ownerNotMarked.link(this);
+    ownerNotMarkedOrAlreadyRemembered.link(this);
 
     if (mode == ShouldFilterBaseAndValue)
         ownerNotCell.link(this);
@@ -953,9 +953,9 @@
     if (mode == ShouldFilterBaseAndValue)
         ownerNotCell = branch32(NotEqual, regT0, TrustedImm32(JSValue::CellTag));
 
-    Jump ownerNotMarked = checkMarkWord(regT1);
+    Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(regT1);
     callOperation(operationUnconditionalWriteBarrier, regT1);
-    ownerNotMarked.link(this);
+    ownerNotMarkedOrAlreadyRemembered.link(this);
 
     if (mode == ShouldFilterBaseAndValue)
         ownerNotCell.link(this);
@@ -993,9 +993,9 @@
 {
 #if ENABLE(GGC)
     if (!MarkedBlock::blockFor(owner)->isMarked(owner)) {
-        Jump ownerNotMarked = checkMarkWord(owner);
+        Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(owner);
         callOperation(operationUnconditionalWriteBarrier, owner);
-        ownerNotMarked.link(this);
+        ownerNotMarkedOrAlreadyRemembered.link(this);
     } else
         callOperation(operationUnconditionalWriteBarrier, owner);
 #else

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (165134 => 165135)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2014-03-05 23:33:21 UTC (rev 165135)
@@ -825,11 +825,11 @@
     ASSERT(owner != scratch2);
 
 #if ENABLE(DFG_JIT)
-    MacroAssembler::Jump definitelyNotMarked = DFG::SpeculativeJIT::genericWriteBarrier(jit, owner);
+    MacroAssembler::Jump ownerNotMarkedOrAlreadyRemembered = DFG::SpeculativeJIT::checkMarkByte(jit, owner);
 #endif
     MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2, allocator);
 #if ENABLE(DFG_JIT)
-    definitelyNotMarked.link(&jit);
+    ownerNotMarkedOrAlreadyRemembered.link(&jit);
 #endif
     return call;
 }

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (165134 => 165135)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2014-03-05 23:33:21 UTC (rev 165135)
@@ -448,14 +448,7 @@
 end
 
 macro checkMarkByte(cell, scratch1, scratch2, continuation)
-    move cell, scratch1
-    move cell, scratch2
-
-    andp MarkedBlockMask, scratch1
-    andp ~MarkedBlockMask, scratch2
-
-    rshiftp AtomNumberShift + BitMapWordShift, scratch2
-    loadb MarkedBlock::m_marks[scratch1, scratch2, 1], scratch1
+    loadb JSCell::m_gcData[cell], scratch1
     continuation(scratch1)
 end
 

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (165134 => 165135)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2014-03-05 23:33:21 UTC (rev 165135)
@@ -543,8 +543,8 @@
         loadisFromInstruction(cellOperand, t1)
         loadConstantOrVariablePayload(t1, CellTag, t2, .writeBarrierDone)
         checkMarkByte(t2, t1, t3, 
-            macro(marked)
-                btbz marked, .writeBarrierDone
+            macro(gcData)
+                btbnz gcData, .writeBarrierDone
                 push cfr, PC
                 # We make two extra slots because cCall2 will poke.
                 subp 8, sp
@@ -577,8 +577,8 @@
         loadp CodeBlock[cfr], t3
         loadp CodeBlock::m_globalObject[t3], t3
         checkMarkByte(t3, t1, t2,
-            macro(marked)
-                btbz marked, .writeBarrierDone
+            macro(gcData)
+                btbnz gcData, .writeBarrierDone
                 push cfr, PC
                 # We make two extra slots because cCall2 will poke.
                 subp 8, sp

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (165134 => 165135)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2014-03-05 23:33:21 UTC (rev 165135)
@@ -395,8 +395,8 @@
         loadisFromInstruction(cellOperand, t1)
         loadConstantOrVariableCell(t1, t2, .writeBarrierDone)
         checkMarkByte(t2, t1, t3, 
-            macro(marked)
-                btbz marked, .writeBarrierDone
+            macro(gcData)
+                btbnz gcData, .writeBarrierDone
                 push PB, PC
                 cCall2Void(_llint_write_barrier_slow, cfr, t2)
                 pop PC, PB
@@ -426,8 +426,8 @@
         loadp CodeBlock[cfr], t3
         loadp CodeBlock::m_globalObject[t3], t3
         checkMarkByte(t3, t1, t2,
-            macro(marked)
-                btbz marked, .writeBarrierDone
+            macro(gcData)
+                btbnz gcData, .writeBarrierDone
                 push PB, PC
                 cCall2Void(_llint_write_barrier_slow, cfr, t3)
                 pop PC, PB

Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (165134 => 165135)


--- trunk/Source/_javascript_Core/runtime/JSCell.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -142,9 +142,32 @@
 
     JSValue fastGetOwnProperty(VM&, const String&);
 
-    void mark() { m_gcData = 1; }
-    bool isMarked() const { return m_gcData; }
+    enum GCData : uint8_t {
+        Marked = 0,
+        NotMarked = 1,
+        MarkedAndRemembered = 2,
+    };
 
+    void setMarked() { m_gcData = Marked; }
+    void setRemembered(bool remembered)
+    {
+        ASSERT(m_gcData == remembered ? Marked : MarkedAndRemembered);
+        m_gcData = remembered ? MarkedAndRemembered : Marked; 
+    }
+    bool isMarked() const
+    {
+        switch (m_gcData) {
+        case Marked:
+        case MarkedAndRemembered:
+            return true;
+        case NotMarked:
+            return false;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return false;
+    }
+    bool isRemembered() const { return m_gcData == MarkedAndRemembered; }
+
     static ptrdiff_t structureIDOffset()
     {
         return OBJECT_OFFSETOF(JSCell, m_structureID);

Modified: trunk/Source/_javascript_Core/runtime/JSCellInlines.h (165134 => 165135)


--- trunk/Source/_javascript_Core/runtime/JSCellInlines.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/runtime/JSCellInlines.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -38,7 +38,7 @@
 namespace JSC {
 
 inline JSCell::JSCell(CreatingEarlyCellTag)
-    : m_gcData(0)
+    : m_gcData(NotMarked)
 {
     ASSERT(!isCompilationThread());
 }
@@ -48,7 +48,7 @@
     , m_indexingType(structure->indexingType())
     , m_type(structure->typeInfo().type())
     , m_flags(structure->typeInfo().inlineTypeFlags())
-    , m_gcData(0)
+    , m_gcData(NotMarked)
 {
     ASSERT(!isCompilationThread());
 }

Modified: trunk/Source/_javascript_Core/runtime/StructureIDBlob.h (165134 => 165135)


--- trunk/Source/_javascript_Core/runtime/StructureIDBlob.h	2014-03-05 23:16:47 UTC (rev 165134)
+++ trunk/Source/_javascript_Core/runtime/StructureIDBlob.h	2014-03-05 23:33:21 UTC (rev 165135)
@@ -46,7 +46,7 @@
         u.fields.indexingType = indexingType;
         u.fields.type = typeInfo.type();
         u.fields.inlineTypeFlags = typeInfo.inlineTypeFlags();
-        u.fields.defaultGCData = 0;
+        u.fields.defaultGCData = JSCell::NotMarked;
     }
 
     void operator=(const StructureIDBlob& other) { u.doubleWord = other.u.doubleWord; }
@@ -79,7 +79,7 @@
             IndexingType indexingType;
             JSType type;
             TypeInfo::InlineTypeFlags inlineTypeFlags;
-            uint8_t defaultGCData;
+            JSCell::GCData defaultGCData;
         } fields;
         struct {
             int32_t word1;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to