<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[179478] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/179478">179478</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-02-02 10:38:08 -0800 (Mon, 02 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Polymorphic call inlining should be based on polymorphic call inline caching rather than logging
https://bugs.webkit.org/show_bug.cgi?id=140660

Reviewed by Geoffrey Garen.
        
When we first implemented polymorphic call inlining, we did the profiling based on a call
edge log. The idea was to store each call edge (a tuple of call site and callee) into a
global log that was processed lazily. Processing the log would give precise counts of call
edges, and could be used to drive well-informed inlining decisions - polymorphic or not.
This was a speed-up on throughput tests but a slow-down for latency tests. It was a net win
nonetheless.
        
Experience with this code shows three things. First, the call edge profiler is buggy and
complex. It would take work to fix the bugs. Second, the call edge profiler incurs lots of
overhead for latency code that we care deeply about. Third, it's not at all clear that
having call edge counts for every possible callee is any better than just having call edge
counts for the limited number of callees that an inline cache would catch.
        
So, this patch removes the call edge profiler and replaces it with a polymorphic call inline
cache. If we miss the basic call inline cache, we inflate the cache to be a jump to an
out-of-line stub that cases on the previously known callees. If that misses again, then we
rewrite that stub to include the new callee. We do this up to some number of callees. If we
hit the limit then we switch to using a plain virtual call.
        
Substantial speed-up on V8Spider; undoes the slow-down that the original call edge profiler
caused. Might be a SunSpider speed-up (below 1%), depending on hardware.
        
Rolling this back in after fixing https://bugs.webkit.org/show_bug.cgi?id=141107.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CallEdge.h:
(JSC::CallEdge::count):
(JSC::CallEdge::CallEdge):
* bytecode/CallEdgeProfile.cpp: Removed.
* bytecode/CallEdgeProfile.h: Removed.
* bytecode/CallEdgeProfileInlines.h: Removed.
* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::unlink):
(JSC::CallLinkInfo::visitWeak):
* bytecode/CallLinkInfo.h:
* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::CallLinkStatus):
(JSC::CallLinkStatus::computeFor):
(JSC::CallLinkStatus::computeFromCallLinkInfo):
(JSC::CallLinkStatus::isClosureCall):
(JSC::CallLinkStatus::makeClosureCall):
(JSC::CallLinkStatus::dump):
(JSC::CallLinkStatus::computeFromCallEdgeProfile): Deleted.
* bytecode/CallLinkStatus.h:
(JSC::CallLinkStatus::CallLinkStatus):
(JSC::CallLinkStatus::isSet):
(JSC::CallLinkStatus::variants):
(JSC::CallLinkStatus::size):
(JSC::CallLinkStatus::at):
(JSC::CallLinkStatus::operator[]):
(JSC::CallLinkStatus::canOptimize):
(JSC::CallLinkStatus::edges): Deleted.
(JSC::CallLinkStatus::canTrustCounts): Deleted.
* bytecode/CallVariant.cpp:
(JSC::variantListWithVariant):
(JSC::despecifiedVariantList):
* bytecode/CallVariant.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::~CodeBlock):
(JSC::CodeBlock::linkIncomingPolymorphicCall):
(JSC::CodeBlock::unlinkIncomingCalls):
(JSC::CodeBlock::noticeIncomingCall):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::isIncomingCallAlreadyLinked): Deleted.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleInlining):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGTierUpCheckInjectionPhase.cpp:
(JSC::DFG::TierUpCheckInjectionPhase::run):
(JSC::DFG::TierUpCheckInjectionPhase::removeFTLProfiling): Deleted.
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* heap/Heap.cpp:
(JSC::Heap::collect):
* jit/BinarySwitch.h:
* jit/ClosureCallStubRoutine.cpp: Removed.
* jit/ClosureCallStubRoutine.h: Removed.
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileOpCall):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
(JSC::operationLinkPolymorphicCallFor):
(JSC::operationLinkClosureCallFor): Deleted.
* jit/JITStubRoutine.h:
* jit/JITWriteBarrier.h:
* jit/PolymorphicCallStubRoutine.cpp: Added.
(JSC::PolymorphicCallNode::~PolymorphicCallNode):
(JSC::PolymorphicCallNode::unlink):
(JSC::PolymorphicCallCase::dump):
(JSC::PolymorphicCallStubRoutine::PolymorphicCallStubRoutine):
(JSC::PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine):
(JSC::PolymorphicCallStubRoutine::variants):
(JSC::PolymorphicCallStubRoutine::edges):
(JSC::PolymorphicCallStubRoutine::visitWeak):
(JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternal):
* jit/PolymorphicCallStubRoutine.h: Added.
(JSC::PolymorphicCallNode::PolymorphicCallNode):
(JSC::PolymorphicCallCase::PolymorphicCallCase):
(JSC::PolymorphicCallCase::variant):
(JSC::PolymorphicCallCase::codeBlock):
* jit/Repatch.cpp:
(JSC::linkSlowFor):
(JSC::linkFor):
(JSC::revertCall):
(JSC::unlinkFor):
(JSC::linkVirtualFor):
(JSC::linkPolymorphicCall):
(JSC::linkClosureCall): Deleted.
* jit/Repatch.h:
* jit/ThunkGenerators.cpp:
(JSC::linkPolymorphicCallForThunkGenerator):
(JSC::linkPolymorphicCallThunkGenerator):
(JSC::linkPolymorphicCallThatPreservesRegsThunkGenerator):
(JSC::linkClosureCallForThunkGenerator): Deleted.
(JSC::linkClosureCallThunkGenerator): Deleted.
(JSC::linkClosureCallThatPreservesRegsThunkGenerator): Deleted.
* jit/ThunkGenerators.h:
(JSC::linkPolymorphicCallThunkGeneratorFor):
(JSC::linkClosureCallThunkGeneratorFor): Deleted.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/Options.h:
* runtime/VM.cpp:
(JSC::VM::prepareToDiscardCode):
(JSC::VM::ensureCallEdgeLog): Deleted.
* runtime/VM.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkMakefileshared">trunk/Makefile.shared</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeh">trunk/Source/JavaScriptCore/bytecode/CallEdge.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkInfocpp">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkInfoh">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkStatuscpp">trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkStatush">trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallVariantcpp">trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallVarianth">trunk/Source/JavaScriptCore/bytecode/CallVariant.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDrivercpp">trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTierUpCheckInjectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitBinarySwitchh">trunk/Source/JavaScriptCore/jit/BinarySwitch.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCallcpp">trunk/Source/JavaScriptCore/jit/JITCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCall32_64cpp">trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITStubRoutineh">trunk/Source/JavaScriptCore/jit/JITStubRoutine.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITWriteBarrierh">trunk/Source/JavaScriptCore/jit/JITWriteBarrier.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchh">trunk/Source/JavaScriptCore/jit/Repatch.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorscpp">trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorsh">trunk/Source/JavaScriptCore/jit/ThunkGenerators.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorejitPolymorphicCallStubRoutinecpp">trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitPolymorphicCallStubRoutineh">trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeProfilecpp">trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeProfileh">trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeProfileInlinesh">trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitClosureCallStubRoutinecpp">trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitClosureCallStubRoutineh">trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkMakefileshared"></a>
<div class="modfile"><h4>Modified: trunk/Makefile.shared (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Makefile.shared        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Makefile.shared        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -12,6 +12,8 @@
</span><span class="cx">         XCODE_OPTIONS += ONLY_ACTIVE_ARCH=NO
</span><span class="cx"> endif
</span><span class="cx"> 
</span><ins>+XCODE_OPTIONS += TOOLCHAINS=com.apple.dt.toolchain.OSX10_11
+
</ins><span class="cx"> DEFAULT_VERBOSITY := $(shell defaults read org.webkit.BuildConfiguration BuildTranscriptVerbosity 2&gt;/dev/null || echo &quot;default&quot;)
</span><span class="cx"> VERBOSITY ?= $(DEFAULT_VERBOSITY)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -66,7 +66,6 @@
</span><span class="cx">     bytecode/BytecodeBasicBlock.cpp
</span><span class="cx">     bytecode/BytecodeLivenessAnalysis.cpp
</span><span class="cx">     bytecode/CallEdge.cpp
</span><del>-    bytecode/CallEdgeProfile.cpp
</del><span class="cx">     bytecode/CallLinkInfo.cpp
</span><span class="cx">     bytecode/CallLinkStatus.cpp
</span><span class="cx">     bytecode/CallVariant.cpp
</span><span class="lines">@@ -327,7 +326,6 @@
</span><span class="cx">     jit/AssemblyHelpers.cpp
</span><span class="cx">     jit/ArityCheckFailReturnThunks.cpp
</span><span class="cx">     jit/BinarySwitch.cpp
</span><del>-    jit/ClosureCallStubRoutine.cpp
</del><span class="cx">     jit/ExecutableAllocator.cpp
</span><span class="cx">     jit/ExecutableAllocatorFixedVMPool.cpp
</span><span class="cx">     jit/GCAwareJITStubRoutine.cpp
</span><span class="lines">@@ -350,6 +348,7 @@
</span><span class="cx">     jit/JITStubs.cpp
</span><span class="cx">     jit/JITThunks.cpp
</span><span class="cx">     jit/JITToDFGDeferredCompilationCallback.cpp
</span><ins>+    jit/PolymorphicCallStubRoutine.cpp
</ins><span class="cx">     jit/Reg.cpp
</span><span class="cx">     jit/RegisterPreservationWrapperGenerator.cpp
</span><span class="cx">     jit/RegisterSet.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,3 +1,168 @@
</span><ins>+2015-01-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Polymorphic call inlining should be based on polymorphic call inline caching rather than logging
+        https://bugs.webkit.org/show_bug.cgi?id=140660
+
+        Reviewed by Geoffrey Garen.
+        
+        When we first implemented polymorphic call inlining, we did the profiling based on a call
+        edge log. The idea was to store each call edge (a tuple of call site and callee) into a
+        global log that was processed lazily. Processing the log would give precise counts of call
+        edges, and could be used to drive well-informed inlining decisions - polymorphic or not.
+        This was a speed-up on throughput tests but a slow-down for latency tests. It was a net win
+        nonetheless.
+        
+        Experience with this code shows three things. First, the call edge profiler is buggy and
+        complex. It would take work to fix the bugs. Second, the call edge profiler incurs lots of
+        overhead for latency code that we care deeply about. Third, it's not at all clear that
+        having call edge counts for every possible callee is any better than just having call edge
+        counts for the limited number of callees that an inline cache would catch.
+        
+        So, this patch removes the call edge profiler and replaces it with a polymorphic call inline
+        cache. If we miss the basic call inline cache, we inflate the cache to be a jump to an
+        out-of-line stub that cases on the previously known callees. If that misses again, then we
+        rewrite that stub to include the new callee. We do this up to some number of callees. If we
+        hit the limit then we switch to using a plain virtual call.
+        
+        Substantial speed-up on V8Spider; undoes the slow-down that the original call edge profiler
+        caused. Might be a SunSpider speed-up (below 1%), depending on hardware.
+        
+        Rolling this back in after fixing https://bugs.webkit.org/show_bug.cgi?id=141107.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallEdge.h:
+        (JSC::CallEdge::count):
+        (JSC::CallEdge::CallEdge):
+        * bytecode/CallEdgeProfile.cpp: Removed.
+        * bytecode/CallEdgeProfile.h: Removed.
+        * bytecode/CallEdgeProfileInlines.h: Removed.
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::unlink):
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkInfo.h:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::isClosureCall):
+        (JSC::CallLinkStatus::makeClosureCall):
+        (JSC::CallLinkStatus::dump):
+        (JSC::CallLinkStatus::computeFromCallEdgeProfile): Deleted.
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::isSet):
+        (JSC::CallLinkStatus::variants):
+        (JSC::CallLinkStatus::size):
+        (JSC::CallLinkStatus::at):
+        (JSC::CallLinkStatus::operator[]):
+        (JSC::CallLinkStatus::canOptimize):
+        (JSC::CallLinkStatus::edges): Deleted.
+        (JSC::CallLinkStatus::canTrustCounts): Deleted.
+        * bytecode/CallVariant.cpp:
+        (JSC::variantListWithVariant):
+        (JSC::despecifiedVariantList):
+        * bytecode/CallVariant.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::~CodeBlock):
+        (JSC::CodeBlock::linkIncomingPolymorphicCall):
+        (JSC::CodeBlock::unlinkIncomingCalls):
+        (JSC::CodeBlock::noticeIncomingCall):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::isIncomingCallAlreadyLinked): Deleted.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        (JSC::DFG::TierUpCheckInjectionPhase::removeFTLProfiling): Deleted.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * jit/BinarySwitch.h:
+        * jit/ClosureCallStubRoutine.cpp: Removed.
+        * jit/ClosureCallStubRoutine.h: Removed.
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        (JSC::operationLinkPolymorphicCallFor):
+        (JSC::operationLinkClosureCallFor): Deleted.
+        * jit/JITStubRoutine.h:
+        * jit/JITWriteBarrier.h:
+        * jit/PolymorphicCallStubRoutine.cpp: Added.
+        (JSC::PolymorphicCallNode::~PolymorphicCallNode):
+        (JSC::PolymorphicCallNode::unlink):
+        (JSC::PolymorphicCallCase::dump):
+        (JSC::PolymorphicCallStubRoutine::PolymorphicCallStubRoutine):
+        (JSC::PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine):
+        (JSC::PolymorphicCallStubRoutine::variants):
+        (JSC::PolymorphicCallStubRoutine::edges):
+        (JSC::PolymorphicCallStubRoutine::visitWeak):
+        (JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternal):
+        * jit/PolymorphicCallStubRoutine.h: Added.
+        (JSC::PolymorphicCallNode::PolymorphicCallNode):
+        (JSC::PolymorphicCallCase::PolymorphicCallCase):
+        (JSC::PolymorphicCallCase::variant):
+        (JSC::PolymorphicCallCase::codeBlock):
+        * jit/Repatch.cpp:
+        (JSC::linkSlowFor):
+        (JSC::linkFor):
+        (JSC::revertCall):
+        (JSC::unlinkFor):
+        (JSC::linkVirtualFor):
+        (JSC::linkPolymorphicCall):
+        (JSC::linkClosureCall): Deleted.
+        * jit/Repatch.h:
+        * jit/ThunkGenerators.cpp:
+        (JSC::linkPolymorphicCallForThunkGenerator):
+        (JSC::linkPolymorphicCallThunkGenerator):
+        (JSC::linkPolymorphicCallThatPreservesRegsThunkGenerator):
+        (JSC::linkClosureCallForThunkGenerator): Deleted.
+        (JSC::linkClosureCallThunkGenerator): Deleted.
+        (JSC::linkClosureCallThatPreservesRegsThunkGenerator): Deleted.
+        * jit/ThunkGenerators.h:
+        (JSC::linkPolymorphicCallThunkGeneratorFor):
+        (JSC::linkClosureCallThunkGeneratorFor): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::jitCompileAndSetHeuristics):
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::prepareToDiscardCode):
+        (JSC::VM::ensureCallEdgeLog): Deleted.
+        * runtime/VM.h:
+
</ins><span class="cx"> 2015-01-30  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Converting Flushes and PhantomLocals to Phantoms requires an OSR availability analysis rather than just using the SetLocal's child
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -314,7 +314,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\BytecodeBasicBlock.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\BytecodeLivenessAnalysis.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CallEdge.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\bytecode\CallEdgeProfile.cpp&quot; /&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CallLinkInfo.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CallLinkStatus.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\CallVariant.cpp&quot; /&gt;
</span><span class="lines">@@ -598,7 +597,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\ArityCheckFailReturnThunks.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\AssemblyHelpers.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\BinarySwitch.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\jit\ClosureCallStubRoutine.cpp&quot; /&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\jit\ExecutableAllocator.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\GCAwareJITStubRoutine.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\HostCallReturnValue.cpp&quot; /&gt;
</span><span class="lines">@@ -621,6 +619,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\JITStubs.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\JITThunks.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\JITToDFGDeferredCompilationCallback.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\jit\PolymorphicCallStubRoutine.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\jit\Reg.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\RegisterPreservationWrapperGenerator.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\RegisterSet.cpp&quot; /&gt;
</span><span class="lines">@@ -932,8 +931,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\BytecodeLivenessAnalysis.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\BytecodeUseDef.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\CallEdge.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\bytecode\CallEdgeProfile.h&quot; /&gt;
-    &lt;ClInclude Include=&quot;..\bytecode\CallEdgeProfileInlines.h&quot; /&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\CallLinkInfo.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\CallLinkStatus.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\CallReturnOffsetToBytecodeOffset.h&quot; /&gt;
</span><span class="lines">@@ -1334,7 +1331,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\AssemblyHelpers.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\BinarySwitch.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\CCallHelpers.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\jit\ClosureCallStubRoutine.h&quot; /&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\jit\CompactJITCodeMap.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\ExecutableAllocator.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\FPRInfo.h&quot; /&gt;
</span><span class="lines">@@ -1358,6 +1354,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\JITToDFGDeferredCompilationCallback.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\JITWriteBarrier.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\JSInterfaceJIT.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\jit\PolymorphicCallStubRoutine.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\jit\Reg.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterPreservationWrapperGenerator.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\RegisterSet.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -281,13 +281,8 @@
</span><span class="cx">                 0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */; };
</span><span class="cx">                 0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F3B7E2619A11B8000D9BC56 /* CallEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2019A11B8000D9BC56 /* CallEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F3B7E2719A11B8000D9BC56 /* CallEdgeProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2119A11B8000D9BC56 /* CallEdgeProfile.cpp */; };
-                0F3B7E2819A11B8000D9BC56 /* CallEdgeProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2219A11B8000D9BC56 /* CallEdgeProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F3B7E2919A11B8000D9BC56 /* CallEdgeProfileInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2319A11B8000D9BC56 /* CallEdgeProfileInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */; };
</span><span class="cx">                 0F3B7E2B19A11B8000D9BC56 /* CallVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2519A11B8000D9BC56 /* CallVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F3B7E2D19A12AAE00D9BC56 /* CallEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */; };
</del><span class="cx">                 0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */; };
</span><span class="cx">                 0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */; };
</span><span class="lines">@@ -355,6 +350,8 @@
</span><span class="cx">                 0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63948215E48114006A597C /* DFGArrayMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */; };
</span><span class="cx">                 0F64B2721A784BAF006E4E66 /* BinarySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2701A784BAF006E4E66 /* BinarySwitch.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F64B2771A7957B2006E4E66 /* CallEdge.cpp */; };
+                0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2781A7957B2006E4E66 /* CallEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */; };
</span><span class="lines">@@ -386,8 +383,6 @@
</span><span class="cx">                 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
</span><span class="cx">                 0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */; };
-                0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A201651C66100A80AFE /* ARM64Disassembler.cpp */; };
</span><span class="cx">                 0F7576D218E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */; };
</span><span class="cx">                 0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -602,6 +597,8 @@
</span><span class="cx">                 0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
</span><span class="cx">                 0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE7211B193B9C590031F6ED /* DFGTransition.cpp */; };
</span><span class="cx">                 0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE7211C193B9C590031F6ED /* DFGTransition.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FE834171A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */; };
+                0FE834181A6EF97B00D04847 /* PolymorphicCallStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */; };
</span><span class="cx">                 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FE95F7918B5694700B531FB /* FTLDataSection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE95F7718B5694700B531FB /* FTLDataSection.cpp */; };
</span><span class="lines">@@ -1952,13 +1949,8 @@
</span><span class="cx">                 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFGSimplificationPhase.h; path = dfg/DFGCFGSimplificationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValidate.cpp; path = dfg/DFGValidate.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValidate.h; path = dfg/DFGValidate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F3B7E2019A11B8000D9BC56 /* CallEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdge.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F3B7E2119A11B8000D9BC56 /* CallEdgeProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdgeProfile.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F3B7E2219A11B8000D9BC56 /* CallEdgeProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdgeProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F3B7E2319A11B8000D9BC56 /* CallEdgeProfileInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdgeProfileInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallVariant.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3B7E2519A11B8000D9BC56 /* CallVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallVariant.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdge.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantStructureCheck.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantStructureCheck.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPrePostNumbering.cpp; path = dfg/DFGPrePostNumbering.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2027,6 +2019,8 @@
</span><span class="cx">                 0F63948215E48114006A597C /* DFGArrayMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayMode.h; path = dfg/DFGArrayMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BinarySwitch.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F64B2701A784BAF006E4E66 /* BinarySwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BinarySwitch.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F64B2771A7957B2006E4E66 /* CallEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdge.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F64B2781A7957B2006E4E66 /* CallEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdge.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysisInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullBytecodeLiveness.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailability.cpp; path = dfg/DFGAvailability.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2058,8 +2052,6 @@
</span><span class="cx">                 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilerCommon.h; path = dfg/DFGOSRExitCompilerCommon.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBackwardsPropagationPhase.h; path = dfg/DFGBackwardsPropagationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClosureCallStubRoutine.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClosureCallStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessorCallJITStubRoutine.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessorCallJITStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2286,6 +2278,8 @@
</span><span class="cx">                 0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE7211B193B9C590031F6ED /* DFGTransition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTransition.cpp; path = dfg/DFGTransition.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE7211C193B9C590031F6ED /* DFGTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTransition.h; path = dfg/DFGTransition.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicCallStubRoutine.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicCallStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredWatchpoints.cpp; path = dfg/DFGDesiredWatchpoints.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredWatchpoints.h; path = dfg/DFGDesiredWatchpoints.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE95F7718B5694700B531FB /* FTLDataSection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLDataSection.cpp; path = ftl/FTLDataSection.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3751,8 +3745,6 @@
</span><span class="cx">                                 0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */,
</span><span class="cx">                                 0F64B2701A784BAF006E4E66 /* BinarySwitch.h */,
</span><span class="cx">                                 0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */,
</span><del>-                                0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */,
-                                0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */,
</del><span class="cx">                                 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
</span><span class="cx">                                 A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
</span><span class="cx">                                 A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
</span><span class="lines">@@ -3800,6 +3792,8 @@
</span><span class="cx">                                 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
</span><span class="cx">                                 A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
</span><span class="cx">                                 A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
</span><ins>+                                0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */,
+                                0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */,
</ins><span class="cx">                                 0FA7A8E918B413C80052371D /* Reg.cpp */,
</span><span class="cx">                                 0FA7A8EA18B413C80052371D /* Reg.h */,
</span><span class="cx">                                 0F6B1CBB1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp */,
</span><span class="lines">@@ -5033,11 +5027,8 @@
</span><span class="cx">                                 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */,
</span><span class="cx">                                 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */,
</span><span class="cx">                                 0F8023E91613832300A0BA45 /* ByValInfo.h */,
</span><del>-                                0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */,
-                                0F3B7E2019A11B8000D9BC56 /* CallEdge.h */,
-                                0F3B7E2119A11B8000D9BC56 /* CallEdgeProfile.cpp */,
-                                0F3B7E2219A11B8000D9BC56 /* CallEdgeProfile.h */,
-                                0F3B7E2319A11B8000D9BC56 /* CallEdgeProfileInlines.h */,
</del><ins>+                                0F64B2771A7957B2006E4E66 /* CallEdge.cpp */,
+                                0F64B2781A7957B2006E4E66 /* CallEdge.h */,
</ins><span class="cx">                                 0F0B83AE14BCF71400885B4F /* CallLinkInfo.cpp */,
</span><span class="cx">                                 0F0B83AF14BCF71400885B4F /* CallLinkInfo.h */,
</span><span class="cx">                                 0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
</span><span class="lines">@@ -5489,7 +5480,6 @@
</span><span class="cx">                                 0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
</span><span class="cx">                                 0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */,
</span><span class="cx">                                 BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
</span><del>-                                0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
</del><span class="cx">                                 969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
</span><span class="cx">                                 0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
</span><span class="cx">                                 0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */,
</span><span class="lines">@@ -5533,6 +5523,7 @@
</span><span class="cx">                                 BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
</span><span class="cx">                                 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
</span><span class="cx">                                 BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
</span><ins>+                                0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */,
</ins><span class="cx">                                 14A1563210966365006FA260 /* DateInstanceCache.h in Headers */,
</span><span class="cx">                                 BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */,
</span><span class="cx">                                 BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
</span><span class="lines">@@ -5580,7 +5571,6 @@
</span><span class="cx">                                 0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
</span><span class="cx">                                 0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */,
</span><span class="cx">                                 0F8F2B9A172F0501007DBDA5 /* DFGDesiredIdentifiers.h in Headers */,
</span><del>-                                0F3B7E2819A11B8000D9BC56 /* CallEdgeProfile.h in Headers */,
</del><span class="cx">                                 C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */,
</span><span class="cx">                                 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */,
</span><span class="cx">                                 C2981FD917BAEE4B00A3BC98 /* DFGDesiredWeakReferences.h in Headers */,
</span><span class="lines">@@ -5871,7 +5861,6 @@
</span><span class="cx">                                 A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */,
</span><span class="cx">                                 BC18C4160E16F5CD00B34460 /* JSLexicalEnvironment.h in Headers */,
</span><span class="cx">                                 840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */,
</span><del>-                                0F3B7E2919A11B8000D9BC56 /* CallEdgeProfileInlines.h in Headers */,
</del><span class="cx">                                 C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */,
</span><span class="cx">                                 A76140D2182982CB00750624 /* JSArgumentsIterator.h in Headers */,
</span><span class="cx">                                 BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
</span><span class="lines">@@ -6192,7 +6181,6 @@
</span><span class="cx">                                 E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
</span><span class="cx">                                 E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */,
</span><span class="cx">                                 0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */,
</span><del>-                                0F3B7E2619A11B8000D9BC56 /* CallEdge.h in Headers */,
</del><span class="cx">                                 A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */,
</span><span class="cx">                                 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */,
</span><span class="cx">                                 0FD82E54141DAEEE00179C94 /* SpeculatedType.h in Headers */,
</span><span class="lines">@@ -6243,6 +6231,7 @@
</span><span class="cx">                                 0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
</span><span class="cx">                                 A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */,
</span><span class="cx">                                 A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */,
</span><ins>+                                0FE834181A6EF97B00D04847 /* PolymorphicCallStubRoutine.h in Headers */,
</ins><span class="cx">                                 866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */,
</span><span class="cx">                                 A7A8AF4217ADB5F3005AB174 /* Uint32Array.h in Headers */,
</span><span class="cx">                                 A7A8AF3F17ADB5F3005AB174 /* Uint8Array.h in Headers */,
</span><span class="lines">@@ -6781,7 +6770,6 @@
</span><span class="cx">                                 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
</span><span class="cx">                                 0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
</span><span class="cx">                                 0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */,
</span><del>-                                0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
</del><span class="cx">                                 969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
</span><span class="cx">                                 0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
</span><span class="cx">                                 0FC97F33182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp in Sources */,
</span><span class="lines">@@ -6796,6 +6784,7 @@
</span><span class="cx">                                 0F9C5E5E18E35F5E00D431C3 /* FTLDWARFRegister.cpp in Sources */,
</span><span class="cx">                                 A709F2F217A0AC2A00512E98 /* CommonSlowPaths.cpp in Sources */,
</span><span class="cx">                                 6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */,
</span><ins>+                                0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */,
</ins><span class="cx">                                 A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
</span><span class="cx">                                 147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
</span><span class="cx">                                 146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
</span><span class="lines">@@ -6967,8 +6956,8 @@
</span><span class="cx">                                 0F235BD517178E1C00690C7F /* FTLExitArgumentForOperand.cpp in Sources */,
</span><span class="cx">                                 0F235BD817178E1C00690C7F /* FTLExitThunkGenerator.cpp in Sources */,
</span><span class="cx">                                 0F235BDA17178E1C00690C7F /* FTLExitValue.cpp in Sources */,
</span><del>-                                0F3B7E2719A11B8000D9BC56 /* CallEdgeProfile.cpp in Sources */,
</del><span class="cx">                                 A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */,
</span><ins>+                                0FE834171A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp in Sources */,
</ins><span class="cx">                                 0FD8A31917D51F2200CA2C40 /* FTLForOSREntryJITCode.cpp in Sources */,
</span><span class="cx">                                 0F25F1AF181635F300522F39 /* FTLInlineCacheSize.cpp in Sources */,
</span><span class="cx">                                 0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
</span><span class="lines">@@ -7160,7 +7149,6 @@
</span><span class="cx">                                 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
</span><span class="cx">                                 0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */,
</span><span class="cx">                                 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
</span><del>-                                0F3B7E2D19A12AAE00D9BC56 /* CallEdge.cpp in Sources */,
</del><span class="cx">                                 0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
</span><span class="cx">                                 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
</span><span class="cx">                                 0FCEFACD1805E75500472CE4 /* LLVMAPI.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallEdge.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdge.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdge.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,17 +30,15 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-typedef uint16_t CallEdgeCountType;
-
</del><span class="cx"> class CallEdge {
</span><span class="cx"> public:
</span><span class="cx">     CallEdge();
</span><del>-    CallEdge(CallVariant, CallEdgeCountType);
</del><ins>+    CallEdge(CallVariant, uint32_t);
</ins><span class="cx">     
</span><span class="cx">     bool operator!() const { return !m_callee; }
</span><span class="cx">     
</span><span class="cx">     CallVariant callee() const { return m_callee; }
</span><del>-    CallEdgeCountType count() const { return m_count; }
</del><ins>+    uint32_t count() const { return m_count; }
</ins><span class="cx">     
</span><span class="cx">     CallEdge despecifiedClosure() const
</span><span class="cx">     {
</span><span class="lines">@@ -49,12 +47,12 @@
</span><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     
</span><del>-public:
</del><ins>+private:
</ins><span class="cx">     CallVariant m_callee;
</span><del>-    CallEdgeCountType m_count;
</del><ins>+    uint32_t m_count;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline CallEdge::CallEdge(CallVariant callee, CallEdgeCountType count)
</del><ins>+inline CallEdge::CallEdge(CallVariant callee, uint32_t count)
</ins><span class="cx">     : m_callee(callee)
</span><span class="cx">     , m_count(count)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeProfilecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,360 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include &quot;config.h&quot;
-#include &quot;CallEdgeProfile.h&quot;
-
-#include &quot;CCallHelpers.h&quot;
-#include &quot;CallEdgeProfileInlines.h&quot;
-#include &quot;JITOperations.h&quot;
-#include &quot;JSCInlines.h&quot;
-
-namespace JSC {
-
-CallEdgeList CallEdgeProfile::callEdges() const
-{
-    ConcurrentJITLocker locker(m_lock);
-    
-    CallEdgeList result;
-    
-    CallVariant primaryCallee = m_primaryCallee;
-    CallEdgeCountType numCallsToPrimary = m_numCallsToPrimary;
-    // Defend against races. These fields are modified by the log processor without locking.
-    if (!!primaryCallee &amp;&amp; numCallsToPrimary)
-        result.append(CallEdge(primaryCallee, numCallsToPrimary));
-    
-    if (m_otherCallees) {
-        // Make sure that if the primary thread had just created a m_otherCalles while log
-        // processing, we see a consistently created one. The lock being held is insufficient for
-        // this, since the log processor will only grab the lock when merging the secondary
-        // spectrum into the primary one but may still create the data structure without holding
-        // locks.
-        WTF::loadLoadFence();
-        for (CallEdge&amp; entry : m_otherCallees-&gt;m_processed) {
-            // Defend against the possibility that the primary duplicates an entry in the secondary
-            // spectrum. That can happen when the GC removes the primary. We could have the GC fix
-            // the situation by changing the primary to be something from the secondary spectrum,
-            // but this fix seems simpler to implement and also cheaper.
-            if (entry.callee() == result[0].callee()) {
-                result[0] = CallEdge(result[0].callee(), entry.count() + result[0].count());
-                continue;
-            }
-            
-            result.append(entry);
-        }
-    }
-    
-    std::sort(result.begin(), result.end(), [] (const CallEdge&amp; a, const CallEdge&amp; b) -&gt; bool {
-            return a.count() &gt; b.count();
-        });
-    
-    if (result.size() &gt;= 2)
-        ASSERT(result[0].count() &gt;= result.last().count());
-    
-    return result;
-}
-
-CallEdgeCountType CallEdgeProfile::numCallsToKnownCells() const
-{
-    CallEdgeCountType result = 0;
-    for (CallEdge&amp; edge : callEdges())
-        result += edge.count();
-    return result;
-}
-
-static bool worthDespecifying(const CallVariant&amp; variant)
-{
-    return !Heap::isMarked(variant.rawCalleeCell())
-        &amp;&amp; Heap::isMarked(variant.despecifiedClosure().rawCalleeCell());
-}
-
-bool CallEdgeProfile::worthDespecifying()
-{
-    if (m_closuresAreDespecified)
-        return false;
-    
-    bool didSeeEntry = false;
-    
-    if (!!m_primaryCallee) {
-        didSeeEntry = true;
-        if (!JSC::worthDespecifying(m_primaryCallee))
-            return false;
-    }
-    
-    if (m_otherCallees) {
-        for (unsigned i = m_otherCallees-&gt;m_processed.size(); i--;) {
-            didSeeEntry = true;
-            if (!JSC::worthDespecifying(m_otherCallees-&gt;m_processed[i].callee()))
-                return false;
-        }
-    }
-    
-    return didSeeEntry;
-}
-
-void CallEdgeProfile::visitWeak()
-{
-    if (!m_primaryCallee &amp;&amp; !m_otherCallees)
-        return;
-    
-    ConcurrentJITLocker locker(m_lock);
-    
-    // See if anything is dead and if that can be rectified by despecifying.
-    if (worthDespecifying()) {
-        CallSpectrum newSpectrum;
-        
-        if (!!m_primaryCallee)
-            newSpectrum.add(m_primaryCallee.despecifiedClosure(), m_numCallsToPrimary);
-        
-        if (m_otherCallees) {
-            for (unsigned i = m_otherCallees-&gt;m_processed.size(); i--;) {
-                newSpectrum.add(
-                    m_otherCallees-&gt;m_processed[i].callee().despecifiedClosure(),
-                    m_otherCallees-&gt;m_processed[i].count());
-            }
-        }
-        
-        Vector&lt;CallSpectrum::KeyAndCount&gt; list = newSpectrum.buildList();
-        RELEASE_ASSERT(list.size());
-        m_primaryCallee = list.last().key;
-        m_numCallsToPrimary = list.last().count;
-        
-        if (m_otherCallees) {
-            m_otherCallees-&gt;m_processed.clear();
-
-            // We could have a situation where the GC clears the primary and then log processing
-            // reinstates it without ever doing an addSlow and subsequent mergeBack. In such a case
-            // the primary could duplicate an entry in otherCallees, which means that even though we
-            // had an otherCallees object, the list size is just 1.
-            if (list.size() &gt;= 2) {
-                for (unsigned i = list.size() - 1; i--;)
-                    m_otherCallees-&gt;m_processed.append(CallEdge(list[i].key, list[i].count));
-            }
-        }
-        
-        m_closuresAreDespecified = true;
-        
-        return;
-    }
-    
-    if (!!m_primaryCallee &amp;&amp; !Heap::isMarked(m_primaryCallee.rawCalleeCell())) {
-        m_numCallsToUnknownCell += m_numCallsToPrimary;
-        
-        m_primaryCallee = CallVariant();
-        m_numCallsToPrimary = 0;
-    }
-    
-    if (m_otherCallees) {
-        for (unsigned i = 0; i &lt; m_otherCallees-&gt;m_processed.size(); i++) {
-            if (Heap::isMarked(m_otherCallees-&gt;m_processed[i].callee().rawCalleeCell()))
-                continue;
-            
-            m_numCallsToUnknownCell += m_otherCallees-&gt;m_processed[i].count();
-            m_otherCallees-&gt;m_processed[i--] = m_otherCallees-&gt;m_processed.last();
-            m_otherCallees-&gt;m_processed.removeLast();
-        }
-        
-        // Only exists while we are processing the log.
-        RELEASE_ASSERT(!m_otherCallees-&gt;m_temporarySpectrum);
-    }
-}
-
-void CallEdgeProfile::addSlow(CallVariant callee, CallEdgeProfileVector&amp; mergeBackLog)
-{
-    // This exists to handle cases where the spectrum wasn't created yet, or we're storing to a
-    // particular spectrum for the first time during a log processing iteration.
-    
-    if (!m_otherCallees) {
-        m_otherCallees = std::make_unique&lt;Secondary&gt;();
-        // If a compiler thread notices the m_otherCallees being non-null, we want to make sure
-        // that it sees a fully created one.
-        WTF::storeStoreFence();
-    }
-    
-    if (!m_otherCallees-&gt;m_temporarySpectrum) {
-        m_otherCallees-&gt;m_temporarySpectrum = std::make_unique&lt;CallSpectrum&gt;();
-        for (unsigned i = m_otherCallees-&gt;m_processed.size(); i--;) {
-            m_otherCallees-&gt;m_temporarySpectrum-&gt;add(
-                m_otherCallees-&gt;m_processed[i].callee(),
-                m_otherCallees-&gt;m_processed[i].count());
-        }
-        
-        // This means that this is the first time we're seeing this profile during this log
-        // processing iteration.
-        mergeBackLog.append(this);
-    }
-    
-    m_otherCallees-&gt;m_temporarySpectrum-&gt;add(callee);
-}
-
-void CallEdgeProfile::mergeBack()
-{
-    ConcurrentJITLocker locker(m_lock);
-    
-    RELEASE_ASSERT(m_otherCallees);
-    RELEASE_ASSERT(m_otherCallees-&gt;m_temporarySpectrum);
-    
-    if (!!m_primaryCallee)
-        m_otherCallees-&gt;m_temporarySpectrum-&gt;add(m_primaryCallee, m_numCallsToPrimary);
-    
-    if (!m_closuresAreDespecified) {
-        CallSpectrum newSpectrum;
-        for (auto&amp; entry : *m_otherCallees-&gt;m_temporarySpectrum)
-            newSpectrum.add(entry.key.despecifiedClosure(), entry.value);
-        
-        if (newSpectrum.size() &lt; m_otherCallees-&gt;m_temporarySpectrum-&gt;size()) {
-            *m_otherCallees-&gt;m_temporarySpectrum = newSpectrum;
-            m_closuresAreDespecified = true;
-        }
-    }
-    
-    Vector&lt;CallSpectrum::KeyAndCount&gt; list = m_otherCallees-&gt;m_temporarySpectrum-&gt;buildList();
-    m_otherCallees-&gt;m_temporarySpectrum = nullptr;
-    
-    m_primaryCallee = list.last().key;
-    m_numCallsToPrimary = list.last().count;
-    list.removeLast();
-    
-    m_otherCallees-&gt;m_processed.clear();
-    for (unsigned count = maxKnownCallees; count-- &amp;&amp; !list.isEmpty();) {
-        m_otherCallees-&gt;m_processed.append(CallEdge(list.last().key, list.last().count));
-        list.removeLast();
-    }
-    
-    for (unsigned i = list.size(); i--;)
-        m_numCallsToUnknownCell += list[i].count;
-}
-
-void CallEdgeProfile::fadeByHalf()
-{
-    m_numCallsToPrimary &gt;&gt;= 1;
-    m_numCallsToNotCell &gt;&gt;= 1;
-    m_numCallsToUnknownCell &gt;&gt;= 1;
-    m_totalCount &gt;&gt;= 1;
-    
-    if (m_otherCallees) {
-        for (unsigned i = m_otherCallees-&gt;m_processed.size(); i--;) {
-            m_otherCallees-&gt;m_processed[i] = CallEdge(
-                m_otherCallees-&gt;m_processed[i].callee(),
-                m_otherCallees-&gt;m_processed[i].count() &gt;&gt; 1);
-        }
-        
-        if (m_otherCallees-&gt;m_temporarySpectrum) {
-            for (auto&amp; entry : *m_otherCallees-&gt;m_temporarySpectrum)
-                entry.value &gt;&gt;= 1;
-        }
-    }
-}
-
-CallEdgeLog::CallEdgeLog()
-    : m_scaledLogIndex(logSize * sizeof(Entry))
-{
-    ASSERT(!(m_scaledLogIndex % sizeof(Entry)));
-}
-
-CallEdgeLog::~CallEdgeLog() { }
-
-bool CallEdgeLog::isEnabled()
-{
-    return Options::enableCallEdgeProfiling() &amp;&amp; Options::useFTLJIT();
-}
-
-#if ENABLE(JIT)
-
-extern &quot;C&quot; JIT_OPERATION void operationProcessCallEdgeLog(CallEdgeLog*) WTF_INTERNAL;
-extern &quot;C&quot; JIT_OPERATION void operationProcessCallEdgeLog(CallEdgeLog* log)
-{
-    log-&gt;processLog();
-}
-
-void CallEdgeLog::emitLogCode(CCallHelpers&amp; jit, CallEdgeProfile&amp; profile, JSValueRegs calleeRegs)
-{
-    const unsigned numberOfArguments = 1;
-    
-    GPRReg scratchGPR;
-    if (!calleeRegs.uses(GPRInfo::regT0))
-        scratchGPR = GPRInfo::regT0;
-    else if (!calleeRegs.uses(GPRInfo::regT1))
-        scratchGPR = GPRInfo::regT1;
-    else
-        scratchGPR = GPRInfo::regT2;
-    
-    jit.load32(&amp;m_scaledLogIndex, scratchGPR);
-    
-    CCallHelpers::Jump ok = jit.branchTest32(CCallHelpers::NonZero, scratchGPR);
-    
-    ASSERT_UNUSED(numberOfArguments, stackAlignmentRegisters() &gt;= 1 + numberOfArguments);
-    
-    jit.subPtr(CCallHelpers::TrustedImm32(stackAlignmentBytes()), CCallHelpers::stackPointerRegister);
-    
-    jit.storeValue(calleeRegs, CCallHelpers::Address(CCallHelpers::stackPointerRegister, sizeof(JSValue)));
-    jit.setupArguments(CCallHelpers::TrustedImmPtr(this));
-    jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast&lt;void*&gt;(operationProcessCallEdgeLog)), GPRInfo::nonArgGPR0);
-    jit.call(GPRInfo::nonArgGPR0);
-    jit.loadValue(CCallHelpers::Address(CCallHelpers::stackPointerRegister, sizeof(JSValue)), calleeRegs);
-    
-    jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentBytes()), CCallHelpers::stackPointerRegister);
-    
-    jit.move(CCallHelpers::TrustedImm32(logSize * sizeof(Entry)), scratchGPR);
-    ok.link(&amp;jit);
-
-    jit.sub32(CCallHelpers::TrustedImm32(sizeof(Entry)), scratchGPR);
-    jit.store32(scratchGPR, &amp;m_scaledLogIndex);
-    jit.addPtr(CCallHelpers::TrustedImmPtr(m_log), scratchGPR);
-    jit.storeValue(calleeRegs, CCallHelpers::Address(scratchGPR, OBJECT_OFFSETOF(Entry, m_value)));
-    jit.storePtr(CCallHelpers::TrustedImmPtr(&amp;profile), CCallHelpers::Address(scratchGPR, OBJECT_OFFSETOF(Entry, m_profile)));
-}
-
-void CallEdgeLog::emitLogCode(
-    CCallHelpers&amp; jit, OwnPtr&lt;CallEdgeProfile&gt;&amp; profilePointer, JSValueRegs calleeRegs)
-{
-    if (!isEnabled())
-        return;
-    
-    profilePointer.createTransactionally();
-    emitLogCode(jit, *profilePointer, calleeRegs);
-}
-
-#endif // ENABLE(JIT)
-
-void CallEdgeLog::processLog()
-{
-    ASSERT(!(m_scaledLogIndex % sizeof(Entry)));
-    
-    if (Options::callEdgeProfileReallyProcessesLog()) {
-        CallEdgeProfileVector mergeBackLog;
-        
-        for (unsigned i = m_scaledLogIndex / sizeof(Entry); i &lt; logSize; ++i)
-            m_log[i].m_profile-&gt;add(m_log[i].m_value, mergeBackLog);
-        
-        for (unsigned i = mergeBackLog.size(); i--;)
-            mergeBackLog[i]-&gt;mergeBack();
-    }
-    
-    m_scaledLogIndex = logSize * sizeof(Entry);
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeProfileh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,131 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef CallEdgeProfile_h
-#define CallEdgeProfile_h
-
-#include &quot;CallEdge.h&quot;
-#include &quot;CallVariant.h&quot;
-#include &quot;ConcurrentJITLock.h&quot;
-#include &quot;GPRInfo.h&quot;
-#include &quot;JSCell.h&quot;
-#include &lt;wtf/OwnPtr.h&gt;
-
-namespace JSC {
-
-class CCallHelpers;
-class LLIntOffsetsExtractor;
-
-class CallEdgeLog;
-class CallEdgeProfile;
-typedef Vector&lt;CallEdgeProfile*, 10&gt; CallEdgeProfileVector;
-
-class CallEdgeProfile {
-public:
-    CallEdgeProfile();
-    
-    CallEdgeCountType numCallsToNotCell() const { return m_numCallsToNotCell; }
-    CallEdgeCountType numCallsToUnknownCell() const { return m_numCallsToUnknownCell; }
-    CallEdgeCountType numCallsToKnownCells() const;
-    
-    CallEdgeCountType totalCalls() const { return m_totalCount; }
-    
-    // Call while holding the owning CodeBlock's lock.
-    CallEdgeList callEdges() const;
-    
-    void visitWeak();
-    
-private:
-    friend class CallEdgeLog;
-    
-    static const unsigned maxKnownCallees = 5;
-    
-    void add(JSValue, CallEdgeProfileVector&amp; mergeBackLog);
-    
-    bool worthDespecifying();
-    void addSlow(CallVariant, CallEdgeProfileVector&amp; mergeBackLog);
-    void mergeBack();
-    void fadeByHalf();
-    
-    // It's cheaper to let this have its own lock. It needs to be able to find which lock to
-    // lock. Normally it would lock the owning CodeBlock's lock, but that would require a
-    // pointer-width word to point at the CodeBlock. Having the byte-sized lock here is
-    // cheaper. However, this means that the relationship with the CodeBlock lock is:
-    // acquire the CodeBlock lock before this one.
-    mutable ConcurrentJITLock m_lock;
-    
-    bool m_closuresAreDespecified;
-    
-    CallEdgeCountType m_numCallsToPrimary;
-    CallEdgeCountType m_numCallsToNotCell;
-    CallEdgeCountType m_numCallsToUnknownCell;
-    CallEdgeCountType m_totalCount;
-    CallVariant m_primaryCallee;
-    
-    typedef Spectrum&lt;CallVariant, CallEdgeCountType&gt; CallSpectrum;
-    
-    struct Secondary {
-        Vector&lt;CallEdge&gt; m_processed; // Processed but not necessarily sorted.
-        std::unique_ptr&lt;CallSpectrum&gt; m_temporarySpectrum;
-    };
-    
-    std::unique_ptr&lt;Secondary&gt; m_otherCallees;
-};
-
-class CallEdgeLog {
-public:
-    CallEdgeLog();
-    ~CallEdgeLog();
-
-    static bool isEnabled();
-    
-#if ENABLE(JIT)
-    void emitLogCode(CCallHelpers&amp;, CallEdgeProfile&amp;, JSValueRegs calleeRegs); // Assumes that stack is aligned, all volatile registers - other than calleeGPR - are clobberable, and the parameter space is in use.
-    
-    // Same as above but creates a CallEdgeProfile instance if one did not already exist. Does
-    // this in a thread-safe manner by calling OwnPtr::createTransactionally.
-    void emitLogCode(CCallHelpers&amp;, OwnPtr&lt;CallEdgeProfile&gt;&amp;, JSValueRegs calleeRegs);
-#endif // ENABLE(JIT)
-    
-    void processLog();
-    
-private:
-    friend class LLIntOffsetsExtractor;
-
-    static const unsigned logSize = 10000;
-    
-    struct Entry {
-        JSValue m_value;
-        CallEdgeProfile* m_profile;
-    };
-    
-    unsigned m_scaledLogIndex;
-    Entry m_log[logSize];
-};
-
-} // namespace JSC
-
-#endif // CallEdgeProfile_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeProfileInlinesh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,91 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef CallEdgeProfileInlines_h
-#define CallEdgeProfileInlines_h
-
-#include &quot;CallEdgeProfile.h&quot;
-
-namespace JSC {
-
-inline CallEdgeProfile::CallEdgeProfile()
-    : m_closuresAreDespecified(false)
-    , m_numCallsToPrimary(0)
-    , m_numCallsToNotCell(0)
-    , m_numCallsToUnknownCell(0)
-    , m_totalCount(0)
-    , m_primaryCallee(nullptr)
-{
-}
-
-ALWAYS_INLINE void CallEdgeProfile::add(JSValue value, CallEdgeProfileVector&amp; mergeBackLog)
-{
-    unsigned newTotalCount = m_totalCount + 1;
-    if (UNLIKELY(!newTotalCount)) {
-        fadeByHalf(); // Tackle overflows by dividing all counts by two.
-        newTotalCount = m_totalCount + 1;
-    }
-    ASSERT(newTotalCount);
-    m_totalCount = newTotalCount;
-    
-    if (UNLIKELY(!value.isCell())) {
-        m_numCallsToNotCell++;
-        return;
-    }
-
-    CallVariant callee = CallVariant(value.asCell());
-    
-    if (m_closuresAreDespecified)
-        callee = callee.despecifiedClosure();
-    
-    if (UNLIKELY(!m_primaryCallee)) {
-        m_primaryCallee = callee;
-        m_numCallsToPrimary = 1;
-        return;
-    }
-        
-    if (LIKELY(m_primaryCallee == callee)) {
-        m_numCallsToPrimary++;
-        return;
-    }
-        
-    if (UNLIKELY(!m_otherCallees)) {
-        addSlow(callee, mergeBackLog);
-        return;
-    }
-        
-    CallSpectrum* secondary = m_otherCallees-&gt;m_temporarySpectrum.get();
-    if (!secondary) {
-        addSlow(callee, mergeBackLog);
-        return;
-    }
-        
-    secondary-&gt;add(callee);
-}
-
-} // namespace JSC
-
-#endif // CallEdgeProfileInlines_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -29,7 +29,9 @@
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="cx"> #include &quot;DFGThunks.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;Repatch.h&quot;
</ins><span class="cx"> #include &quot;RepatchBuffer.h&quot;
</span><ins>+#include &lt;wtf/ListDump.h&gt;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="lines">@@ -37,21 +39,18 @@
</span><span class="cx"> 
</span><span class="cx"> void CallLinkInfo::unlink(RepatchBuffer&amp; repatchBuffer)
</span><span class="cx"> {
</span><del>-    ASSERT(isLinked());
</del><ins>+    if (!isLinked()) {
+        // We could be called even if we're not linked anymore because of how polymorphic calls
+        // work. Each callsite within the polymorphic call stub may separately ask us to unlink().
+        RELEASE_ASSERT(!isOnList());
+        return;
+    }
</ins><span class="cx">     
</span><del>-    if (Options::showDisassembly())
-        dataLog(&quot;Unlinking call from &quot;, callReturnLocation, &quot; to &quot;, pointerDump(repatchBuffer.codeBlock()), &quot;\n&quot;);
</del><ins>+    unlinkFor(
+        repatchBuffer, *this,
+        (callType == Construct || callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
+        isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired);
</ins><span class="cx"> 
</span><del>-    repatchBuffer.revertJumpReplacementToBranchPtrWithPatch(RepatchBuffer::startOfBranchPtrWithPatchOnRegister(hotPathBegin), static_cast&lt;MacroAssembler::RegisterID&gt;(calleeGPR), 0);
-    repatchBuffer.relink(
-        callReturnLocation,
-        repatchBuffer.codeBlock()-&gt;vm()-&gt;getCTIStub(linkThunkGeneratorFor(
-            (callType == Construct || callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
-            isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired)).code());
-    hasSeenShouldRepatch = false;
-    callee.clear();
-    stub.clear();
-
</del><span class="cx">     // It will be on a list if the callee has a code block.
</span><span class="cx">     if (isOnList())
</span><span class="cx">         remove();
</span><span class="lines">@@ -61,12 +60,12 @@
</span><span class="cx"> {
</span><span class="cx">     if (isLinked()) {
</span><span class="cx">         if (stub) {
</span><del>-            if (!Heap::isMarked(stub-&gt;executable())) {
</del><ins>+            if (!stub-&gt;visitWeak(repatchBuffer)) {
</ins><span class="cx">                 if (Options::verboseOSR()) {
</span><span class="cx">                     dataLog(
</span><span class="cx">                         &quot;Clearing closure call from &quot;, *repatchBuffer.codeBlock(), &quot; to &quot;,
</span><del>-                        stub-&gt;executable()-&gt;hashFor(specializationKind()),
-                        &quot;, stub routine &quot;, RawPointer(stub.get()), &quot;.\n&quot;);
</del><ins>+                        listDump(stub-&gt;variants()), &quot;, stub routine &quot;, RawPointer(stub.get()),
+                        &quot;.\n&quot;);
</ins><span class="cx">                 }
</span><span class="cx">                 unlink(repatchBuffer);
</span><span class="cx">             }
</span><span class="lines">@@ -83,11 +82,6 @@
</span><span class="cx">     }
</span><span class="cx">     if (!!lastSeenCallee &amp;&amp; !Heap::isMarked(lastSeenCallee.get()))
</span><span class="cx">         lastSeenCallee.clear();
</span><del>-    
-    if (callEdgeProfile) {
-        WTF::loadLoadFence();
-        callEdgeProfile-&gt;visitWeak();
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CallLinkInfo&amp; CallLinkInfo::dummy()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -26,13 +26,12 @@
</span><span class="cx"> #ifndef CallLinkInfo_h
</span><span class="cx"> #define CallLinkInfo_h
</span><span class="cx"> 
</span><del>-#include &quot;CallEdgeProfile.h&quot;
-#include &quot;ClosureCallStubRoutine.h&quot;
</del><span class="cx"> #include &quot;CodeLocation.h&quot;
</span><span class="cx"> #include &quot;CodeSpecializationKind.h&quot;
</span><span class="cx"> #include &quot;JITWriteBarrier.h&quot;
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="cx"> #include &quot;Opcode.h&quot;
</span><ins>+#include &quot;PolymorphicCallStubRoutine.h&quot;
</ins><span class="cx"> #include &quot;WriteBarrier.h&quot;
</span><span class="cx"> #include &lt;wtf/OwnPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/SentinelLinkedList.h&gt;
</span><span class="lines">@@ -82,15 +81,14 @@
</span><span class="cx">     CodeLocationNearCall hotPathOther;
</span><span class="cx">     JITWriteBarrier&lt;JSFunction&gt; callee;
</span><span class="cx">     WriteBarrier&lt;JSFunction&gt; lastSeenCallee;
</span><del>-    RefPtr&lt;ClosureCallStubRoutine&gt; stub;
</del><ins>+    RefPtr&lt;PolymorphicCallStubRoutine&gt; stub;
</ins><span class="cx">     bool isFTL : 1;
</span><span class="cx">     bool hasSeenShouldRepatch : 1;
</span><span class="cx">     bool hasSeenClosure : 1;
</span><span class="cx">     unsigned callType : 5; // CallType
</span><span class="cx">     unsigned calleeGPR : 8;
</span><del>-    unsigned slowPathCount;
</del><ins>+    uint32_t slowPathCount;
</ins><span class="cx">     CodeOrigin codeOrigin;
</span><del>-    OwnPtr&lt;CallEdgeProfile&gt; callEdgeProfile;
</del><span class="cx"> 
</span><span class="cx">     bool isLinked() { return stub || callee; }
</span><span class="cx">     void unlink(RepatchBuffer&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    m_edges.append(CallEdge(CallVariant(value.asCell()), 1));
</del><ins>+    m_variants.append(CallVariant(value.asCell()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CallLinkStatus CallLinkStatus::computeFromLLInt(const ConcurrentJITLocker&amp; locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
</span><span class="lines">@@ -129,23 +129,6 @@
</span><span class="cx">     // We don't really need this, but anytime we have to debug this code, it becomes indispensable.
</span><span class="cx">     UNUSED_PARAM(profiledBlock);
</span><span class="cx">     
</span><del>-    if (Options::callStatusShouldUseCallEdgeProfile()) {
-        // Always trust the call edge profile over anything else since this has precise counts.
-        // It can make the best possible decision because it never &quot;forgets&quot; what happened for any
-        // call, with the exception of fading out the counts of old calls (for example if the
-        // counter type is 16-bit then calls that happened more than 2^16 calls ago are given half
-        // weight, and this compounds for every 2^15 [sic] calls after that). The combination of
-        // high fidelity for recent calls and fading for older calls makes this the most useful
-        // mechamism of choosing how to optimize future calls.
-        CallEdgeProfile* edgeProfile = callLinkInfo.callEdgeProfile.get();
-        WTF::loadLoadFence();
-        if (edgeProfile) {
-            CallLinkStatus result = computeFromCallEdgeProfile(edgeProfile);
-            if (!!result)
-                return result;
-        }
-    }
-    
</del><span class="cx">     return computeFromCallLinkInfo(locker, callLinkInfo);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -165,12 +148,68 @@
</span><span class="cx">     // that is still marginally valid (i.e. the pointers ain't stale). This kind of raciness
</span><span class="cx">     // is probably OK for now.
</span><span class="cx">     
</span><ins>+    // PolymorphicCallStubRoutine is a GCAwareJITStubRoutine, so if non-null, it will stay alive
+    // until next GC even if the CallLinkInfo is concurrently cleared. Also, the variants list is
+    // never mutated after the PolymorphicCallStubRoutine is instantiated. We have some conservative
+    // fencing in place to make sure that we see the variants list after construction.
+    if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub.get()) {
+        WTF::loadLoadFence();
+        
+        CallEdgeList edges = stub-&gt;edges();
+        
+        // Now that we've loaded the edges list, there are no further concurrency concerns. We will
+        // just manipulate and prune this list to our liking - mostly removing entries that are too
+        // infrequent and ensuring that it's sorted in descending order of frequency.
+        
+        RELEASE_ASSERT(edges.size());
+        
+        std::sort(
+            edges.begin(), edges.end(),
+            [] (CallEdge a, CallEdge b) {
+                return a.count() &gt; b.count();
+            });
+        RELEASE_ASSERT(edges.first().count() &gt;= edges.last().count());
+        
+        double totalCallsToKnown = 0;
+        double totalCallsToUnknown = callLinkInfo.slowPathCount;
+        CallVariantList variants;
+        for (size_t i = 0; i &lt; edges.size(); ++i) {
+            CallEdge edge = edges[i];
+            // If the call is at the tail of the distribution, then we don't optimize it and we
+            // treat it as if it was a call to something unknown. We define the tail as being either
+            // a call that doesn't belong to the N most frequent callees (N =
+            // maxPolymorphicCallVariantsForInlining) or that has a total call count that is too
+            // small.
+            if (i &gt;= Options::maxPolymorphicCallVariantsForInlining()
+                || edge.count() &lt; Options::frequentCallThreshold())
+                totalCallsToUnknown += edge.count();
+            else {
+                totalCallsToKnown += edge.count();
+                variants.append(edge.callee());
+            }
+        }
+        
+        // Bail if we didn't find any calls that qualified.
+        RELEASE_ASSERT(!!totalCallsToKnown == !!variants.size());
+        if (variants.isEmpty())
+            return takesSlowPath();
+        
+        // We require that the distribution of callees is skewed towards a handful of common ones.
+        if (totalCallsToKnown / totalCallsToUnknown &lt; Options::minimumCallToKnownRate())
+            return takesSlowPath();
+        
+        RELEASE_ASSERT(totalCallsToKnown);
+        RELEASE_ASSERT(variants.size());
+        
+        CallLinkStatus result;
+        result.m_variants = variants;
+        result.m_couldTakeSlowPath = !!totalCallsToUnknown;
+        return result;
+    }
+    
</ins><span class="cx">     if (callLinkInfo.slowPathCount &gt;= Options::couldTakeSlowCaseMinimumCount())
</span><span class="cx">         return takesSlowPath();
</span><span class="cx">     
</span><del>-    if (ClosureCallStubRoutine* stub = callLinkInfo.stub.get())
-        return CallLinkStatus(stub-&gt;executable());
-    
</del><span class="cx">     JSFunction* target = callLinkInfo.lastSeenCallee.get();
</span><span class="cx">     if (!target)
</span><span class="cx">         return takesSlowPath();
</span><span class="lines">@@ -181,34 +220,6 @@
</span><span class="cx">     return CallLinkStatus(target);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-CallLinkStatus CallLinkStatus::computeFromCallEdgeProfile(CallEdgeProfile* edgeProfile)
-{
-    // In cases where the call edge profile saw nothing, use the CallLinkInfo instead.
-    if (!edgeProfile-&gt;totalCalls())
-        return CallLinkStatus();
-    
-    // To do anything meaningful, we require that the majority of calls are to something we
-    // know how to handle.
-    unsigned numCallsToKnown = edgeProfile-&gt;numCallsToKnownCells();
-    unsigned numCallsToUnknown = edgeProfile-&gt;numCallsToNotCell() + edgeProfile-&gt;numCallsToUnknownCell();
-    
-    // We require that the majority of calls were to something that we could possibly inline.
-    if (numCallsToKnown &lt;= numCallsToUnknown)
-        return takesSlowPath();
-    
-    // We require that the number of such calls is greater than some minimal threshold, so that we
-    // avoid inlining completely cold calls.
-    if (numCallsToKnown &lt; Options::frequentCallThreshold())
-        return takesSlowPath();
-    
-    CallLinkStatus result;
-    result.m_edges = edgeProfile-&gt;callEdges();
-    result.m_couldTakeSlowPath = !!numCallsToUnknown;
-    result.m_canTrustCounts = true;
-    
-    return result;
-}
-
</del><span class="cx"> CallLinkStatus CallLinkStatus::computeFor(
</span><span class="cx">     const ConcurrentJITLocker&amp; locker, CodeBlock* profiledBlock, CallLinkInfo&amp; callLinkInfo,
</span><span class="cx">     ExitSiteData exitSiteData)
</span><span class="lines">@@ -282,8 +293,8 @@
</span><span class="cx"> 
</span><span class="cx"> bool CallLinkStatus::isClosureCall() const
</span><span class="cx"> {
</span><del>-    for (unsigned i = m_edges.size(); i--;) {
-        if (m_edges[i].callee().isClosureCall())
</del><ins>+    for (unsigned i = m_variants.size(); i--;) {
+        if (m_variants[i].isClosureCall())
</ins><span class="cx">             return true;
</span><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="lines">@@ -291,18 +302,7 @@
</span><span class="cx"> 
</span><span class="cx"> void CallLinkStatus::makeClosureCall()
</span><span class="cx"> {
</span><del>-    ASSERT(!m_isProved);
-    for (unsigned i = m_edges.size(); i--;)
-        m_edges[i] = m_edges[i].despecifiedClosure();
-    
-    if (!ASSERT_DISABLED) {
-        // Doing this should not have created duplicates, because the CallEdgeProfile
-        // should despecify closures if doing so would reduce the number of known callees.
-        for (unsigned i = 0; i &lt; m_edges.size(); ++i) {
-            for (unsigned j = i + 1; j &lt; m_edges.size(); ++j)
-                ASSERT(m_edges[i].callee() != m_edges[j].callee());
-        }
-    }
</del><ins>+    m_variants = despecifiedVariantList(m_variants);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CallLinkStatus::dump(PrintStream&amp; out) const
</span><span class="lines">@@ -320,7 +320,8 @@
</span><span class="cx">     if (m_couldTakeSlowPath)
</span><span class="cx">         out.print(comma, &quot;Could Take Slow Path&quot;);
</span><span class="cx">     
</span><del>-    out.print(listDump(m_edges));
</del><ins>+    if (!m_variants.isEmpty())
+        out.print(comma, listDump(m_variants));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkStatush"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #define CallLinkStatus_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CallLinkInfo.h&quot;
</span><ins>+#include &quot;CallVariant.h&quot;
</ins><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="cx"> #include &quot;CodeSpecializationKind.h&quot;
</span><span class="cx"> #include &quot;ConcurrentJITLock.h&quot;
</span><span class="lines">@@ -48,7 +49,6 @@
</span><span class="cx">     CallLinkStatus()
</span><span class="cx">         : m_couldTakeSlowPath(false)
</span><span class="cx">         , m_isProved(false)
</span><del>-        , m_canTrustCounts(false)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -62,10 +62,9 @@
</span><span class="cx">     explicit CallLinkStatus(JSValue);
</span><span class="cx">     
</span><span class="cx">     CallLinkStatus(CallVariant variant)
</span><del>-        : m_edges(1, CallEdge(variant, 1))
</del><ins>+        : m_variants(1, variant)
</ins><span class="cx">         , m_couldTakeSlowPath(false)
</span><span class="cx">         , m_isProved(false)
</span><del>-        , m_canTrustCounts(false)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -109,19 +108,18 @@
</span><span class="cx">     static CallLinkStatus computeFor(
</span><span class="cx">         CodeBlock*, CodeOrigin, const CallLinkInfoMap&amp;, const ContextMap&amp;);
</span><span class="cx">     
</span><del>-    bool isSet() const { return !m_edges.isEmpty() || m_couldTakeSlowPath; }
</del><ins>+    bool isSet() const { return !m_variants.isEmpty() || m_couldTakeSlowPath; }
</ins><span class="cx">     
</span><span class="cx">     bool operator!() const { return !isSet(); }
</span><span class="cx">     
</span><span class="cx">     bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
</span><span class="cx">     
</span><del>-    CallEdgeList edges() const { return m_edges; }
-    unsigned size() const { return m_edges.size(); }
-    CallEdge at(unsigned i) const { return m_edges[i]; }
-    CallEdge operator[](unsigned i) const { return at(i); }
</del><ins>+    CallVariantList variants() const { return m_variants; }
+    unsigned size() const { return m_variants.size(); }
+    CallVariant at(unsigned i) const { return m_variants[i]; }
+    CallVariant operator[](unsigned i) const { return at(i); }
</ins><span class="cx">     bool isProved() const { return m_isProved; }
</span><del>-    bool canOptimize() const { return !m_edges.isEmpty(); }
-    bool canTrustCounts() const { return m_canTrustCounts; }
</del><ins>+    bool canOptimize() const { return !m_variants.isEmpty(); }
</ins><span class="cx">     
</span><span class="cx">     bool isClosureCall() const; // Returns true if any callee is a closure call.
</span><span class="cx">     
</span><span class="lines">@@ -132,15 +130,13 @@
</span><span class="cx">     
</span><span class="cx">     static CallLinkStatus computeFromLLInt(const ConcurrentJITLocker&amp;, CodeBlock*, unsigned bytecodeIndex);
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    static CallLinkStatus computeFromCallEdgeProfile(CallEdgeProfile*);
</del><span class="cx">     static CallLinkStatus computeFromCallLinkInfo(
</span><span class="cx">         const ConcurrentJITLocker&amp;, CallLinkInfo&amp;);
</span><span class="cx"> #endif
</span><span class="cx">     
</span><del>-    CallEdgeList m_edges;
</del><ins>+    CallVariantList m_variants;
</ins><span class="cx">     bool m_couldTakeSlowPath;
</span><span class="cx">     bool m_isProved;
</span><del>-    bool m_canTrustCounts;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallVariantcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -50,5 +50,34 @@
</span><span class="cx">     out.print(&quot;Executable: &quot;, *executable());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CallVariantList variantListWithVariant(const CallVariantList&amp; list, CallVariant variantToAdd)
+{
+    ASSERT(variantToAdd);
+    CallVariantList result;
+    for (CallVariant variant : list) {
+        ASSERT(variant);
+        if (!!variantToAdd) {
+            if (variant == variantToAdd)
+                variantToAdd = CallVariant();
+            else if (variant.despecifiedClosure() == variantToAdd.despecifiedClosure()) {
+                variant = variant.despecifiedClosure();
+                variantToAdd = CallVariant();
+            }
+        }
+        result.append(variant);
+    }
+    if (!!variantToAdd)
+        result.append(variantToAdd);
+    return result;
+}
+
+CallVariantList despecifiedVariantList(const CallVariantList&amp; list)
+{
+    CallVariantList result;
+    for (CallVariant variant : list)
+        result = variantListWithVariant(result, variant.despecifiedClosure());
+    return result;
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallVarianth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallVariant.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallVariant.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CallVariant.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -56,11 +56,8 @@
</span><span class="cx"> //     than the fact that they don't fall into any of the above categories.
</span><span class="cx"> //
</span><span class="cx"> // This class serves as a kind of union over these four things. It does so by just holding a
</span><del>-// JSCell*. We determine which of the modes its in by doing type checks on the cell. Note that there
-// is no lifecycle management for the cell because this class is always used in contexts where we
-// either do custom weak reference logic over instances of this class (see CallEdgeProfile), or we
-// are inside the compiler and we assume that the compiler runs in between collections and so can
-// touch the heap without notifying anyone.
</del><ins>+// JSCell*. We determine which of the modes its in by doing type checks on the cell. Note that we
+// cannot use WriteBarrier&lt;&gt; here because this gets used inside the compiler.
</ins><span class="cx"> 
</span><span class="cx"> class CallVariant {
</span><span class="cx"> public:
</span><span class="lines">@@ -181,6 +178,13 @@
</span><span class="cx"> 
</span><span class="cx"> typedef Vector&lt;CallVariant, 1&gt; CallVariantList;
</span><span class="cx"> 
</span><ins>+// Returns a new variant list by attempting to either append the given variant or merge it with one
+// of the variants we already have by despecifying closures.
+CallVariantList variantListWithVariant(const CallVariantList&amp;, CallVariant);
+
+// Returns a new list where every element is despecified, and the list is deduplicated.
+CallVariantList despecifiedVariantList(const CallVariantList&amp;);
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2010, 2012-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich &lt;cwzwarich@uwaterloo.ca&gt;
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -2174,6 +2174,8 @@
</span><span class="cx">     // destructor will try to remove nodes from our (no longer valid) linked list.
</span><span class="cx">     while (m_incomingCalls.begin() != m_incomingCalls.end())
</span><span class="cx">         m_incomingCalls.begin()-&gt;remove();
</span><ins>+    while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
+        m_incomingPolymorphicCalls.begin()-&gt;remove();
</ins><span class="cx">     
</span><span class="cx">     // Note that our outgoing calls will be removed from other CodeBlocks'
</span><span class="cx">     // m_incomingCalls linked lists through the execution of the ~CallLinkInfo
</span><span class="lines">@@ -3040,6 +3042,12 @@
</span><span class="cx">     noticeIncomingCall(callerFrame);
</span><span class="cx">     m_incomingCalls.push(incoming);
</span><span class="cx"> }
</span><ins>+
+void CodeBlock::linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode* incoming)
+{
+    noticeIncomingCall(callerFrame);
+    m_incomingPolymorphicCalls.push(incoming);
+}
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx"> void CodeBlock::unlinkIncomingCalls()
</span><span class="lines">@@ -3047,11 +3055,13 @@
</span><span class="cx">     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
</span><span class="cx">         m_incomingLLIntCalls.begin()-&gt;unlink();
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    if (m_incomingCalls.isEmpty())
</del><ins>+    if (m_incomingCalls.isEmpty() &amp;&amp; m_incomingPolymorphicCalls.isEmpty())
</ins><span class="cx">         return;
</span><span class="cx">     RepatchBuffer repatchBuffer(this);
</span><span class="cx">     while (m_incomingCalls.begin() != m_incomingCalls.end())
</span><span class="cx">         m_incomingCalls.begin()-&gt;unlink(repatchBuffer);
</span><ins>+    while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
+        m_incomingPolymorphicCalls.begin()-&gt;unlink(repatchBuffer);
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3245,12 +3255,19 @@
</span><span class="cx">     CodeBlock* callerCodeBlock = callerFrame-&gt;codeBlock();
</span><span class="cx">     
</span><span class="cx">     if (Options::verboseCallLink())
</span><del>-        dataLog(&quot;Noticing call link from &quot;, *callerCodeBlock, &quot; to &quot;, *this, &quot;\n&quot;);
</del><ins>+        dataLog(&quot;Noticing call link from &quot;, pointerDump(callerCodeBlock), &quot; to &quot;, *this, &quot;\n&quot;);
</ins><span class="cx">     
</span><ins>+#if ENABLE(DFG_JIT)
</ins><span class="cx">     if (!m_shouldAlwaysBeInlined)
</span><span class="cx">         return;
</span><ins>+    
+    if (!callerCodeBlock) {
+        m_shouldAlwaysBeInlined = false;
+        if (Options::verboseCallLink())
+            dataLog(&quot;    Clearing SABI because caller is native.\n&quot;);
+        return;
+    }
</ins><span class="cx"> 
</span><del>-#if ENABLE(DFG_JIT)
</del><span class="cx">     if (!hasBaselineJITProfiling())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -3278,6 +3295,13 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    if (JITCode::isOptimizingJIT(callerCodeBlock-&gt;jitType())) {
+        m_shouldAlwaysBeInlined = false;
+        if (Options::verboseCallLink())
+            dataLog(&quot;    Clearing SABI bcause caller was already optimized.\n&quot;);
+        return;
+    }
+    
</ins><span class="cx">     if (callerCodeBlock-&gt;codeType() != FunctionCode) {
</span><span class="cx">         // If the caller is either eval or global code, assume that that won't be
</span><span class="cx">         // optimized anytime soon. For eval code this is particularly true since we
</span><span class="lines">@@ -3298,9 +3322,12 @@
</span><span class="cx">         m_shouldAlwaysBeInlined = false;
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-
-    RELEASE_ASSERT(callerCodeBlock-&gt;m_capabilityLevelState != DFG::CapabilityLevelNotSet);
</del><span class="cx">     
</span><ins>+    if (callerCodeBlock-&gt;m_capabilityLevelState == DFG::CapabilityLevelNotSet) {
+        dataLog(&quot;In call from &quot;, *callerCodeBlock, &quot; &quot;, callerFrame-&gt;codeOrigin(), &quot; to &quot;, *this, &quot;: caller's DFG capability level is not set.\n&quot;);
+        CRASH();
+    }
+    
</ins><span class="cx">     if (canCompile(callerCodeBlock-&gt;m_capabilityLevelState))
</span><span class="cx">         return;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -229,11 +229,7 @@
</span><span class="cx">     void unlinkCalls();
</span><span class="cx">         
</span><span class="cx">     void linkIncomingCall(ExecState* callerFrame, CallLinkInfo*);
</span><del>-        
-    bool isIncomingCallAlreadyLinked(CallLinkInfo* incoming)
-    {
-        return m_incomingCalls.isOnList(incoming);
-    }
</del><ins>+    void linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode*);
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx">     void linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo*);
</span><span class="lines">@@ -1077,6 +1073,7 @@
</span><span class="cx">     Vector&lt;ByValInfo&gt; m_byValInfos;
</span><span class="cx">     Bag&lt;CallLinkInfo&gt; m_callLinkInfos;
</span><span class="cx">     SentinelLinkedList&lt;CallLinkInfo, BasicRawSentinelNode&lt;CallLinkInfo&gt;&gt; m_incomingCalls;
</span><ins>+    SentinelLinkedList&lt;PolymorphicCallNode, BasicRawSentinelNode&lt;PolymorphicCallNode&gt;&gt; m_incomingPolymorphicCalls;
</ins><span class="cx"> #endif
</span><span class="cx">     std::unique_ptr&lt;CompactJITCodeMap&gt; m_jitCodeMap;
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -741,7 +741,7 @@
</span><span class="cx">         
</span><span class="cx">     case ArithSin: {
</span><span class="cx">         JSValue child = forNode(node-&gt;child1()).value();
</span><del>-        if (child &amp;&amp; child.isNumber()) {
</del><ins>+        if (false &amp;&amp; child &amp;&amp; child.isNumber()) {
</ins><span class="cx">             setConstant(node, jsDoubleNumber(sin(child.asNumber())));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -751,7 +751,7 @@
</span><span class="cx">     
</span><span class="cx">     case ArithCos: {
</span><span class="cx">         JSValue child = forNode(node-&gt;child1()).value();
</span><del>-        if (child &amp;&amp; child.isNumber()) {
</del><ins>+        if (false &amp;&amp; child &amp;&amp; child.isNumber()) {
</ins><span class="cx">             setConstant(node, jsDoubleNumber(cos(child.asNumber())));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -1968,14 +1968,6 @@
</span><span class="cx">         forNode(node).makeHeapTop();
</span><span class="cx">         break;
</span><span class="cx"> 
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
-        if (forNode(m_graph.varArgChild(node, 0)).m_value)
-            m_state.setFoundConstants(true);
-        clobberWorld(node-&gt;origin.semantic, clobberLimit);
-        forNode(node).makeHeapTop();
-        break;
-
</del><span class="cx">     case ForceOSRExit:
</span><span class="cx">     case CheckBadCell:
</span><span class="cx">         m_state.setIsValid(false);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx">  /*
</span><del>- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -675,7 +675,7 @@
</span><span class="cx">         if (parameterSlots &gt; m_parameterSlots)
</span><span class="cx">             m_parameterSlots = parameterSlots;
</span><span class="cx"> 
</span><del>-        int dummyThisArgument = op == Call || op == NativeCall || op == ProfiledCall ? 0 : 1;
</del><ins>+        int dummyThisArgument = op == Call || op == NativeCall ? 0 : 1;
</ins><span class="cx">         for (int i = 0 + dummyThisArgument; i &lt; argCount; ++i)
</span><span class="cx">             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
</span><span class="cx"> 
</span><span class="lines">@@ -1044,17 +1044,8 @@
</span><span class="cx">     if (callTarget-&gt;hasConstant())
</span><span class="cx">         callLinkStatus = CallLinkStatus(callTarget-&gt;asJSValue()).setIsProved(true);
</span><span class="cx">     
</span><del>-    if ((!callLinkStatus.canOptimize() || callLinkStatus.size() != 1)
-        &amp;&amp; !isFTL(m_graph.m_plan.mode) &amp;&amp; Options::useFTLJIT()
-        &amp;&amp; InlineCallFrame::isNormalCall(kind)
-        &amp;&amp; CallEdgeLog::isEnabled()
-        &amp;&amp; Options::dfgDoesCallEdgeProfiling()) {
-        ASSERT(op == Call || op == Construct);
-        if (op == Call)
-            op = ProfiledCall;
-        else
-            op = ProfiledConstruct;
-    }
</del><ins>+    if (Options::verboseDFGByteCodeParsing())
+        dataLog(&quot;    Handling call at &quot;, currentCodeOrigin(), &quot;: &quot;, callLinkStatus, &quot;\n&quot;);
</ins><span class="cx">     
</span><span class="cx">     if (!callLinkStatus.canOptimize()) {
</span><span class="cx">         // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
</span><span class="lines">@@ -1076,17 +1067,17 @@
</span><span class="cx">     
</span><span class="cx"> #if ENABLE(FTL_NATIVE_CALL_INLINING)
</span><span class="cx">     if (isFTL(m_graph.m_plan.mode) &amp;&amp; Options::optimizeNativeCalls() &amp;&amp; callLinkStatus.size() == 1 &amp;&amp; !callLinkStatus.couldTakeSlowPath()) {
</span><del>-        CallVariant callee = callLinkStatus[0].callee();
</del><ins>+        CallVariant callee = callLinkStatus[0];
</ins><span class="cx">         JSFunction* function = callee.function();
</span><span class="cx">         CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</span><span class="cx">         if (function &amp;&amp; function-&gt;isHostFunction()) {
</span><span class="cx">             emitFunctionChecks(callee, callTarget, registerOffset, specializationKind);
</span><span class="cx">             callOpInfo = OpInfo(m_graph.freeze(function));
</span><span class="cx"> 
</span><del>-            if (op == Call || op == ProfiledCall)
</del><ins>+            if (op == Call)
</ins><span class="cx">                 op = NativeCall;
</span><span class="cx">             else {
</span><del>-                ASSERT(op == Construct || op == ProfiledConstruct);
</del><ins>+                ASSERT(op == Construct);
</ins><span class="cx">                 op = NativeConstruct;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -1426,13 +1417,13 @@
</span><span class="cx">     // this in cases where we don't need control flow diamonds to check the callee.
</span><span class="cx">     if (!callLinkStatus.couldTakeSlowPath() &amp;&amp; callLinkStatus.size() == 1) {
</span><span class="cx">         emitFunctionChecks(
</span><del>-            callLinkStatus[0].callee(), callTargetNode, registerOffset, specializationKind);
</del><ins>+            callLinkStatus[0], callTargetNode, registerOffset, specializationKind);
</ins><span class="cx">         bool result = attemptToInlineCall(
</span><del>-            callTargetNode, resultOperand, callLinkStatus[0].callee(), registerOffset,
</del><ins>+            callTargetNode, resultOperand, callLinkStatus[0], registerOffset,
</ins><span class="cx">             argumentCountIncludingThis, nextOffset, kind, CallerDoesNormalLinking, prediction,
</span><span class="cx">             inliningBalance);
</span><span class="cx">         if (!result &amp;&amp; !callLinkStatus.isProved())
</span><del>-            undoFunctionChecks(callLinkStatus[0].callee());
</del><ins>+            undoFunctionChecks(callLinkStatus[0]);
</ins><span class="cx">         if (verbose) {
</span><span class="cx">             dataLog(&quot;Done inlining (simple).\n&quot;);
</span><span class="cx">             dataLog(&quot;Stack: &quot;, currentCodeOrigin(), &quot;\n&quot;);
</span><span class="lines">@@ -1462,7 +1453,7 @@
</span><span class="cx">     bool allAreClosureCalls = true;
</span><span class="cx">     bool allAreDirectCalls = true;
</span><span class="cx">     for (unsigned i = callLinkStatus.size(); i--;) {
</span><del>-        if (callLinkStatus[i].callee().isClosureCall())
</del><ins>+        if (callLinkStatus[i].isClosureCall())
</ins><span class="cx">             allAreDirectCalls = false;
</span><span class="cx">         else
</span><span class="cx">             allAreClosureCalls = false;
</span><span class="lines">@@ -1475,9 +1466,8 @@
</span><span class="cx">         thingToSwitchOn = addToGraph(GetExecutable, callTargetNode);
</span><span class="cx">     else {
</span><span class="cx">         // FIXME: We should be able to handle this case, but it's tricky and we don't know of cases
</span><del>-        // where it would be beneficial. Also, CallLinkStatus would make all callees appear like
-        // closure calls if any calls were closure calls - except for calls to internal functions.
-        // So this will only arise if some callees are internal functions and others are closures.
</del><ins>+        // where it would be beneficial. It might be best to handle these cases as if all calls were
+        // closure calls.
</ins><span class="cx">         // https://bugs.webkit.org/show_bug.cgi?id=136020
</span><span class="cx">         if (verbose) {
</span><span class="cx">             dataLog(&quot;Bailing inlining (mix).\n&quot;);
</span><span class="lines">@@ -1517,7 +1507,7 @@
</span><span class="cx">     // to the continuation block, which we create last.
</span><span class="cx">     Vector&lt;BasicBlock*&gt; landingBlocks;
</span><span class="cx">     
</span><del>-    // We make force this true if we give up on inlining any of the edges.
</del><ins>+    // We may force this true if we give up on inlining any of the edges.
</ins><span class="cx">     bool couldTakeSlowPath = callLinkStatus.couldTakeSlowPath();
</span><span class="cx">     
</span><span class="cx">     if (verbose)
</span><span class="lines">@@ -1533,7 +1523,7 @@
</span><span class="cx">         Node* myCallTargetNode = getDirect(calleeReg);
</span><span class="cx">         
</span><span class="cx">         bool inliningResult = attemptToInlineCall(
</span><del>-            myCallTargetNode, resultOperand, callLinkStatus[i].callee(), registerOffset,
</del><ins>+            myCallTargetNode, resultOperand, callLinkStatus[i], registerOffset,
</ins><span class="cx">             argumentCountIncludingThis, nextOffset, kind, CallerLinksManually, prediction,
</span><span class="cx">             inliningBalance);
</span><span class="cx">         
</span><span class="lines">@@ -1552,10 +1542,10 @@
</span><span class="cx">         
</span><span class="cx">         JSCell* thingToCaseOn;
</span><span class="cx">         if (allAreDirectCalls)
</span><del>-            thingToCaseOn = callLinkStatus[i].callee().nonExecutableCallee();
</del><ins>+            thingToCaseOn = callLinkStatus[i].nonExecutableCallee();
</ins><span class="cx">         else {
</span><span class="cx">             ASSERT(allAreClosureCalls);
</span><del>-            thingToCaseOn = callLinkStatus[i].callee().executable();
</del><ins>+            thingToCaseOn = callLinkStatus[i].executable();
</ins><span class="cx">         }
</span><span class="cx">         data.cases.append(SwitchCase(m_graph.freeze(thingToCaseOn), block.get()));
</span><span class="cx">         m_currentIndex = nextOffset;
</span><span class="lines">@@ -1567,7 +1557,7 @@
</span><span class="cx">         landingBlocks.append(m_currentBlock);
</span><span class="cx"> 
</span><span class="cx">         if (verbose)
</span><del>-            dataLog(&quot;Finished inlining &quot;, callLinkStatus[i].callee(), &quot; at &quot;, currentCodeOrigin(), &quot;.\n&quot;);
</del><ins>+            dataLog(&quot;Finished inlining &quot;, callLinkStatus[i], &quot; at &quot;, currentCodeOrigin(), &quot;.\n&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RefPtr&lt;BasicBlock&gt; slowPathBlock = adoptRef(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -363,8 +363,6 @@
</span><span class="cx">     case ArrayPop:
</span><span class="cx">     case Call:
</span><span class="cx">     case Construct:
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
</del><span class="cx">     case NativeCall:
</span><span class="cx">     case NativeConstruct:
</span><span class="cx">     case ToPrimitive:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -420,20 +420,6 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><del>-            case ProfiledCall:
-            case ProfiledConstruct: {
-                if (!m_state.forNode(m_graph.varArgChild(node, 0)).m_value)
-                    break;
-                
-                // If we were able to prove that the callee is a constant then the normal call
-                // inline cache will record this callee. This means that there is no need to do any
-                // additional profiling.
-                m_interpreter.execute(indexInBlock);
-                node-&gt;setOp(node-&gt;op() == ProfiledCall ? Call : Construct);
-                eliminated = true;
-                break;
-            }
-
</del><span class="cx">             default:
</span><span class="cx">                 break;
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -118,8 +118,6 @@
</span><span class="cx">     case Construct:
</span><span class="cx">     case NativeCall:
</span><span class="cx">     case NativeConstruct:
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
</del><span class="cx">     case Breakpoint:
</span><span class="cx">     case ProfileWillCall:
</span><span class="cx">     case ProfileDidCall:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDrivercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -79,20 +79,17 @@
</span><span class="cx">     if (mode == DFGMode) {
</span><span class="cx">         vm.getCTIStub(linkCallThunkGenerator);
</span><span class="cx">         vm.getCTIStub(linkConstructThunkGenerator);
</span><del>-        vm.getCTIStub(linkClosureCallThunkGenerator);
</del><ins>+        vm.getCTIStub(linkPolymorphicCallThunkGenerator);
</ins><span class="cx">         vm.getCTIStub(virtualCallThunkGenerator);
</span><span class="cx">         vm.getCTIStub(virtualConstructThunkGenerator);
</span><span class="cx">     } else {
</span><span class="cx">         vm.getCTIStub(linkCallThatPreservesRegsThunkGenerator);
</span><span class="cx">         vm.getCTIStub(linkConstructThatPreservesRegsThunkGenerator);
</span><del>-        vm.getCTIStub(linkClosureCallThatPreservesRegsThunkGenerator);
</del><ins>+        vm.getCTIStub(linkPolymorphicCallThatPreservesRegsThunkGenerator);
</ins><span class="cx">         vm.getCTIStub(virtualCallThatPreservesRegsThunkGenerator);
</span><span class="cx">         vm.getCTIStub(virtualConstructThatPreservesRegsThunkGenerator);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (CallEdgeLog::isEnabled())
-        vm.ensureCallEdgeLog().processLog();
-
</del><span class="cx">     if (vm.typeProfiler())
</span><span class="cx">         vm.typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;Preparing for DFG compilation.&quot;));
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1202,8 +1202,6 @@
</span><span class="cx">         case AllocationProfileWatchpoint:
</span><span class="cx">         case Call:
</span><span class="cx">         case Construct:
</span><del>-        case ProfiledCall:
-        case ProfiledConstruct:
</del><span class="cx">         case ProfileControlFlow:
</span><span class="cx">         case NativeCall:
</span><span class="cx">         case NativeConstruct:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1064,8 +1064,6 @@
</span><span class="cx">         case GetMyArgumentByValSafe:
</span><span class="cx">         case Call:
</span><span class="cx">         case Construct:
</span><del>-        case ProfiledCall:
-        case ProfiledConstruct:
</del><span class="cx">         case NativeCall:
</span><span class="cx">         case NativeConstruct:
</span><span class="cx">         case GetByOffset:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -217,8 +217,6 @@
</span><span class="cx">     /* Calls. */\
</span><span class="cx">     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><span class="cx">     macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><del>-    macro(ProfiledCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
-    macro(ProfiledConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</del><span class="cx">     macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><span class="cx">     macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><span class="cx">     \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1203,6 +1203,11 @@
</span><span class="cx">     DeferGC deferGC(vm-&gt;heap);
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><span class="cx">     
</span><ins>+    if (codeBlock-&gt;jitType() != JITCode::DFGJIT) {
+        dataLog(&quot;Unexpected code block in DFG-&gt;FTL tier-up: &quot;, *codeBlock, &quot;\n&quot;);
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
</ins><span class="cx">     JITCode* jitCode = codeBlock-&gt;jitCode()-&gt;dfg();
</span><span class="cx">     
</span><span class="cx">     if (Options::verboseOSR()) {
</span><span class="lines">@@ -1222,6 +1227,11 @@
</span><span class="cx">     DeferGC deferGC(vm-&gt;heap);
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><span class="cx">     
</span><ins>+    if (codeBlock-&gt;jitType() != JITCode::DFGJIT) {
+        dataLog(&quot;Unexpected code block in DFG-&gt;FTL tier-up: &quot;, *codeBlock, &quot;\n&quot;);
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
</ins><span class="cx">     JITCode* jitCode = codeBlock-&gt;jitCode()-&gt;dfg();
</span><span class="cx">     
</span><span class="cx">     if (Options::verboseOSR()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -188,8 +188,6 @@
</span><span class="cx">         case GetDirectPname:
</span><span class="cx">         case Call:
</span><span class="cx">         case Construct:
</span><del>-        case ProfiledCall:
-        case ProfiledConstruct:
</del><span class="cx">         case NativeCall:
</span><span class="cx">         case NativeConstruct:
</span><span class="cx">         case GetGlobalVar:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -189,8 +189,6 @@
</span><span class="cx">     case CompareStrictEq:
</span><span class="cx">     case Call:
</span><span class="cx">     case Construct:
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
</del><span class="cx">     case NewObject:
</span><span class="cx">     case NewArray:
</span><span class="cx">     case NewArrayWithSize:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -638,9 +638,9 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::emitCall(Node* node)
</span><span class="cx"> {
</span><del>-    bool isCall = node-&gt;op() == Call || node-&gt;op() == ProfiledCall;
</del><ins>+    bool isCall = node-&gt;op() == Call;
</ins><span class="cx">     if (!isCall)
</span><del>-        ASSERT(node-&gt;op() == Construct || node-&gt;op() == ProfiledConstruct);
</del><ins>+        ASSERT(node-&gt;op() == Construct);
</ins><span class="cx"> 
</span><span class="cx">     // For constructors, the this argument is not passed but we have to make space
</span><span class="cx">     // for it.
</span><span class="lines">@@ -689,11 +689,6 @@
</span><span class="cx">     
</span><span class="cx">     CallLinkInfo* info = m_jit.codeBlock()-&gt;addCallLinkInfo();
</span><span class="cx"> 
</span><del>-    if (node-&gt;op() == ProfiledCall || node-&gt;op() == ProfiledConstruct) {
-        m_jit.vm()-&gt;callEdgeLog-&gt;emitLogCode(
-            m_jit, info-&gt;callEdgeProfile, callee.jsValueRegs());
-    }
-    
</del><span class="cx">     slowPath.append(branchNotCell(callee.jsValueRegs()));
</span><span class="cx">     slowPath.append(m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleePayloadGPR, targetToCheck));
</span><span class="cx"> 
</span><span class="lines">@@ -4169,8 +4164,6 @@
</span><span class="cx"> 
</span><span class="cx">     case Call:
</span><span class="cx">     case Construct:
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
</del><span class="cx">         emitCall(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -624,9 +624,9 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::emitCall(Node* node)
</span><span class="cx"> {
</span><del>-    bool isCall = node-&gt;op() == Call || node-&gt;op() == ProfiledCall;
</del><ins>+    bool isCall = node-&gt;op() == Call;
</ins><span class="cx">     if (!isCall)
</span><del>-        DFG_ASSERT(m_jit.graph(), node, node-&gt;op() == Construct || node-&gt;op() == ProfiledConstruct);
</del><ins>+        DFG_ASSERT(m_jit.graph(), node, node-&gt;op() == Construct);
</ins><span class="cx">     
</span><span class="cx">     // For constructors, the this argument is not passed but we have to make space
</span><span class="cx">     // for it.
</span><span class="lines">@@ -669,11 +669,6 @@
</span><span class="cx">     
</span><span class="cx">     CallLinkInfo* callLinkInfo = m_jit.codeBlock()-&gt;addCallLinkInfo();
</span><span class="cx">     
</span><del>-    if (node-&gt;op() == ProfiledCall || node-&gt;op() == ProfiledConstruct) {
-        m_jit.vm()-&gt;callEdgeLog-&gt;emitLogCode(
-            m_jit, callLinkInfo-&gt;callEdgeProfile, JSValueRegs(calleeGPR));
-    }
-
</del><span class="cx">     slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(0));
</span><span class="cx"> 
</span><span class="cx">     JITCompiler::Call fastCall = m_jit.nearCall();
</span><span class="lines">@@ -4236,8 +4231,6 @@
</span><span class="cx"> 
</span><span class="cx">     case Call:
</span><span class="cx">     case Construct:
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
</del><span class="cx">         emitCall(node);
</span><span class="cx">         break;
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGTierUpCheckInjectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -50,17 +50,13 @@
</span><span class="cx">         if (!Options::useFTLJIT())
</span><span class="cx">             return false;
</span><span class="cx">         
</span><del>-        if (m_graph.m_profiledBlock-&gt;m_didFailFTLCompilation) {
-            removeFTLProfiling();
</del><ins>+        if (m_graph.m_profiledBlock-&gt;m_didFailFTLCompilation)
</ins><span class="cx">             return false;
</span><del>-        }
</del><span class="cx">         
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx">         FTL::CapabilityLevel level = FTL::canCompile(m_graph);
</span><del>-        if (level == FTL::CannotCompile) {
-            removeFTLProfiling();
</del><ins>+        if (level == FTL::CannotCompile)
</ins><span class="cx">             return false;
</span><del>-        }
</del><span class="cx">         
</span><span class="cx">         if (!Options::enableOSREntryToFTL())
</span><span class="cx">             level = FTL::CanCompile;
</span><span class="lines">@@ -122,32 +118,6 @@
</span><span class="cx">         return false;
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span><span class="cx">     }
</span><del>-
-private:
-    void removeFTLProfiling()
-    {
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            
-            for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
-                Node* node = block-&gt;at(nodeIndex);
-                switch (node-&gt;op()) {
-                case ProfiledCall:
-                    node-&gt;setOp(Call);
-                    break;
-                    
-                case ProfiledConstruct:
-                    node-&gt;setOp(Construct);
-                    break;
-                    
-                default:
-                    break;
-                }
-            }
-        }
-    }
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> bool performTierUpCheckInjection(Graph&amp; graph)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -176,11 +176,6 @@
</span><span class="cx">     case MaterializeNewObject:
</span><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><del>-    case ProfiledCall:
-    case ProfiledConstruct:
-        // These are OK not because the FTL can support them, but because if the DFG sees one of
-        // these then the FTL will see a normal Call/Construct.
-        break;
</del><span class="cx">     case Identity:
</span><span class="cx">         // No backend handles this because it will be optimized out. But we may check
</span><span class="cx">         // for capabilities before optimization. It would be a deep error to remove this
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -992,11 +992,6 @@
</span><span class="cx">         vm()-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;GC&quot;));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (vm()-&gt;callEdgeLog) {
-        DeferGCForAWhile awhile(*this);
-        vm()-&gt;callEdgeLog-&gt;processLog();
-    }
-    
</del><span class="cx">     RELEASE_ASSERT(!m_deferralDepth);
</span><span class="cx">     ASSERT(vm()-&gt;currentThreadIsHoldingAPILock());
</span><span class="cx">     RELEASE_ASSERT(vm()-&gt;atomicStringTable() == wtfThreadData().atomicStringTable());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitBinarySwitchh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/BinarySwitch.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/BinarySwitch.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/BinarySwitch.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx"> //     int value = switch.caseValue();
</span><span class="cx"> //     unsigned index = switch.caseIndex(); // index into casesVector, above
</span><span class="cx"> //     ... // generate code for this case
</span><ins>+//     ... = jit.jump(); // you have to jump out yourself; falling through causes undefined behavior
</ins><span class="cx"> // }
</span><span class="cx"> // switch.fallThrough().link(&amp;jit);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitClosureCallStubRoutinecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,60 +0,0 @@
</span><del>-/*
- * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include &quot;config.h&quot;
-#include &quot;ClosureCallStubRoutine.h&quot;
-
-#if ENABLE(JIT)
-
-#include &quot;Executable.h&quot;
-#include &quot;Heap.h&quot;
-#include &quot;VM.h&quot;
-#include &quot;JSCInlines.h&quot;
-#include &quot;SlotVisitor.h&quot;
-#include &quot;Structure.h&quot;
-
-namespace JSC {
-
-ClosureCallStubRoutine::ClosureCallStubRoutine(
-    const MacroAssemblerCodeRef&amp; code, VM&amp; vm, const JSCell* owner,
-    ExecutableBase* executable)
-    : GCAwareJITStubRoutine(code, vm)
-    , m_executable(vm, owner, executable)
-{
-}
-
-ClosureCallStubRoutine::~ClosureCallStubRoutine()
-{
-}
-
-void ClosureCallStubRoutine::markRequiredObjectsInternal(SlotVisitor&amp; visitor)
-{
-    visitor.append(&amp;m_executable);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitClosureCallStubRoutineh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,58 +0,0 @@
</span><del>-/*
- * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ClosureCallStubRoutine_h
-#define ClosureCallStubRoutine_h
-
-#if ENABLE(JIT)
-
-#include &quot;CodeOrigin.h&quot;
-#include &quot;GCAwareJITStubRoutine.h&quot;
-
-namespace JSC {
-
-class ClosureCallStubRoutine : public GCAwareJITStubRoutine {
-public:
-    ClosureCallStubRoutine(
-        const MacroAssemblerCodeRef&amp;, VM&amp;, const JSCell* owner,
-        ExecutableBase*);
-    
-    virtual ~ClosureCallStubRoutine();
-    
-    ExecutableBase* executable() const { return m_executable.get(); }
-
-protected:
-    virtual void markRequiredObjectsInternal(SlotVisitor&amp;) override;
-
-private:
-    WriteBarrier&lt;ExecutableBase&gt; m_executable;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // ClosureCallStubRoutine_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/JITCall.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -214,10 +214,6 @@
</span><span class="cx">     
</span><span class="cx">     CallLinkInfo* info = m_codeBlock-&gt;addCallLinkInfo();
</span><span class="cx"> 
</span><del>-    if (CallEdgeLog::isEnabled() &amp;&amp; shouldEmitProfiling()
-        &amp;&amp; Options::baselineDoesCallEdgeProfiling())
-        m_vm-&gt;ensureCallEdgeLog().emitLogCode(*this, info-&gt;callEdgeProfile, JSValueRegs(regT0));
-
</del><span class="cx">     if (opcodeID == op_call_eval) {
</span><span class="cx">         compileCallEval(instruction);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -278,12 +278,6 @@
</span><span class="cx"> 
</span><span class="cx">     CallLinkInfo* info = m_codeBlock-&gt;addCallLinkInfo();
</span><span class="cx"> 
</span><del>-    if (CallEdgeLog::isEnabled() &amp;&amp; shouldEmitProfiling()
-        &amp;&amp; Options::baselineDoesCallEdgeProfiling()) {
-        m_vm-&gt;ensureCallEdgeLog().emitLogCode(
-            *this, info-&gt;callEdgeProfile, JSValueRegs(regT1, regT0));
-    }
-
</del><span class="cx">     if (opcodeID == op_call_eval) {
</span><span class="cx">         compileCallEval(instruction);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -770,47 +770,12 @@
</span><span class="cx">     return virtualForWithFunction(execCallee, kind, registers, calleeAsFunctionCellIgnored);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool attemptToOptimizeClosureCall(
-    ExecState* execCallee, RegisterPreservationMode registers, JSCell* calleeAsFunctionCell,
-    CallLinkInfo&amp; callLinkInfo)
</del><ins>+char* JIT_OPERATION operationLinkPolymorphicCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
</ins><span class="cx"> {
</span><del>-    if (!calleeAsFunctionCell)
-        return false;
-    
-    JSFunction* callee = jsCast&lt;JSFunction*&gt;(calleeAsFunctionCell);
-    JSFunction* oldCallee = callLinkInfo.callee.get();
-    
-    if (!oldCallee || oldCallee-&gt;executable() != callee-&gt;executable())
-        return false;
-    
-    ASSERT(callee-&gt;executable()-&gt;hasJITCodeForCall());
-    MacroAssemblerCodePtr codePtr =
-        callee-&gt;executable()-&gt;generatedJITCodeForCall()-&gt;addressForCall(
-            *execCallee-&gt;callerFrame()-&gt;codeBlock()-&gt;vm(), callee-&gt;executable(),
-            ArityCheckNotRequired, registers);
-    
-    CodeBlock* codeBlock;
-    if (callee-&gt;executable()-&gt;isHostFunction())
-        codeBlock = 0;
-    else {
-        codeBlock = jsCast&lt;FunctionExecutable*&gt;(callee-&gt;executable())-&gt;codeBlockForCall();
-        if (execCallee-&gt;argumentCountIncludingThis() &lt; static_cast&lt;size_t&gt;(codeBlock-&gt;numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs || callLinkInfo.callType == CallLinkInfo::ConstructVarargs)
-            return false;
-    }
-    
-    linkClosureCall(
-        execCallee, callLinkInfo, codeBlock, callee-&gt;executable(), codePtr, registers);
-    
-    return true;
-}
-
-char* JIT_OPERATION operationLinkClosureCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
-{
</del><span class="cx">     JSCell* calleeAsFunctionCell;
</span><span class="cx">     char* result = virtualForWithFunction(execCallee, CodeForCall, RegisterPreservationNotRequired, calleeAsFunctionCell);
</span><span class="cx"> 
</span><del>-    if (!attemptToOptimizeClosureCall(execCallee, RegisterPreservationNotRequired, calleeAsFunctionCell, *callLinkInfo))
-        linkSlowFor(execCallee, *callLinkInfo, CodeForCall, RegisterPreservationNotRequired);
</del><ins>+    linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell), RegisterPreservationNotRequired);
</ins><span class="cx">     
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -825,13 +790,12 @@
</span><span class="cx">     return virtualFor(execCallee, CodeForConstruct, RegisterPreservationNotRequired);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-char* JIT_OPERATION operationLinkClosureCallThatPreservesRegs(ExecState* execCallee, CallLinkInfo* callLinkInfo)
</del><ins>+char* JIT_OPERATION operationLinkPolymorphicCallThatPreservesRegs(ExecState* execCallee, CallLinkInfo* callLinkInfo)
</ins><span class="cx"> {
</span><span class="cx">     JSCell* calleeAsFunctionCell;
</span><span class="cx">     char* result = virtualForWithFunction(execCallee, CodeForCall, MustPreserveRegisters, calleeAsFunctionCell);
</span><span class="cx"> 
</span><del>-    if (!attemptToOptimizeClosureCall(execCallee, MustPreserveRegisters, calleeAsFunctionCell, *callLinkInfo))
-        linkSlowFor(execCallee, *callLinkInfo, CodeForCall, MustPreserveRegisters);
</del><ins>+    linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell), MustPreserveRegisters);
</ins><span class="cx">     
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -1027,6 +991,10 @@
</span><span class="cx">     DeferGCForAWhile deferGC(vm.heap);
</span><span class="cx">     
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><ins>+    if (codeBlock-&gt;jitType() != JITCode::BaselineJIT) {
+        dataLog(&quot;Unexpected code block in Baseline-&gt;DFG tier-up: &quot;, *codeBlock, &quot;\n&quot;);
+        RELEASE_ASSERT_NOT_REACHED();
+    }
</ins><span class="cx">     
</span><span class="cx">     if (bytecodeIndex) {
</span><span class="cx">         // If we're attempting to OSR from a loop, assume that this should be
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -246,12 +246,12 @@
</span><span class="cx"> void JIT_OPERATION operationDirectPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationCallEval(ExecState*, ExecState*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationLinkCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><del>-char* JIT_OPERATION operationLinkClosureCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</del><ins>+char* JIT_OPERATION operationLinkPolymorphicCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</ins><span class="cx"> char* JIT_OPERATION operationVirtualCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationVirtualConstruct(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationLinkConstruct(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationLinkCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><del>-char* JIT_OPERATION operationLinkClosureCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</del><ins>+char* JIT_OPERATION operationLinkPolymorphicCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</ins><span class="cx"> char* JIT_OPERATION operationVirtualCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationVirtualConstructThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationLinkConstructThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
</span><span class="lines">@@ -391,13 +391,13 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline P_JITOperation_ECli operationLinkClosureCallFor(RegisterPreservationMode registers)
</del><ins>+inline P_JITOperation_ECli operationLinkPolymorphicCallFor(RegisterPreservationMode registers)
</ins><span class="cx"> {
</span><span class="cx">     switch (registers) {
</span><span class="cx">     case RegisterPreservationNotRequired:
</span><del>-        return operationLinkClosureCall;
</del><ins>+        return operationLinkPolymorphicCall;
</ins><span class="cx">     case MustPreserveRegisters:
</span><del>-        return operationLinkClosureCallThatPreservesRegs;
</del><ins>+        return operationLinkPolymorphicCallThatPreservesRegs;
</ins><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     return 0;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITStubRoutineh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITStubRoutine.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITStubRoutine.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/JITStubRoutine.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -141,6 +141,9 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    // Return true if you are still valid after. Return false if you are now invalid. If you return
+    // false, you will usually not do any clearing because the idea is that you will simply be
+    // destroyed.
</ins><span class="cx">     virtual bool visitWeak(RepatchBuffer&amp;);
</span><span class="cx"> 
</span><span class="cx"> protected:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWriteBarrierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITWriteBarrier.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWriteBarrier.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/JITWriteBarrier.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><span class="cx"> #include &quot;SlotVisitor.h&quot;
</span><span class="cx"> #include &quot;UnusedPointer.h&quot;
</span><ins>+#include &quot;VM.h&quot;
</ins><span class="cx"> #include &quot;WriteBarrier.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitPolymorphicCallStubRoutinecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp (0 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;PolymorphicCallStubRoutine.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;CallLinkInfo.h&quot;
+#include &quot;CodeBlock.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;LinkBuffer.h&quot;
+
+namespace JSC {
+
+PolymorphicCallNode::~PolymorphicCallNode()
+{
+    if (isOnList())
+        remove();
+}
+
+void PolymorphicCallNode::unlink(RepatchBuffer&amp; repatchBuffer)
+{
+    if (Options::showDisassembly())
+        dataLog(&quot;Unlinking polymorphic call at &quot;, m_callLinkInfo-&gt;callReturnLocation, &quot;, &quot;, m_callLinkInfo-&gt;codeOrigin, &quot;\n&quot;);
+    
+    m_callLinkInfo-&gt;unlink(repatchBuffer);
+    
+    if (isOnList())
+        remove();
+}
+
+void PolymorphicCallCase::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;&lt;variant = &quot;, m_variant, &quot;, codeBlock = &quot;, pointerDump(m_codeBlock), &quot;&gt;&quot;);
+}
+
+PolymorphicCallStubRoutine::PolymorphicCallStubRoutine(
+    const MacroAssemblerCodeRef&amp; codeRef, VM&amp; vm, const JSCell* owner, ExecState* callerFrame,
+    CallLinkInfo&amp; info, const Vector&lt;PolymorphicCallCase&gt;&amp; cases,
+    std::unique_ptr&lt;uint32_t[]&gt; fastCounts)
+    : GCAwareJITStubRoutine(codeRef, vm)
+    , m_fastCounts(WTF::move(fastCounts))
+{
+    for (PolymorphicCallCase callCase : cases) {
+        m_variants.append(WriteBarrier&lt;JSCell&gt;(vm, owner, callCase.variant().rawCalleeCell()));
+        if (shouldShowDisassemblyFor(callerFrame-&gt;codeBlock()))
+            dataLog(&quot;Linking polymorphic call in &quot;, *callerFrame-&gt;codeBlock(), &quot; at &quot;, callerFrame-&gt;codeOrigin(), &quot; to &quot;, callCase.variant(), &quot;, codeBlock = &quot;, pointerDump(callCase.codeBlock()), &quot;\n&quot;);
+        if (CodeBlock* codeBlock = callCase.codeBlock())
+            codeBlock-&gt;linkIncomingPolymorphicCall(callerFrame, m_callNodes.add(&amp;info));
+    }
+    m_variants.shrinkToFit();
+    WTF::storeStoreFence();
+}
+
+PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine() { }
+
+CallVariantList PolymorphicCallStubRoutine::variants() const
+{
+    CallVariantList result;
+    for (size_t i = 0; i &lt; m_variants.size(); ++i)
+        result.append(CallVariant(m_variants[i].get()));
+    return result;
+}
+
+CallEdgeList PolymorphicCallStubRoutine::edges() const
+{
+    // We wouldn't have these if this was an FTL stub routine. We shouldn't be asking for profiling
+    // from the FTL.
+    RELEASE_ASSERT(m_fastCounts);
+    
+    CallEdgeList result;
+    for (size_t i = 0; i &lt; m_variants.size(); ++i)
+        result.append(CallEdge(CallVariant(m_variants[i].get()), m_fastCounts[i]));
+    return result;
+}
+
+bool PolymorphicCallStubRoutine::visitWeak(RepatchBuffer&amp;)
+{
+    for (auto&amp; variant : m_variants) {
+        if (!Heap::isMarked(variant.get()))
+            return false;
+    }
+    return true;
+}
+
+void PolymorphicCallStubRoutine::markRequiredObjectsInternal(SlotVisitor&amp; visitor)
+{
+    for (auto&amp; variant : m_variants)
+        visitor.append(&amp;variant);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitPolymorphicCallStubRoutineh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h (0 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -0,0 +1,110 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef PolymorphicCallStubRoutine_h
+#define PolymorphicCallStubRoutine_h
+
+#if ENABLE(JIT)
+
+#include &quot;CallEdge.h&quot;
+#include &quot;CallVariant.h&quot;
+#include &quot;CodeOrigin.h&quot;
+#include &quot;GCAwareJITStubRoutine.h&quot;
+#include &lt;wtf/FastMalloc.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+struct CallLinkInfo;
+
+class PolymorphicCallNode : public BasicRawSentinelNode&lt;PolymorphicCallNode&gt; {
+    WTF_MAKE_NONCOPYABLE(PolymorphicCallNode);
+public:
+    PolymorphicCallNode(CallLinkInfo* info)
+        : m_callLinkInfo(info)
+    {
+    }
+    
+    ~PolymorphicCallNode();
+    
+    void unlink(RepatchBuffer&amp;);
+    
+private:
+    CallLinkInfo* m_callLinkInfo;
+};
+
+class PolymorphicCallCase {
+public:
+    PolymorphicCallCase()
+        : m_codeBlock(nullptr)
+    {
+    }
+    
+    PolymorphicCallCase(CallVariant variant, CodeBlock* codeBlock)
+        : m_variant(variant)
+        , m_codeBlock(codeBlock)
+    {
+    }
+    
+    CallVariant variant() const { return m_variant; }
+    CodeBlock* codeBlock() const { return m_codeBlock; }
+    
+    void dump(PrintStream&amp;) const;
+    
+private:
+    CallVariant m_variant;
+    CodeBlock* m_codeBlock;
+};
+
+class PolymorphicCallStubRoutine : public GCAwareJITStubRoutine {
+public:
+    PolymorphicCallStubRoutine(
+        const MacroAssemblerCodeRef&amp;, VM&amp;, const JSCell* owner,
+        ExecState* callerFrame, CallLinkInfo&amp;, const Vector&lt;PolymorphicCallCase&gt;&amp;,
+        std::unique_ptr&lt;uint32_t[]&gt; fastCounts);
+    
+    virtual ~PolymorphicCallStubRoutine();
+    
+    CallVariantList variants() const;
+    CallEdgeList edges() const;
+    
+    bool visitWeak(RepatchBuffer&amp;) override;
+
+protected:
+    virtual void markRequiredObjectsInternal(SlotVisitor&amp;) override;
+
+private:
+    Vector&lt;WriteBarrier&lt;JSCell&gt;, 2&gt; m_variants;
+    std::unique_ptr&lt;uint32_t[]&gt; m_fastCounts;
+    Bag&lt;PolymorphicCallNode&gt; m_callNodes;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // PolymorphicCallStubRoutine_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AccessorCallJITStubRoutine.h&quot;
</span><ins>+#include &quot;BinarySwitch.h&quot;
</ins><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="cx"> #include &quot;DFGSpeculativeJIT.h&quot;
</span><span class="lines">@@ -1575,12 +1576,17 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void linkSlowFor(
</span><ins>+    RepatchBuffer&amp; repatchBuffer, VM* vm, CallLinkInfo&amp; callLinkInfo, ThunkGenerator generator)
+{
+    repatchBuffer.relink(
+        callLinkInfo.callReturnLocation, vm-&gt;getCTIStub(generator).code());
+}
+
+static void linkSlowFor(
</ins><span class="cx">     RepatchBuffer&amp; repatchBuffer, VM* vm, CallLinkInfo&amp; callLinkInfo,
</span><span class="cx">     CodeSpecializationKind kind, RegisterPreservationMode registers)
</span><span class="cx"> {
</span><del>-    repatchBuffer.relink(
-        callLinkInfo.callReturnLocation,
-        vm-&gt;getCTIStub(virtualThunkGeneratorFor(kind, registers)).code());
</del><ins>+    linkSlowFor(repatchBuffer, vm, callLinkInfo, virtualThunkGeneratorFor(kind, registers));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void linkFor(
</span><span class="lines">@@ -1592,10 +1598,6 @@
</span><span class="cx">     
</span><span class="cx">     CodeBlock* callerCodeBlock = exec-&gt;callerFrame()-&gt;codeBlock();
</span><span class="cx"> 
</span><del>-    // If you're being call-linked from a DFG caller then you obviously didn't get inlined.
-    if (calleeCodeBlock &amp;&amp; JITCode::isOptimizingJIT(callerCodeBlock-&gt;jitType()))
-        calleeCodeBlock-&gt;m_shouldAlwaysBeInlined = false;
-    
</del><span class="cx">     VM* vm = callerCodeBlock-&gt;vm();
</span><span class="cx">     
</span><span class="cx">     RepatchBuffer repatchBuffer(callerCodeBlock);
</span><span class="lines">@@ -1611,7 +1613,8 @@
</span><span class="cx">         calleeCodeBlock-&gt;linkIncomingCall(exec-&gt;callerFrame(), &amp;callLinkInfo);
</span><span class="cx">     
</span><span class="cx">     if (kind == CodeForCall) {
</span><del>-        repatchBuffer.relink(callLinkInfo.callReturnLocation, vm-&gt;getCTIStub(linkClosureCallThunkGeneratorFor(registers)).code());
</del><ins>+        linkSlowFor(
+            repatchBuffer, vm, callLinkInfo, linkPolymorphicCallThunkGeneratorFor(registers));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1631,16 +1634,122 @@
</span><span class="cx">     linkSlowFor(repatchBuffer, vm, callLinkInfo, kind, registers);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void linkClosureCall(
-    ExecState* exec, CallLinkInfo&amp; callLinkInfo, CodeBlock* calleeCodeBlock, 
-    ExecutableBase* executable, MacroAssemblerCodePtr codePtr,
</del><ins>+static void revertCall(
+    RepatchBuffer&amp; repatchBuffer, VM* vm, CallLinkInfo&amp; callLinkInfo, ThunkGenerator generator)
+{
+    repatchBuffer.revertJumpReplacementToBranchPtrWithPatch(
+        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin),
+        static_cast&lt;MacroAssembler::RegisterID&gt;(callLinkInfo.calleeGPR), 0);
+    linkSlowFor(repatchBuffer, vm, callLinkInfo, generator);
+    callLinkInfo.hasSeenShouldRepatch = false;
+    callLinkInfo.callee.clear();
+    callLinkInfo.stub.clear();
+    if (callLinkInfo.isOnList())
+        callLinkInfo.remove();
+}
+
+void unlinkFor(
+    RepatchBuffer&amp; repatchBuffer, CallLinkInfo&amp; callLinkInfo,
+    CodeSpecializationKind kind, RegisterPreservationMode registers)
+{
+    if (Options::showDisassembly())
+        dataLog(&quot;Unlinking call from &quot;, callLinkInfo.callReturnLocation, &quot; in request from &quot;, pointerDump(repatchBuffer.codeBlock()), &quot;\n&quot;);
+    
+    revertCall(
+        repatchBuffer, repatchBuffer.codeBlock()-&gt;vm(), callLinkInfo,
+        linkThunkGeneratorFor(kind, registers));
+}
+
+void linkVirtualFor(
+    ExecState* exec, CallLinkInfo&amp; callLinkInfo,
+    CodeSpecializationKind kind, RegisterPreservationMode registers)
+{
+    // FIXME: We could generate a virtual call stub here. This would lead to faster virtual calls
+    // by eliminating the branch prediction bottleneck inside the shared virtual call thunk.
+    
+    CodeBlock* callerCodeBlock = exec-&gt;callerFrame()-&gt;codeBlock();
+    VM* vm = callerCodeBlock-&gt;vm();
+    
+    if (shouldShowDisassemblyFor(callerCodeBlock))
+        dataLog(&quot;Linking virtual call at &quot;, *callerCodeBlock, &quot; &quot;, exec-&gt;callerFrame()-&gt;codeOrigin(), &quot;\n&quot;);
+    
+    RepatchBuffer repatchBuffer(callerCodeBlock);
+    revertCall(repatchBuffer, vm, callLinkInfo, virtualThunkGeneratorFor(kind, registers));
+}
+
+namespace {
+struct CallToCodePtr {
+    CCallHelpers::Call call;
+    MacroAssemblerCodePtr codePtr;
+};
+} // annonymous namespace
+
+void linkPolymorphicCall(
+    ExecState* exec, CallLinkInfo&amp; callLinkInfo, CallVariant newVariant,
</ins><span class="cx">     RegisterPreservationMode registers)
</span><span class="cx"> {
</span><del>-    ASSERT(!callLinkInfo.stub);
</del><ins>+    // Currently we can't do anything for non-function callees.
+    // https://bugs.webkit.org/show_bug.cgi?id=140685
+    if (!newVariant || !newVariant.executable()) {
+        linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+        return;
+    }
</ins><span class="cx">     
</span><span class="cx">     CodeBlock* callerCodeBlock = exec-&gt;callerFrame()-&gt;codeBlock();
</span><span class="cx">     VM* vm = callerCodeBlock-&gt;vm();
</span><span class="cx">     
</span><ins>+    CallVariantList list;
+    if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub.get())
+        list = stub-&gt;variants();
+    else if (JSFunction* oldCallee = callLinkInfo.callee.get())
+        list = CallVariantList{ CallVariant(oldCallee) };
+    
+    list = variantListWithVariant(list, newVariant);
+
+    // If there are any closure calls then it makes sense to treat all of them as closure calls.
+    // This makes switching on callee cheaper. It also produces profiling that's easier on the DFG;
+    // the DFG doesn't really want to deal with a combination of closure and non-closure callees.
+    bool isClosureCall = false;
+    for (CallVariant variant : list)  {
+        if (variant.isClosureCall()) {
+            list = despecifiedVariantList(list);
+            isClosureCall = true;
+            break;
+        }
+    }
+    
+    Vector&lt;PolymorphicCallCase&gt; callCases;
+    
+    // Figure out what our cases are.
+    for (CallVariant variant : list) {
+        CodeBlock* codeBlock;
+        if (variant.executable()-&gt;isHostFunction())
+            codeBlock = nullptr;
+        else {
+            codeBlock = jsCast&lt;FunctionExecutable*&gt;(variant.executable())-&gt;codeBlockForCall();
+            
+            // If we cannot handle a callee, assume that it's better for this whole thing to be a
+            // virtual call.
+            if (exec-&gt;argumentCountIncludingThis() &lt; static_cast&lt;size_t&gt;(codeBlock-&gt;numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs || callLinkInfo.callType == CallLinkInfo::ConstructVarargs) {
+                linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+                return;
+            }
+        }
+        
+        callCases.append(PolymorphicCallCase(variant, codeBlock));
+    }
+    
+    // If we are over the limit, just use a normal virtual call.
+    unsigned maxPolymorphicCallVariantListSize;
+    if (callerCodeBlock-&gt;jitType() == JITCode::topTierJIT())
+        maxPolymorphicCallVariantListSize = Options::maxPolymorphicCallVariantListSizeForTopTier();
+    else
+        maxPolymorphicCallVariantListSize = Options::maxPolymorphicCallVariantListSize();
+    if (list.size() &gt; maxPolymorphicCallVariantListSize) {
+        linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+        return;
+    }
+    
</ins><span class="cx">     GPRReg calleeGPR = static_cast&lt;GPRReg&gt;(callLinkInfo.calleeGPR);
</span><span class="cx">     
</span><span class="cx">     CCallHelpers stubJit(vm, callerCodeBlock);
</span><span class="lines">@@ -1655,33 +1764,82 @@
</span><span class="cx">         stubJit.abortWithReason(RepatchInsaneArgumentCount);
</span><span class="cx">         okArgumentCount.link(&amp;stubJit);
</span><span class="cx">     }
</span><ins>+    
+    GPRReg scratch = AssemblyHelpers::selectScratchGPR(calleeGPR);
+    GPRReg comparisonValueGPR;
+    
+    if (isClosureCall) {
+        // Verify that we have a function and stash the executable in scratch.
</ins><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-    // We can safely clobber everything except the calleeGPR. We can't rely on tagMaskRegister
-    // being set. So we do this the hard way.
-    GPRReg scratch = AssemblyHelpers::selectScratchGPR(calleeGPR);
-    stubJit.move(MacroAssembler::TrustedImm64(TagMask), scratch);
-    slowPath.append(stubJit.branchTest64(CCallHelpers::NonZero, calleeGPR, scratch));
</del><ins>+        // We can safely clobber everything except the calleeGPR. We can't rely on tagMaskRegister
+        // being set. So we do this the hard way.
+        stubJit.move(MacroAssembler::TrustedImm64(TagMask), scratch);
+        slowPath.append(stubJit.branchTest64(CCallHelpers::NonZero, calleeGPR, scratch));
</ins><span class="cx"> #else
</span><del>-    // We would have already checked that the callee is a cell.
</del><ins>+        // We would have already checked that the callee is a cell.
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><del>-    slowPath.append(
-        stubJit.branch8(
-            CCallHelpers::NotEqual,
-            CCallHelpers::Address(calleeGPR, JSCell::typeInfoTypeOffset()),
-            CCallHelpers::TrustedImm32(JSFunctionType)));
</del><ins>+        slowPath.append(
+            stubJit.branch8(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(calleeGPR, JSCell::typeInfoTypeOffset()),
+                CCallHelpers::TrustedImm32(JSFunctionType)));
</ins><span class="cx">     
</span><del>-    slowPath.append(
-        stubJit.branchPtr(
-            CCallHelpers::NotEqual,
</del><ins>+        stubJit.loadPtr(
</ins><span class="cx">             CCallHelpers::Address(calleeGPR, JSFunction::offsetOfExecutable()),
</span><del>-            CCallHelpers::TrustedImmPtr(executable)));
</del><ins>+            scratch);
+        
+        comparisonValueGPR = scratch;
+    } else
+        comparisonValueGPR = calleeGPR;
</ins><span class="cx">     
</span><del>-    AssemblyHelpers::Call call = stubJit.nearCall();
-    AssemblyHelpers::Jump done = stubJit.jump();
</del><ins>+    Vector&lt;int64_t&gt; caseValues(callCases.size());
+    Vector&lt;CallToCodePtr&gt; calls(callCases.size());
+    std::unique_ptr&lt;uint32_t[]&gt; fastCounts;
</ins><span class="cx">     
</span><ins>+    if (callerCodeBlock-&gt;jitType() != JITCode::topTierJIT())
+        fastCounts = std::make_unique&lt;uint32_t[]&gt;(callCases.size());
+    
+    for (size_t i = callCases.size(); i--;) {
+        if (fastCounts)
+            fastCounts[i] = 0;
+        
+        CallVariant variant = callCases[i].variant();
+        if (isClosureCall)
+            caseValues[i] = bitwise_cast&lt;intptr_t&gt;(variant.executable());
+        else
+            caseValues[i] = bitwise_cast&lt;intptr_t&gt;(variant.function());
+    }
+    
+    GPRReg fastCountsBaseGPR =
+        AssemblyHelpers::selectScratchGPR(calleeGPR, comparisonValueGPR, GPRInfo::regT3);
+    stubJit.move(CCallHelpers::TrustedImmPtr(fastCounts.get()), fastCountsBaseGPR);
+    
+    BinarySwitch binarySwitch(comparisonValueGPR, caseValues, BinarySwitch::IntPtr);
+    CCallHelpers::JumpList done;
+    while (binarySwitch.advance(stubJit)) {
+        size_t caseIndex = binarySwitch.caseIndex();
+        
+        CallVariant variant = callCases[caseIndex].variant();
+        
+        ASSERT(variant.executable()-&gt;hasJITCodeForCall());
+        MacroAssemblerCodePtr codePtr =
+            variant.executable()-&gt;generatedJITCodeForCall()-&gt;addressForCall(
+                *vm, variant.executable(), ArityCheckNotRequired, registers);
+        
+        if (fastCounts) {
+            stubJit.add32(
+                CCallHelpers::TrustedImm32(1),
+                CCallHelpers::Address(fastCountsBaseGPR, caseIndex * sizeof(uint32_t)));
+        }
+        calls[caseIndex].call = stubJit.nearCall();
+        calls[caseIndex].codePtr = codePtr;
+        done.append(stubJit.jump());
+    }
+    
</ins><span class="cx">     slowPath.link(&amp;stubJit);
</span><ins>+    binarySwitch.fallThrough().link(&amp;stubJit);
</ins><span class="cx">     stubJit.move(calleeGPR, GPRInfo::regT0);
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx">     stubJit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::regT1);
</span><span class="lines">@@ -1691,34 +1849,45 @@
</span><span class="cx">     
</span><span class="cx">     stubJit.restoreReturnAddressBeforeReturn(GPRInfo::regT4);
</span><span class="cx">     AssemblyHelpers::Jump slow = stubJit.jump();
</span><del>-    
</del><ins>+        
</ins><span class="cx">     LinkBuffer patchBuffer(*vm, stubJit, callerCodeBlock);
</span><span class="cx">     
</span><del>-    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
</del><ins>+    RELEASE_ASSERT(callCases.size() == calls.size());
+    for (CallToCodePtr callToCodePtr : calls) {
+        patchBuffer.link(
+            callToCodePtr.call, FunctionPtr(callToCodePtr.codePtr.executableAddress()));
+    }
</ins><span class="cx">     if (JITCode::isOptimizingJIT(callerCodeBlock-&gt;jitType()))
</span><span class="cx">         patchBuffer.link(done, callLinkInfo.callReturnLocation.labelAtOffset(0));
</span><span class="cx">     else
</span><span class="cx">         patchBuffer.link(done, callLinkInfo.hotPathOther.labelAtOffset(0));
</span><del>-    patchBuffer.link(slow, CodeLocationLabel(vm-&gt;getCTIStub(virtualThunkGeneratorFor(CodeForCall, registers)).code()));
</del><ins>+    patchBuffer.link(slow, CodeLocationLabel(vm-&gt;getCTIStub(linkPolymorphicCallThunkGeneratorFor(registers)).code()));
</ins><span class="cx">     
</span><del>-    RefPtr&lt;ClosureCallStubRoutine&gt; stubRoutine = adoptRef(new ClosureCallStubRoutine(
</del><ins>+    RefPtr&lt;PolymorphicCallStubRoutine&gt; stubRoutine = adoptRef(new PolymorphicCallStubRoutine(
</ins><span class="cx">         FINALIZE_CODE_FOR(
</span><span class="cx">             callerCodeBlock, patchBuffer,
</span><del>-            (&quot;Closure call stub for %s, return point %p, target %p (%s)&quot;,
</del><ins>+            (&quot;Polymorphic call stub for %s, return point %p, targets %s&quot;,
</ins><span class="cx">                 toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation.labelAtOffset(0).executableAddress(),
</span><del>-                codePtr.executableAddress(), toCString(pointerDump(calleeCodeBlock)).data())),
-        *vm, callerCodeBlock-&gt;ownerExecutable(), executable));
</del><ins>+                toCString(listDump(callCases)).data())),
+        *vm, callerCodeBlock-&gt;ownerExecutable(), exec-&gt;callerFrame(), callLinkInfo, callCases,
+        WTF::move(fastCounts)));
</ins><span class="cx">     
</span><span class="cx">     RepatchBuffer repatchBuffer(callerCodeBlock);
</span><span class="cx">     
</span><span class="cx">     repatchBuffer.replaceWithJump(
</span><span class="cx">         RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin),
</span><span class="cx">         CodeLocationLabel(stubRoutine-&gt;code().code()));
</span><ins>+    // This is weird. The original slow path should no longer be reachable.
</ins><span class="cx">     linkSlowFor(repatchBuffer, vm, callLinkInfo, CodeForCall, registers);
</span><span class="cx">     
</span><ins>+    // If there had been a previous stub routine, that one will die as soon as the GC runs and sees
+    // that it's no longer on stack.
</ins><span class="cx">     callLinkInfo.stub = stubRoutine.release();
</span><span class="cx">     
</span><del>-    ASSERT(!calleeCodeBlock || calleeCodeBlock-&gt;isIncomingCallAlreadyLinked(&amp;callLinkInfo));
</del><ins>+    // The call link info no longer has a call cache apart from the jump to the polymorphic call
+    // stub.
+    if (callLinkInfo.isOnList())
+        callLinkInfo.remove();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void resetGetByID(RepatchBuffer&amp; repatchBuffer, StructureStubInfo&amp; stubInfo)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/Repatch.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><ins>+#include &quot;CallVariant.h&quot;
</ins><span class="cx"> #include &quot;JITOperations.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -41,7 +42,9 @@
</span><span class="cx"> void repatchIn(ExecState*, JSCell*, const Identifier&amp;, bool wasFound, const PropertySlot&amp;, StructureStubInfo&amp;);
</span><span class="cx"> void linkFor(ExecState*, CallLinkInfo&amp;, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr, CodeSpecializationKind, RegisterPreservationMode);
</span><span class="cx"> void linkSlowFor(ExecState*, CallLinkInfo&amp;, CodeSpecializationKind, RegisterPreservationMode);
</span><del>-void linkClosureCall(ExecState*, CallLinkInfo&amp;, CodeBlock*, ExecutableBase*, MacroAssemblerCodePtr, RegisterPreservationMode);
</del><ins>+void unlinkFor(RepatchBuffer&amp;, CallLinkInfo&amp;, CodeSpecializationKind, RegisterPreservationMode);
+void linkVirtualFor(ExecState*, CallLinkInfo&amp;, CodeSpecializationKind, RegisterPreservationMode);
+void linkPolymorphicCall(ExecState*, CallLinkInfo&amp;, CallVariant, RegisterPreservationMode);
</ins><span class="cx"> void resetGetByID(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span><span class="cx"> void resetPutByID(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span><span class="cx"> void resetIn(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -137,27 +137,27 @@
</span><span class="cx">     return linkForThunkGenerator(vm, CodeForConstruct, MustPreserveRegisters);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static MacroAssemblerCodeRef linkClosureCallForThunkGenerator(
</del><ins>+static MacroAssemblerCodeRef linkPolymorphicCallForThunkGenerator(
</ins><span class="cx">     VM* vm, RegisterPreservationMode registers)
</span><span class="cx"> {
</span><span class="cx">     CCallHelpers jit(vm);
</span><span class="cx">     
</span><del>-    slowPathFor(jit, vm, operationLinkClosureCallFor(registers));
</del><ins>+    slowPathFor(jit, vm, operationLinkPolymorphicCallFor(registers));
</ins><span class="cx">     
</span><span class="cx">     LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID);
</span><del>-    return FINALIZE_CODE(patchBuffer, (&quot;Link closure call %s slow path thunk&quot;, registers == MustPreserveRegisters ? &quot; that preserves registers&quot; : &quot;&quot;));
</del><ins>+    return FINALIZE_CODE(patchBuffer, (&quot;Link polymorphic call %s slow path thunk&quot;, registers == MustPreserveRegisters ? &quot; that preserves registers&quot; : &quot;&quot;));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // For closure optimizations, we only include calls, since if you're using closures for
</span><span class="cx"> // object construction then you're going to lose big time anyway.
</span><del>-MacroAssemblerCodeRef linkClosureCallThunkGenerator(VM* vm)
</del><ins>+MacroAssemblerCodeRef linkPolymorphicCallThunkGenerator(VM* vm)
</ins><span class="cx"> {
</span><del>-    return linkClosureCallForThunkGenerator(vm, RegisterPreservationNotRequired);
</del><ins>+    return linkPolymorphicCallForThunkGenerator(vm, RegisterPreservationNotRequired);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-MacroAssemblerCodeRef linkClosureCallThatPreservesRegsThunkGenerator(VM* vm)
</del><ins>+MacroAssemblerCodeRef linkPolymorphicCallThatPreservesRegsThunkGenerator(VM* vm)
</ins><span class="cx"> {
</span><del>-    return linkClosureCallForThunkGenerator(vm, MustPreserveRegisters);
</del><ins>+    return linkPolymorphicCallForThunkGenerator(vm, MustPreserveRegisters);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static MacroAssemblerCodeRef virtualForThunkGenerator(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -65,16 +65,16 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-MacroAssemblerCodeRef linkClosureCallThunkGenerator(VM*);
-MacroAssemblerCodeRef linkClosureCallThatPreservesRegsThunkGenerator(VM*);
</del><ins>+MacroAssemblerCodeRef linkPolymorphicCallThunkGenerator(VM*);
+MacroAssemblerCodeRef linkPolymorphicCallThatPreservesRegsThunkGenerator(VM*);
</ins><span class="cx"> 
</span><del>-inline ThunkGenerator linkClosureCallThunkGeneratorFor(RegisterPreservationMode registers)
</del><ins>+inline ThunkGenerator linkPolymorphicCallThunkGeneratorFor(RegisterPreservationMode registers)
</ins><span class="cx"> {
</span><span class="cx">     switch (registers) {
</span><span class="cx">     case RegisterPreservationNotRequired:
</span><del>-        return linkClosureCallThunkGenerator;
</del><ins>+        return linkPolymorphicCallThunkGenerator;
</ins><span class="cx">     case MustPreserveRegisters:
</span><del>-        return linkClosureCallThatPreservesRegsThunkGenerator;
</del><ins>+        return linkPolymorphicCallThatPreservesRegsThunkGenerator;
</ins><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     return 0;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -332,6 +332,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     default:
</span><ins>+        dataLog(&quot;Unexpected code block in LLInt: &quot;, *codeBlock, &quot;\n&quot;);
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -170,12 +170,11 @@
</span><span class="cx">     v(bool, enablePolyvariantDevirtualization, true) \
</span><span class="cx">     v(bool, enablePolymorphicAccessInlining, true) \
</span><span class="cx">     v(bool, enablePolymorphicCallInlining, true) \
</span><del>-    v(bool, callStatusShouldUseCallEdgeProfile, true) \
-    v(bool, callEdgeProfileReallyProcessesLog, true) \
-    v(bool, baselineDoesCallEdgeProfiling, false) \
-    v(bool, dfgDoesCallEdgeProfiling, true) \
-    v(bool, enableCallEdgeProfiling, true) \
</del><ins>+    v(unsigned, maxPolymorphicCallVariantListSize, 15) \
+    v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5) \
+    v(unsigned, maxPolymorphicCallVariantsForInlining, 5) \
</ins><span class="cx">     v(unsigned, frequentCallThreshold, 2) \
</span><ins>+    v(double, minimumCallToKnownRate, 0.51) \
</ins><span class="cx">     v(bool, optimizeNativeCalls, false) \
</span><span class="cx">     v(bool, enableObjectAllocationSinking, true) \
</span><span class="cx">     \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -370,13 +370,6 @@
</span><span class="cx">     return sharedInstance;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-CallEdgeLog&amp; VM::ensureCallEdgeLog()
-{
-    if (!callEdgeLog)
-        callEdgeLog = std::make_unique&lt;CallEdgeLog&gt;();
-    return *callEdgeLog;
-}
-
</del><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
</span><span class="cx"> {
</span><span class="lines">@@ -460,9 +453,6 @@
</span><span class="cx"> 
</span><span class="cx"> void VM::prepareToDiscardCode()
</span><span class="cx"> {
</span><del>-    if (callEdgeLog)
-        callEdgeLog-&gt;processLog();
-    
</del><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     for (unsigned i = DFG::numberOfWorklists(); i--;) {
</span><span class="cx">         if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (179477 => 179478)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2015-02-02 18:15:44 UTC (rev 179477)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2015-02-02 18:38:08 UTC (rev 179478)
</span><span class="lines">@@ -73,7 +73,6 @@
</span><span class="cx"> 
</span><span class="cx"> class ArityCheckFailReturnThunks;
</span><span class="cx"> class BuiltinExecutables;
</span><del>-class CallEdgeLog;
</del><span class="cx"> class CodeBlock;
</span><span class="cx"> class CodeCache;
</span><span class="cx"> class CommonIdentifiers;
</span><span class="lines">@@ -238,9 +237,6 @@
</span><span class="cx">     std::unique_ptr&lt;DFG::LongLivedState&gt; dfgState;
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;CallEdgeLog&gt; callEdgeLog;
-    CallEdgeLog&amp; ensureCallEdgeLog();
-
</del><span class="cx">     VMType vmType;
</span><span class="cx">     ClientData* clientData;
</span><span class="cx">     VMEntryFrame* topVMEntryFrame;
</span></span></pre>
</div>
</div>

</body>
</html>