Modified: branches/ftlopt/Source/_javascript_Core/ChangeLog (169013 => 169014)
--- branches/ftlopt/Source/_javascript_Core/ChangeLog 2014-05-18 16:53:03 UTC (rev 169013)
+++ branches/ftlopt/Source/_javascript_Core/ChangeLog 2014-05-18 17:32:22 UTC (rev 169014)
@@ -1,5 +1,28 @@
2014-05-17 Filip Pizlo <[email protected]>
+ [ftlopt] Factor out how CallLinkStatus uses exit site data
+ https://bugs.webkit.org/show_bug.cgi?id=133042
+
+ Reviewed by Anders Carlsson.
+
+ This makes it easier to use CallLinkStatus from clients that are calling into after
+ already holding some of the relevant locks. This is necessary because we use a "one lock
+ at a time" policy for CodeBlock locks: if you hold one then you're not allowed to acquire
+ any of the others. So, any code that needs to lock multiple CodeBlock locks needs to sort
+ of lock one, do some stuff, release it, then lock another, and then do more stuff. The
+ exit site data corresponds to the stuff you do while holding the baseline lock, while the
+ CallLinkInfo method corresponds to the stuff you do while holding the CallLinkInfo owner's
+ lock.
+
+ * bytecode/CallLinkStatus.cpp:
+ (JSC::CallLinkStatus::computeFor):
+ (JSC::CallLinkStatus::computeExitSiteData):
+ (JSC::CallLinkStatus::computeDFGStatuses):
+ * bytecode/CallLinkStatus.h:
+ (JSC::CallLinkStatus::ExitSiteData::ExitSiteData):
+
+2014-05-17 Filip Pizlo <[email protected]>
+
[ftlopt] InlineCallFrame::isCall should be an enumeration
https://bugs.webkit.org/show_bug.cgi?id=133034
Modified: branches/ftlopt/Source/_javascript_Core/bytecode/CallLinkStatus.cpp (169013 => 169014)
--- branches/ftlopt/Source/_javascript_Core/bytecode/CallLinkStatus.cpp 2014-05-18 16:53:03 UTC (rev 169013)
+++ branches/ftlopt/Source/_javascript_Core/bytecode/CallLinkStatus.cpp 2014-05-18 17:32:22 UTC (rev 169014)
@@ -124,28 +124,38 @@
UNUSED_PARAM(bytecodeIndex);
UNUSED_PARAM(map);
#if ENABLE(DFG_JIT)
- if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
- || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint))
- || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable)))
+ ExitSiteData exitSiteData = computeExitSiteData(locker, profiledBlock, bytecodeIndex);
+ if (exitSiteData.m_takesSlowPath)
return takesSlowPath();
CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex));
if (!callLinkInfo)
return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
- CallLinkStatus result = computeFor(locker, *callLinkInfo);
- if (!result)
- return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
-
- if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction)))
- result.makeClosureCall();
-
- return result;
+ return computeFor(locker, *callLinkInfo, exitSiteData);
#else
return CallLinkStatus();
#endif
}
+CallLinkStatus::ExitSiteData CallLinkStatus::computeExitSiteData(
+ const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex,
+ ExitingJITType exitingJITType)
+{
+ ExitSiteData exitSiteData;
+
+#if ENABLE(DFG_JIT)
+ exitSiteData.m_takesSlowPath =
+ profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitingJITType))
+ || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitingJITType))
+ || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable, exitingJITType));
+ exitSiteData.m_badFunction =
+ profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction, exitingJITType));
+#endif
+
+ return exitSiteData;
+}
+
#if ENABLE(JIT)
CallLinkStatus CallLinkStatus::computeFor(const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo)
{
@@ -177,6 +187,19 @@
return CallLinkStatus(target);
}
+
+CallLinkStatus CallLinkStatus::computeFor(
+ const ConcurrentJITLocker& locker, CallLinkInfo& callLinkInfo, ExitSiteData exitSiteData)
+{
+ if (exitSiteData.m_takesSlowPath)
+ return takesSlowPath();
+
+ CallLinkStatus result = computeFor(locker, callLinkInfo);
+ if (exitSiteData.m_badFunction)
+ result.makeClosureCall();
+
+ return result;
+}
#endif
void CallLinkStatus::computeDFGStatuses(
@@ -189,9 +212,6 @@
CallLinkInfo& info = **iter;
CodeOrigin codeOrigin = info.codeOrigin;
- bool takeSlowPath;
- bool badFunction;
-
// Check if we had already previously made a terrible mistake in the FTL for this
// code origin. Note that this is approximate because we could have a monovariant
// inline in the FTL that ended up failing. We should fix that at some point by
@@ -201,28 +221,16 @@
// InlineCallFrames.
CodeBlock* currentBaseline =
baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
+ ExitSiteData exitSiteData;
{
ConcurrentJITLocker locker(currentBaseline->m_lock);
- takeSlowPath =
- currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCache, ExitFromFTL))
- || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCacheWatchpoint, ExitFromFTL))
- || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadExecutable, ExitFromFTL));
- badFunction =
- currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadFunction, ExitFromFTL));
+ exitSiteData = computeExitSiteData(
+ locker, currentBaseline, codeOrigin.bytecodeIndex, ExitFromFTL);
}
{
ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
- if (takeSlowPath)
- map.add(info.codeOrigin, takesSlowPath());
- else {
- CallLinkStatus status = computeFor(locker, info);
- if (status.isSet()) {
- if (badFunction)
- status.makeClosureCall();
- map.add(info.codeOrigin, status);
- }
- }
+ map.add(info.codeOrigin, computeFor(locker, info, exitSiteData));
}
}
#else
Modified: branches/ftlopt/Source/_javascript_Core/bytecode/CallLinkStatus.h (169013 => 169014)
--- branches/ftlopt/Source/_javascript_Core/bytecode/CallLinkStatus.h 2014-05-18 16:53:03 UTC (rev 169013)
+++ branches/ftlopt/Source/_javascript_Core/bytecode/CallLinkStatus.h 2014-05-18 17:32:22 UTC (rev 169014)
@@ -30,6 +30,7 @@
#include "CodeOrigin.h"
#include "CodeSpecializationKind.h"
#include "ConcurrentJITLock.h"
+#include "ExitingJITType.h"
#include "Intrinsic.h"
#include "JSCJSValue.h"
@@ -79,10 +80,23 @@
static CallLinkStatus computeFor(
CodeBlock*, unsigned bytecodeIndex, const CallLinkInfoMap&);
+ struct ExitSiteData {
+ ExitSiteData()
+ : m_takesSlowPath(false)
+ , m_badFunction(false)
+ {
+ }
+
+ bool m_takesSlowPath;
+ bool m_badFunction;
+ };
+ static ExitSiteData computeExitSiteData(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex, ExitingJITType = ExitFromAnything);
+
#if ENABLE(JIT)
// Computes the status assuming that we never took slow path and never previously
// exited.
static CallLinkStatus computeFor(const ConcurrentJITLocker&, CallLinkInfo&);
+ static CallLinkStatus computeFor(const ConcurrentJITLocker&, CallLinkInfo&, ExitSiteData);
#endif
typedef HashMap<CodeOrigin, CallLinkStatus, CodeOriginApproximateHash> ContextMap;