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