summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/CallLinkStatus.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode/CallLinkStatus.h')
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkStatus.h115
1 files changed, 59 insertions, 56 deletions
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.h b/Source/JavaScriptCore/bytecode/CallLinkStatus.h
index 51965fe4a..d3c1eee0c 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkStatus.h
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,12 @@
#ifndef CallLinkStatus_h
#define CallLinkStatus_h
+#include "CallLinkInfo.h"
+#include "CallVariant.h"
+#include "CodeOrigin.h"
#include "CodeSpecializationKind.h"
+#include "ConcurrentJITLock.h"
+#include "ExitingJITType.h"
#include "Intrinsic.h"
#include "JSCJSValue.h"
@@ -37,14 +42,12 @@ class ExecutableBase;
class InternalFunction;
class JSFunction;
class Structure;
+class CallLinkInfo;
class CallLinkStatus {
+ WTF_MAKE_FAST_ALLOCATED;
public:
CallLinkStatus()
- : m_executable(0)
- , m_structure(0)
- , m_couldTakeSlowPath(false)
- , m_isProved(false)
{
}
@@ -57,75 +60,75 @@ public:
explicit CallLinkStatus(JSValue);
- CallLinkStatus(ExecutableBase* executable, Structure* structure)
- : m_executable(executable)
- , m_structure(structure)
- , m_couldTakeSlowPath(false)
- , m_isProved(false)
+ CallLinkStatus(CallVariant variant)
+ : m_variants(1, variant)
{
- ASSERT(!!executable == !!structure);
}
- CallLinkStatus& setIsProved(bool isProved)
- {
- m_isProved = isProved;
- return *this;
- }
+ static CallLinkStatus computeFor(
+ CodeBlock*, unsigned bytecodeIndex, const CallLinkInfoMap&);
+
+ struct ExitSiteData {
+ bool takesSlowPath { false };
+ bool badFunction { false };
+ };
+ static ExitSiteData computeExitSiteData(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
- static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
+#if ENABLE(JIT)
+ // Computes the status assuming that we never took slow path and never previously
+ // exited.
+ static CallLinkStatus computeFor(const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&);
+ static CallLinkStatus computeFor(
+ const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&, ExitSiteData);
+#endif
- CallLinkStatus& setHasBadFunctionExitSite(bool didHaveExitSite)
- {
- ASSERT(!m_isProved);
- if (didHaveExitSite) {
- // Turn this into a closure call.
- m_callTarget = JSValue();
- }
- return *this;
- }
+ typedef HashMap<CodeOrigin, CallLinkStatus, CodeOriginApproximateHash> ContextMap;
- CallLinkStatus& setHasBadCacheExitSite(bool didHaveExitSite)
- {
- ASSERT(!m_isProved);
- if (didHaveExitSite)
- *this = takesSlowPath();
- return *this;
- }
+ // Computes all of the statuses of the DFG code block. Doesn't include statuses that had
+ // no information. Currently we use this when compiling FTL code, to enable polyvariant
+ // inlining.
+ static void computeDFGStatuses(CodeBlock* dfgCodeBlock, ContextMap&);
- CallLinkStatus& setHasBadExecutableExitSite(bool didHaveExitSite)
- {
- ASSERT(!m_isProved);
- if (didHaveExitSite)
- *this = takesSlowPath();
- return *this;
- }
+ // Helper that first consults the ContextMap and then does computeFor().
+ static CallLinkStatus computeFor(
+ CodeBlock*, CodeOrigin, const CallLinkInfoMap&, const ContextMap&);
- bool isSet() const { return m_callTarget || m_executable || m_couldTakeSlowPath; }
+ void setProvenConstantCallee(CallVariant);
+
+ bool isSet() const { return !m_variants.isEmpty() || m_couldTakeSlowPath; }
bool operator!() const { return !isSet(); }
bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
- bool isClosureCall() const { return m_executable && !m_callTarget; }
-
- JSValue callTarget() const { return m_callTarget; }
- JSFunction* function() const;
- InternalFunction* internalFunction() const;
- Intrinsic intrinsicFor(CodeSpecializationKind) const;
- ExecutableBase* executable() const { return m_executable; }
- Structure* structure() const { return m_structure; }
+
+ 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); }
bool isProved() const { return m_isProved; }
- bool canOptimize() const { return (m_callTarget || m_executable) && !m_couldTakeSlowPath; }
+ bool isBasedOnStub() const { return m_isBasedOnStub; }
+ bool canOptimize() const { return !m_variants.isEmpty(); }
+
+ bool isClosureCall() const; // Returns true if any callee is a closure call.
+
+ unsigned maxNumArguments() const { return m_maxNumArguments; }
void dump(PrintStream&) const;
private:
- static CallLinkStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex);
+ void makeClosureCall();
+
+ static CallLinkStatus computeFromLLInt(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
+#if ENABLE(JIT)
+ static CallLinkStatus computeFromCallLinkInfo(
+ const ConcurrentJITLocker&, CallLinkInfo&);
+#endif
- JSValue m_callTarget;
- ExecutableBase* m_executable;
- Structure* m_structure;
- bool m_couldTakeSlowPath;
- bool m_isProved;
+ CallVariantList m_variants;
+ bool m_couldTakeSlowPath { false };
+ bool m_isProved { false };
+ bool m_isBasedOnStub { false };
+ unsigned m_maxNumArguments { 0 };
};
} // namespace JSC