Call linking slow paths should be passed a CallLinkInfo* directly so that you can create a call IC without adding it to any CodeBlocks
https://bugs.webkit.org/show_bug.cgi?id=130644

Reviewed by Andreas Kling.
        
This is conceptually a really simple change but it involves the following:
        
- The inline part of the call IC stuffs a pointer to the CallLinkInfo into regT2.
        
- CodeBlock uses a Bag of CallLinkInfos instead of a Vector.
        
- Remove the significance of a CallLinkInfo's index. This means that DFG::JITCode no
  longer has a vector of slow path counts that shadows the CallLinkInfo vector.
        
- Make CallLinkInfo have its own slowPathCount, which counts actual slow path executions
  and not all relinking.
        
This makes planting JS->JS calls inside other inline caches or stubs a lot easier, since
the CallLinkInfo and the call IC slow paths no longer rely on the call being associated
with a op_call/op_construct instruction and a machine code return PC within such an
instruction.

* bytecode/CallLinkInfo.h:
(JSC::getCallLinkInfoCodeOrigin):
* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::computeFor):
(JSC::CallLinkStatus::computeDFGStatuses):
* bytecode/CallLinkStatus.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printCallOp):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::getCallLinkInfoMap):
(JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
(JSC::CodeBlock::addCallLinkInfo):
(JSC::CodeBlock::unlinkCalls):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::stubInfoBegin):
(JSC::CodeBlock::stubInfoEnd):
(JSC::CodeBlock::callLinkInfosBegin):
(JSC::CodeBlock::callLinkInfosEnd):
(JSC::CodeBlock::byValInfo):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGJITCode.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addJSCall):
(JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
* ftl/FTLCompile.cpp:
(JSC::FTL::fixFunctionBasedOnStackMaps):
* ftl/FTLInlineCacheSize.cpp:
(JSC::FTL::sizeOfCall):
* ftl/FTLJSCall.cpp:
(JSC::FTL::JSCall::JSCall):
(JSC::FTL::JSCall::emit):
(JSC::FTL::JSCall::link):
* ftl/FTLJSCall.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::privateCompile):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
(JSC::operationLinkFor):
(JSC::operationVirtualFor):
(JSC::operationLinkClosureCallFor):
* jit/Repatch.cpp:
(JSC::linkClosureCall):
* jit/ThunkGenerators.cpp:
(JSC::slowPathFor):
(JSC::virtualForThunkGenerator):
* tests/stress/eval-that-is-not-eval.js: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@166135 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
index 804ecab..a80bcbe 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
@@ -115,7 +115,8 @@
 #endif
 }
 
-CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
+CallLinkStatus CallLinkStatus::computeFor(
+    CodeBlock* profiledBlock, unsigned bytecodeIndex, const CallLinkInfoMap& map)
 {
     ConcurrentJITLocker locker(profiledBlock->m_lock);
     
@@ -127,15 +128,11 @@
         || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable)))
         return takesSlowPath();
     
-    if (!profiledBlock->hasBaselineJITProfiling())
+    CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex));
+    if (!callLinkInfo)
         return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
     
-    if (profiledBlock->couldTakeSlowCase(bytecodeIndex))
-        return takesSlowPath();
-    
-    CallLinkInfo& callLinkInfo = profiledBlock->getCallLinkInfo(bytecodeIndex);
-    
-    CallLinkStatus result = computeFor(locker, callLinkInfo);
+    CallLinkStatus result = computeFor(locker, *callLinkInfo);
     if (!result)
         return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
     
@@ -151,6 +148,9 @@
 #if ENABLE(JIT)
 CallLinkStatus CallLinkStatus::computeFor(const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo)
 {
+    if (callLinkInfo.slowPathCount >= Options::couldTakeSlowCaseMinimumCount())
+        return takesSlowPath();
+    
     if (callLinkInfo.stub)
         return CallLinkStatus(callLinkInfo.stub->executable(), callLinkInfo.stub->structure());
     
@@ -171,11 +171,8 @@
 #if ENABLE(DFG_JIT)
     RELEASE_ASSERT(dfgCodeBlock->jitType() == JITCode::DFGJIT);
     CodeBlock* baselineCodeBlock = dfgCodeBlock->alternative();
-    DFG::JITCode* jitCode = dfgCodeBlock->jitCode()->dfg();
-    RELEASE_ASSERT(dfgCodeBlock->numberOfCallLinkInfos() <= jitCode->slowPathCalls.size());
-    
-    for (size_t i = dfgCodeBlock->numberOfCallLinkInfos(); i--;) {
-        CallLinkInfo& info = dfgCodeBlock->callLinkInfo(i);
+    for (auto iter = dfgCodeBlock->callLinkInfosBegin(); !!iter; ++iter) {
+        CallLinkInfo& info = **iter;
         CodeOrigin codeOrigin = info.codeOrigin;
         
         bool takeSlowPath;
@@ -202,7 +199,7 @@
         
         {
             ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
-            if (takeSlowPath || jitCode->slowPathCalls[i] >= Options::couldTakeSlowCaseMinimumCount())
+            if (takeSlowPath)
                 map.add(info.codeOrigin, takesSlowPath());
             else {
                 CallLinkStatus status = computeFor(locker, info);
@@ -230,13 +227,14 @@
 }
 
 CallLinkStatus CallLinkStatus::computeFor(
-    CodeBlock* profiledBlock, CodeOrigin codeOrigin, const CallLinkStatus::ContextMap& map)
+    CodeBlock* profiledBlock, CodeOrigin codeOrigin,
+    const CallLinkInfoMap& baselineMap, const CallLinkStatus::ContextMap& dfgMap)
 {
-    ContextMap::const_iterator iter = map.find(codeOrigin);
-    if (iter != map.end())
+    auto iter = dfgMap.find(codeOrigin);
+    if (iter != dfgMap.end())
         return iter->value;
     
-    return computeFor(profiledBlock, codeOrigin.bytecodeIndex);
+    return computeFor(profiledBlock, codeOrigin.bytecodeIndex, baselineMap);
 }
 
 void CallLinkStatus::dump(PrintStream& out) const