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*);