Title: [161240] trunk/Source/_javascript_Core
Revision
161240
Author
mhahnenb...@apple.com
Date
2014-01-02 16:24:14 -0800 (Thu, 02 Jan 2014)

Log 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):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (161239 => 161240)


--- trunk/Source/_javascript_Core/ChangeLog	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-01-03 00:24:14 UTC (rev 161240)
@@ -1,5 +1,28 @@
 2014-01-02  Mark Hahnenberg  <mhahnenb...@apple.com>
 
+        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):
+
+2014-01-02  Mark Hahnenberg  <mhahnenb...@apple.com>
+
         Storing new CopiedSpace memory into a JSObject should fire a write barrier
         https://bugs.webkit.org/show_bug.cgi?id=126025
 

Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (161239 => 161240)


--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2014-01-03 00:24:14 UTC (rev 161240)
@@ -37,7 +37,8 @@
 
 #define FOR_EACH_ABSTRACT_HEAP(macro) \
     macro(length) \
-    macro(typedArrayProperties)
+    macro(typedArrayProperties) \
+    macro(WriteBarrierBuffer_bufferContents)
 
 #define FOR_EACH_ABSTRACT_FIELD(macro) \
     macro(Butterfly_publicLength, Butterfly::offsetOfPublicLength()) \
@@ -53,6 +54,7 @@
     macro(JSString_value, JSString::offsetOfValue()) \
     macro(JSVariableObject_registers, JSVariableObject::offsetOfRegisters()) \
     macro(MarkedAllocator_freeListHead, MarkedAllocator::offsetOfFreeListHead()) \
+    macro(MarkedBlock_markBits, MarkedBlock::offsetOfMarks()) \
     macro(StringImpl_data, StringImpl::dataOffset()) \
     macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \
     macro(Structure_classInfo, Structure::classInfoOffset()) \

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (161239 => 161240)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2014-01-03 00:24:14 UTC (rev 161240)
@@ -105,6 +105,9 @@
     case TypedArrayWatchpoint:
     case VariableWatchpoint:
     case NotifyWrite:
+    case StoreBarrier:
+    case ConditionalStoreBarrier:
+    case StoreBarrierWithNullCheck:
     case ValueToInt32:
     case Branch:
     case LogicalNot:

Modified: trunk/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h (161239 => 161240)


--- trunk/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h	2014-01-03 00:24:14 UTC (rev 161240)
@@ -71,6 +71,7 @@
     macro(V_JITOperation_EJJJ, functionType(voidType, intPtr, int64, int64, int64)) \
     macro(V_JITOperation_EOZD, functionType(voidType, intPtr, intPtr, int32, doubleType)) \
     macro(V_JITOperation_EOZJ, functionType(voidType, intPtr, intPtr, int32, int64)) \
+    macro(V_JITOperation_EC, functionType(voidType, intPtr, intPtr)) \
     macro(V_JITOperation_EVws, functionType(voidType, intPtr, intPtr)) \
     macro(Z_JITOperation_D, functionType(int32, doubleType))
 

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (161239 => 161240)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-01-03 00:24:14 UTC (rev 161240)
@@ -466,6 +466,15 @@
         case Int52ToValue:
             compileInt52ToValue();
             break;
+        case StoreBarrier:
+            compileStoreBarrier();
+            break;
+        case ConditionalStoreBarrier:
+            compileConditionalStoreBarrier();
+            break;
+        case StoreBarrierWithNullCheck:
+            compileStoreBarrierWithNullCheck();
+            break;
         case Flush:
         case PhantomLocal:
         case SetArgument:
@@ -584,6 +593,34 @@
         setJSValue(lowJSValue(m_node->child1()));
     }
 
+    void compileStoreBarrier()
+    {
+        emitStoreBarrier(lowCell(m_node->child1()));
+    }
+
+    void compileConditionalStoreBarrier()
+    {
+        LValue base = lowCell(m_node->child1());
+        LValue value = lowJSValue(m_node->child2());
+        emitStoreBarrier(base, value, m_node->child2());
+    }
+
+    void compileStoreBarrierWithNullCheck()
+    {
+#if ENABLE(GGC)
+        LBasicBlock isNotNull = FTL_NEW_BLOCK(m_out, ("Store barrier with null check value not null"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
+
+        LValue base = lowJSValue(m_node->child1());
+        m_out.branch(m_out.isZero64(base), continuation, isNotNull);
+        LBasicBlock lastNext = m_out.appendTo(isNotNull, continuation);
+        emitStoreBarrier(base);
+        m_out.appendTo(continuation, lastNext);
+#else
+        speculate(m_node->child1());
+#endif
+    }
+
     void compileUpsilon()
     {
         LValue destination = m_phis.get(m_node->phi());
@@ -3947,6 +3984,72 @@
         return m_graph.masqueradesAsUndefinedWatchpointIsStillValid(m_node->codeOrigin);
     }
     
+    LValue loadMarkByte(LValue base)
+    {
+        LValue markedBlock = m_out.bitAnd(base, m_out.constInt64(MarkedBlock::blockMask));
+        LValue baseOffset = m_out.bitAnd(base, m_out.constInt64(~MarkedBlock::blockMask));
+        LValue markByteIndex = m_out.lShr(baseOffset, m_out.constInt64(MarkedBlock::atomShiftAmount + MarkedBlock::markByteShiftAmount));
+        return m_out.load8(m_out.baseIndex(m_heaps.MarkedBlock_markBits, markedBlock, markByteIndex, ScaleOne, MarkedBlock::offsetOfMarks()));
+    }
+
+    void emitStoreBarrier(LValue base, LValue value, Edge& valueEdge)
+    {
+#if ENABLE(GGC)
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
+        LBasicBlock isCell = FTL_NEW_BLOCK(m_out, ("Store barrier is cell block"));
+
+        if (m_state.forNode(valueEdge.node()).couldBeType(SpecCell))
+            m_out.branch(isNotCell(value), continuation, isCell);
+        else
+            m_out.jump(isCell);
+
+        LBasicBlock lastNext = m_out.appendTo(isCell, continuation);
+        emitStoreBarrier(base);
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+#else
+        UNUSED_PARAM(base);
+        UNUSED_PARAM(value);
+        UNUSED_PARAM(valueEdge);
+#endif
+    }
+
+    void emitStoreBarrier(LValue base)
+    {
+#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 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)), continuation, isMarked);
+
+        // Append to the write barrier buffer.
+        LBasicBlock lastNext = m_out.appendTo(isMarked, 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(m_out.lessThan(currentBufferIndex, bufferCapacity), bufferHasSpace, bufferIsFull);
+
+        // Buffer has space, store to it.
+        m_out.appendTo(bufferHasSpace, bufferIsFull);
+        LValue writeBarrierBufferBase = m_out.loadPtr(m_out.absolute(&vm().heap.writeBarrierBuffer().m_buffer));
+        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExt(currentBufferIndex, m_out.intPtr), ScalePtr));
+        m_out.store32(m_out.add(currentBufferIndex, m_out.constInt32(1)), m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
+        m_out.jump(continuation);
+
+        // Buffer is out of space, flush it.
+        m_out.appendTo(bufferIsFull, continuation);
+        vmCall(m_out.operation(operationFlushWriteBarrierBuffer), m_callFrame, base);
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+#else
+        UNUSED_PARAM(base);
+#endif
+    }
+
     enum ExceptionCheckMode { NoExceptions, CheckExceptions };
     
     LValue vmCall(LValue function, ExceptionCheckMode mode = CheckExceptions)

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (161239 => 161240)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2014-01-03 00:24:14 UTC (rev 161240)
@@ -269,9 +269,7 @@
     , m_copyVisitor(m_sharedData)
     , m_handleSet(vm)
     , m_isSafeToCollect(false)
-#if ENABLE(GGC)
     , m_writeBarrierBuffer(128)
-#endif
     , m_vm(vm)
     , m_lastGCLength(0)
     , m_lastCodeDiscardTime(WTF::monotonicallyIncreasingTime())

Modified: trunk/Source/_javascript_Core/heap/Heap.h (161239 => 161240)


--- trunk/Source/_javascript_Core/heap/Heap.h	2014-01-03 00:10:48 UTC (rev 161239)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2014-01-03 00:24:14 UTC (rev 161240)
@@ -100,9 +100,7 @@
         static void writeBarrier(const JSCell*, JSCell*);
         static uint8_t* addressOfCardFor(JSCell*);
 
-#if ENABLE(GGC)
         WriteBarrierBuffer& writeBarrierBuffer() { return m_writeBarrierBuffer; }
-#endif
         void flushWriteBarrierBuffer(JSCell*);
 
         Heap(VM*, HeapType);
@@ -292,9 +290,7 @@
         
         bool m_isSafeToCollect;
 
-#if ENABLE(GGC)
         WriteBarrierBuffer m_writeBarrierBuffer;
-#endif
 
         VM* m_vm;
         double m_lastGCLength;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to