Title: [231607] trunk/Source/_javascript_Core
Revision
231607
Author
[email protected]
Date
2018-05-09 16:31:14 -0700 (Wed, 09 May 2018)

Log Message

Speed up AbstractInterpreter::executeEdges
https://bugs.webkit.org/show_bug.cgi?id=185457

Reviewed by Saam Barati.

This patch started out with the desire to make executeEdges() faster by making filtering faster.
However, when I studied the disassembly, I found that there are many opportunities for
improvement and I implemented all of them:
        
- Filtering itself now has an inline fast path for when the filtering didn't change the value or
  for non-cells.
        
- Edge execution doesn't fast-forward anything if the filtering fast path would have succeeded,
  since fast-forwarding is only interesting for cells and only if we have a clobbered value.
        
- Similarly, edge verification doesn't need to fast-forward in the common case.
        
- A bunch of stuff related to Graph::doToChildren is now inlined properly.
        
- The edge doesn't even have to be considered for execution if it's UntypedUse.
        
That last bit was the trickiest. We had gotten into a bad habit of using SpecFullNumber in the
abstract interpreter. It's not correct to use SpecFullNumber in the abstract interpreter, because
it means proving that the value could either be formatted as a double (with impure NaN values),
or as any JSValue, or as an Int52. There is no value that could possibly hold all of those
states. This "worked" before because UntypedUse would filter this down to SpecBytecodeNumber. To
make it work again, I needed to fix all of those uses of SpecFullNumber. In the future, we need
to be careful about picking either SpecFullDouble (if returning a DoubleRep) or
SpecBytecodeNumber (if returning a JSValueRep).
        
But that fix revealed an amazing timeout in
stress/keep-checks-when-converting-to-lazy-js-constant-in-strength-reduction.js. We were getting
stuck in an OSR loop (baseline->DFG->FTL->baseline), all involving the same bytecode, without
ever realizing that we should jettison something. The problem was with how
triggerReoptimizationNow was getting the optimizedCodeBlock. It was trying to guess it by using
baselineCodeBlock->replacement(), but that's wrong for FTL-for-OSR-entry code blocks.
        
This is a 1% improvement in V8Spider-CompileTime.

* bytecode/ExitKind.cpp:
(JSC::exitKindMayJettison):
* dfg/DFGAbstractInterpreter.h:
(JSC::DFG::AbstractInterpreter::filterEdgeByUse):
(JSC::DFG::AbstractInterpreter::filterByType): Deleted.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreterExecuteEdgesFunc::AbstractInterpreterExecuteEdgesFunc):
(JSC::DFG::AbstractInterpreterExecuteEdgesFunc::operator() const):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEdges):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterByType):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::verifyEdge):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeDoubleUnaryOpEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filterSlow):
(JSC::DFG::AbstractValue::fastForwardToAndFilterSlow):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::filter):
(JSC::DFG::AbstractValue::fastForwardToAndFilter):
(JSC::DFG::AbstractValue::fastForwardToAndFilterUnproven):
(JSC::DFG::AbstractValue::makeTop):
* dfg/DFGAtTailAbstractState.h:
(JSC::DFG::AtTailAbstractState::fastForward):
(JSC::DFG::AtTailAbstractState::forNodeWithoutFastForward):
(JSC::DFG::AtTailAbstractState::fastForwardAndFilterUnproven):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::doToChildren):
* dfg/DFGInPlaceAbstractState.h:
(JSC::DFG::InPlaceAbstractState::fastForward):
(JSC::DFG::InPlaceAbstractState::fastForwardAndFilterUnproven):
(JSC::DFG::InPlaceAbstractState::forNodeWithoutFastForward):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::executeOSRExit):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::handleExitCounts):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (231606 => 231607)


--- trunk/Source/_javascript_Core/ChangeLog	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-05-09 23:31:14 UTC (rev 231607)
@@ -1,3 +1,82 @@
+2018-05-09  Filip Pizlo  <[email protected]>
+
+        Speed up AbstractInterpreter::executeEdges
+        https://bugs.webkit.org/show_bug.cgi?id=185457
+
+        Reviewed by Saam Barati.
+
+        This patch started out with the desire to make executeEdges() faster by making filtering faster.
+        However, when I studied the disassembly, I found that there are many opportunities for
+        improvement and I implemented all of them:
+        
+        - Filtering itself now has an inline fast path for when the filtering didn't change the value or
+          for non-cells.
+        
+        - Edge execution doesn't fast-forward anything if the filtering fast path would have succeeded,
+          since fast-forwarding is only interesting for cells and only if we have a clobbered value.
+        
+        - Similarly, edge verification doesn't need to fast-forward in the common case.
+        
+        - A bunch of stuff related to Graph::doToChildren is now inlined properly.
+        
+        - The edge doesn't even have to be considered for execution if it's UntypedUse.
+        
+        That last bit was the trickiest. We had gotten into a bad habit of using SpecFullNumber in the
+        abstract interpreter. It's not correct to use SpecFullNumber in the abstract interpreter, because
+        it means proving that the value could either be formatted as a double (with impure NaN values),
+        or as any JSValue, or as an Int52. There is no value that could possibly hold all of those
+        states. This "worked" before because UntypedUse would filter this down to SpecBytecodeNumber. To
+        make it work again, I needed to fix all of those uses of SpecFullNumber. In the future, we need
+        to be careful about picking either SpecFullDouble (if returning a DoubleRep) or
+        SpecBytecodeNumber (if returning a JSValueRep).
+        
+        But that fix revealed an amazing timeout in
+        stress/keep-checks-when-converting-to-lazy-js-constant-in-strength-reduction.js. We were getting
+        stuck in an OSR loop (baseline->DFG->FTL->baseline), all involving the same bytecode, without
+        ever realizing that we should jettison something. The problem was with how
+        triggerReoptimizationNow was getting the optimizedCodeBlock. It was trying to guess it by using
+        baselineCodeBlock->replacement(), but that's wrong for FTL-for-OSR-entry code blocks.
+        
+        This is a 1% improvement in V8Spider-CompileTime.
+
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindMayJettison):
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::filterEdgeByUse):
+        (JSC::DFG::AbstractInterpreter::filterByType): Deleted.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreterExecuteEdgesFunc::AbstractInterpreterExecuteEdgesFunc):
+        (JSC::DFG::AbstractInterpreterExecuteEdgesFunc::operator() const):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEdges):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterByType):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::verifyEdge):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeDoubleUnaryOpEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::filterSlow):
+        (JSC::DFG::AbstractValue::fastForwardToAndFilterSlow):
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::filter):
+        (JSC::DFG::AbstractValue::fastForwardToAndFilter):
+        (JSC::DFG::AbstractValue::fastForwardToAndFilterUnproven):
+        (JSC::DFG::AbstractValue::makeTop):
+        * dfg/DFGAtTailAbstractState.h:
+        (JSC::DFG::AtTailAbstractState::fastForward):
+        (JSC::DFG::AtTailAbstractState::forNodeWithoutFastForward):
+        (JSC::DFG::AtTailAbstractState::fastForwardAndFilterUnproven):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::doToChildren):
+        * dfg/DFGInPlaceAbstractState.h:
+        (JSC::DFG::InPlaceAbstractState::fastForward):
+        (JSC::DFG::InPlaceAbstractState::fastForwardAndFilterUnproven):
+        (JSC::DFG::InPlaceAbstractState::forNodeWithoutFastForward):
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::OSRExit::executeOSRExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::handleExitCounts):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+
 2018-05-09  Saam Barati  <[email protected]>
 
         Add JSVirtualMachine SPI to shrink the memory footprint of the VM

Modified: trunk/Source/_javascript_Core/bytecode/ExitKind.cpp (231606 => 231607)


--- trunk/Source/_javascript_Core/bytecode/ExitKind.cpp	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/bytecode/ExitKind.cpp	2018-05-09 23:31:14 UTC (rev 231607)
@@ -104,9 +104,6 @@
     default:
         return true;
     }
-
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreter.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -160,7 +160,10 @@
     
     ALWAYS_INLINE void filterEdgeByUse(Edge& edge)
     {
-        filterByType(edge, typeFilterFor(edge.useKind()));
+        UseKind useKind = edge.useKind();
+        if (useKind == UntypedUse)
+            return;
+        filterByType(edge, typeFilterFor(useKind));
     }
     
     // Abstractly execute the effects of the given node. This changes the abstract
@@ -242,12 +245,7 @@
         m_state.setFoundConstants(true);
     }
     
-    ALWAYS_INLINE void filterByType(Edge& edge, SpeculatedType type)
-    {
-        AbstractValue& value = forNode(edge);
-        m_state.setProofStatus(edge, value.isType(type) ? IsProved : NeedsCheck);
-        filter(value, type);
-    }
+    ALWAYS_INLINE void filterByType(Edge& edge, SpeculatedType type);
     
     void verifyEdge(Node*, Edge);
     void verifyEdges(Node*);

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -102,13 +102,27 @@
 }
 
 template<typename AbstractStateType>
+class AbstractInterpreterExecuteEdgesFunc {
+public:
+    AbstractInterpreterExecuteEdgesFunc(AbstractInterpreter<AbstractStateType>& interpreter)
+        : m_interpreter(interpreter)
+    {
+    }
+    
+    // This func is manually written out so that we can put ALWAYS_INLINE on it.
+    ALWAYS_INLINE void operator()(Edge& edge) const
+    {
+        m_interpreter.filterEdgeByUse(edge);
+    }
+    
+private:
+    AbstractInterpreter<AbstractStateType>& m_interpreter;
+};
+
+template<typename AbstractStateType>
 void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
 {
-    m_graph.doToChildren(
-        node,
-        [&] (Edge& edge) {
-            filterEdgeByUse(edge);
-        });
+    m_graph.doToChildren(node, AbstractInterpreterExecuteEdgesFunc<AbstractStateType>(*this));
 }
 
 template<typename AbstractStateType>
@@ -130,9 +144,21 @@
 }
 
 template<typename AbstractStateType>
+ALWAYS_INLINE void AbstractInterpreter<AbstractStateType>::filterByType(Edge& edge, SpeculatedType type)
+{
+    AbstractValue& value = m_state.forNodeWithoutFastForward(edge);
+    if (value.isType(type)) {
+        m_state.setProofStatus(edge, IsProved);
+        return;
+    }
+    m_state.setProofStatus(edge, NeedsCheck);
+    m_state.fastForwardAndFilterUnproven(value, type);
+}
+
+template<typename AbstractStateType>
 void AbstractInterpreter<AbstractStateType>::verifyEdge(Node* node, Edge edge)
 {
-    if (!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())))
+    if (!(m_state.forNodeWithoutFastForward(edge).m_type & ~typeFilterFor(edge.useKind())))
         return;
     
     DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type), " (", forNode(edge).m_type, ")").data(), AbstractInterpreterInvalidType, node->op(), edge->op(), edge.useKind(), forNode(edge).m_type);
@@ -999,7 +1025,7 @@
         default:
             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
             clobberWorld();
-            setNonCellTypeForNode(node, SpecFullNumber);
+            setNonCellTypeForNode(node, SpecBytecodeNumber);
             break;
         }
         break;
@@ -1079,7 +1105,7 @@
         } else {
             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
             clobberWorld();
-            setNonCellTypeForNode(node, SpecFullNumber);
+            setNonCellTypeForNode(node, SpecBytecodeNumber);
         }
         break;
     }
@@ -3712,11 +3738,13 @@
         setConstant(node, jsDoubleNumber(equivalentFunction(*number)));
         return;
     }
-    SpeculatedType type = SpecFullNumber;
+    SpeculatedType type;
     if (node->child1().useKind() == DoubleRepUse)
         type = typeOfDoubleUnaryOp(forNode(node->child1()).m_type);
-    else
+    else {
         clobberWorld();
+        type = SpecBytecodeNumber;
+    }
     setNonCellTypeForNode(node, type);
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2018-05-09 23:31:14 UTC (rev 231607)
@@ -332,24 +332,8 @@
     return normalizeClarity(graph);
 }
 
-FiltrationResult AbstractValue::filter(SpeculatedType type)
+FiltrationResult AbstractValue::filterSlow(SpeculatedType type)
 {
-    if ((m_type & type) == m_type)
-        return FiltrationOK;
-    
-    // Fast path for the case that we don't even have a cell.
-    if (!(m_type & SpecCell)) {
-        m_type &= type;
-        FiltrationResult result;
-        if (m_type == SpecNone) {
-            clear();
-            result = Contradiction;
-        } else
-            result = FiltrationOK;
-        checkConsistency();
-        return result;
-    }
-    
     m_type &= type;
     
     // It's possible that prior to this filter() call we had, say, (Final, TOP), and
@@ -362,6 +346,14 @@
     return normalizeClarity();
 }
 
+FiltrationResult AbstractValue::fastForwardToAndFilterSlow(AbstractValueClobberEpoch newEpoch, SpeculatedType type)
+{
+    if (newEpoch != m_effectEpoch)
+        fastForwardToSlow(newEpoch);
+    
+    return filterSlow(type);
+}
+
 FiltrationResult AbstractValue::filterByValue(const FrozenValue& value)
 {
     FiltrationResult result = filter(speculationFromValue(value.value()));

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -312,7 +312,28 @@
     FiltrationResult filter(Graph&, const RegisteredStructureSet&, SpeculatedType admittedTypes = SpecNone);
     
     FiltrationResult filterArrayModes(ArrayModes);
-    FiltrationResult filter(SpeculatedType);
+
+    ALWAYS_INLINE FiltrationResult filter(SpeculatedType type)
+    {
+        if ((m_type & type) == m_type)
+            return FiltrationOK;
+    
+        // Fast path for the case that we don't even have a cell.
+        if (!(m_type & SpecCell)) {
+            m_type &= type;
+            FiltrationResult result;
+            if (m_type == SpecNone) {
+                clear();
+                result = Contradiction;
+            } else
+                result = FiltrationOK;
+            checkConsistency();
+            return result;
+        }
+        
+        return filterSlow(type);
+    }
+    
     FiltrationResult filterByValue(const FrozenValue& value);
     FiltrationResult filter(const AbstractValue&);
     FiltrationResult filterClassInfo(Graph&, const ClassInfo*);
@@ -319,6 +340,23 @@
 
     FiltrationResult filter(Graph&, const InferredType::Descriptor&);
     
+    ALWAYS_INLINE FiltrationResult fastForwardToAndFilterUnproven(AbstractValueClobberEpoch newEpoch, SpeculatedType type)
+    {
+        if (m_type & SpecCell)
+            return fastForwardToAndFilterSlow(newEpoch, type);
+        
+        m_effectEpoch = newEpoch;
+        m_type &= type;
+        FiltrationResult result;
+        if (m_type == SpecNone) {
+            clear();
+            result = Contradiction;
+        } else
+            result = FiltrationOK;
+        checkConsistency();
+        return result;
+    }
+
     FiltrationResult changeStructure(Graph&, const RegisteredStructureSet&);
     
     bool contains(RegisteredStructure) const;
@@ -469,7 +507,7 @@
     
     void makeTop(SpeculatedType top)
     {
-        m_type |= top;
+        m_type = top;
         m_arrayModes = ALL_ARRAY_MODES;
         m_structure.makeTop();
         m_value = JSValue();
@@ -477,6 +515,8 @@
     }
     
     void fastForwardToSlow(AbstractValueClobberEpoch);
+    FiltrationResult filterSlow(SpeculatedType);
+    FiltrationResult fastForwardToAndFilterSlow(AbstractValueClobberEpoch, SpeculatedType);
     
     void filterValueByType();
     void filterArrayModesByType();

Modified: trunk/Source/_javascript_Core/dfg/DFGAtTailAbstractState.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGAtTailAbstractState.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGAtTailAbstractState.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -50,9 +50,27 @@
     }
     
     void createValueForNode(NodeFlowProjection);
+    
+    AbstractValue& fastForward(AbstractValue& value) { return value; }
+    
     AbstractValue& forNode(NodeFlowProjection);
     AbstractValue& forNode(Edge edge) { return forNode(edge.node()); }
     
+    ALWAYS_INLINE AbstractValue& forNodeWithoutFastForward(NodeFlowProjection node)
+    {
+        return forNode(node);
+    }
+    
+    ALWAYS_INLINE AbstractValue& forNodeWithoutFastForward(Edge edge)
+    {
+        return forNode(edge);
+    }
+    
+    ALWAYS_INLINE void fastForwardAndFilterUnproven(AbstractValue& value, SpeculatedType type)
+    {
+        value.filter(type);
+    }
+    
     ALWAYS_INLINE void clearForNode(NodeFlowProjection node)
     {
         forNode(node).clear();

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -716,11 +716,24 @@
     template<typename ChildFunctor>
     ALWAYS_INLINE void doToChildren(Node* node, const ChildFunctor& functor)
     {
-        doToChildrenWithNode(
-            node,
-            [&functor] (Node*, Edge& edge) {
-                functor(edge);
-            });
+        class ForwardingFunc {
+        public:
+            ForwardingFunc(const ChildFunctor& functor)
+                : m_functor(functor)
+            {
+            }
+            
+            // This is a manually written func because we want ALWAYS_INLINE.
+            ALWAYS_INLINE void operator()(Node*, Edge& edge) const
+            {
+                m_functor(edge);
+            }
+        
+        private:
+            const ChildFunctor& m_functor;
+        };
+    
+        doToChildrenWithNode(node, ForwardingFunc(functor));
     }
     
     bool uses(Node* node, Node* child)

Modified: trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -47,6 +47,27 @@
     
     void createValueForNode(NodeFlowProjection) { }
     
+    ALWAYS_INLINE AbstractValue& fastForward(AbstractValue& value)
+    {
+        value.fastForwardTo(m_effectEpoch);
+        return value;
+    }
+    
+    ALWAYS_INLINE void fastForwardAndFilterUnproven(AbstractValue& value, SpeculatedType type)
+    {
+        value.fastForwardToAndFilterUnproven(m_effectEpoch, type);
+    }
+    
+    ALWAYS_INLINE AbstractValue& forNodeWithoutFastForward(NodeFlowProjection node)
+    {
+        return m_abstractValues.at(node);
+    }
+    
+    ALWAYS_INLINE AbstractValue& forNodeWithoutFastForward(Edge edge)
+    {
+        return forNodeWithoutFastForward(edge.node());
+    }
+    
     ALWAYS_INLINE AbstractValue& forNode(NodeFlowProjection node)
     {
         return fastForward(m_abstractValues.at(node));
@@ -226,12 +247,6 @@
     }
 
 private:
-    ALWAYS_INLINE AbstractValue& fastForward(AbstractValue& value)
-    {
-        value.fastForwardTo(m_effectEpoch);
-        return value;
-    }
-    
     void mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, Node*);
 
     static bool mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, Node* destinationNode, Node* sourceNode);

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2018-05-09 23:31:14 UTC (rev 231607)
@@ -716,7 +716,7 @@
     // counterValueForOptimizeAfterWarmUp().
 
     if (UNLIKELY(codeBlock->updateOSRExitCounterAndCheckIfNeedToReoptimize(exitState) == CodeBlock::OptimizeAction::ReoptimizeNow))
-        triggerReoptimizationNow(baselineCodeBlock, &exit);
+        triggerReoptimizationNow(baselineCodeBlock, codeBlock, &exit);
 
     reifyInlinedCallFrames(context, baselineCodeBlock, exit);
     adjustAndJumpToTarget(context, vm, codeBlock, baselineCodeBlock, exit);

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2018-05-09 23:31:14 UTC (rev 231607)
@@ -49,13 +49,13 @@
 
     jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
     
-    jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::regT0);
+    jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::regT3);
     
     AssemblyHelpers::Jump tooFewFails;
     
-    jit.load32(AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfOSRExitCounter()), GPRInfo::regT2);
+    jit.load32(AssemblyHelpers::Address(GPRInfo::regT3, CodeBlock::offsetOfOSRExitCounter()), GPRInfo::regT2);
     jit.add32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
-    jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfOSRExitCounter()));
+    jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT3, CodeBlock::offsetOfOSRExitCounter()));
     
     jit.move(AssemblyHelpers::TrustedImmPtr(jit.baselineCodeBlock()), GPRInfo::regT0);
     AssemblyHelpers::Jump reoptimizeNow = jit.branch32(
@@ -101,14 +101,7 @@
     
     reoptimizeNow.link(&jit);
     
-    // Reoptimize as soon as possible.
-#if !NUMBER_OF_ARGUMENT_REGISTERS
-    jit.poke(GPRInfo::regT0);
-    jit.poke(AssemblyHelpers::TrustedImmPtr(&exit), 1);
-#else
-    jit.move(GPRInfo::regT0, GPRInfo::argumentGPR0);
-    jit.move(AssemblyHelpers::TrustedImmPtr(&exit), GPRInfo::argumentGPR1);
-#endif
+    jit.setupArguments<decltype(triggerReoptimizationNow)>(GPRInfo::regT0, GPRInfo::regT3, AssemblyHelpers::TrustedImmPtr(&exit));
     jit.move(AssemblyHelpers::TrustedImmPtr(tagCFunctionPtr<OperationPtrTag>(triggerReoptimizationNow)), GPRInfo::nonArgGPR0);
     jit.call(GPRInfo::nonArgGPR0, OperationPtrTag);
     AssemblyHelpers::Jump doneAdjusting = jit.jump();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-05-09 23:31:14 UTC (rev 231607)
@@ -2815,7 +2815,7 @@
     scope.throwException(exec, createError(exec, static_cast<ErrorType>(errorType), errorMessage));
 }
 
-extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
+extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, CodeBlock* optimizedCodeBlock, OSRExitBase* exit)
 {
     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
     // really be profitable.
@@ -2830,6 +2830,9 @@
 
     // If I am my own replacement, then reoptimization has already been triggered.
     // This can happen in recursive functions.
+    //
+    // Note that even if optimizedCodeBlock is an FTLForOSREntry style CodeBlock, this condition is a
+    // sure bet that we don't have anything else left to do.
     if (codeBlock->replacement() == codeBlock) {
         if (Options::verboseOSR())
             dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
@@ -2839,7 +2842,6 @@
     // Otherwise, the replacement must be optimized code. Use this as an opportunity
     // to check our logic.
     ASSERT(codeBlock->hasOptimizedReplacement());
-    CodeBlock* optimizedCodeBlock = codeBlock->replacement();
     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
     
     bool didTryToEnterIntoInlinedLoops = false;
@@ -2864,7 +2866,7 @@
         codeBlock->optimizeAfterLongWarmUp();
         return;
     }
-
+    
     optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (231606 => 231607)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2018-05-09 23:15:49 UTC (rev 231606)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2018-05-09 23:31:14 UTC (rev 231607)
@@ -266,7 +266,7 @@
 
 void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState*) WTF_INTERNAL;
 
-void JIT_OPERATION triggerReoptimizationNow(CodeBlock*, OSRExitBase*) WTF_INTERNAL;
+void JIT_OPERATION triggerReoptimizationNow(CodeBlock* baselineCodeBlock, CodeBlock* optiimzedCodeBlock, OSRExitBase*) WTF_INTERNAL;
 
 #if USE(JSVALUE32_64)
 double JIT_OPERATION operationRandom(JSGlobalObject*);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to