]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecode/CallLinkStatus.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / CallLinkStatus.h
index 99b2fdc93fedb647dea617552248edeb53b4a7b3..a307ca0069b5c1886c296fdfa69473e7fc8b2a63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-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
 #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"
 
@@ -40,14 +42,12 @@ class ExecutableBase;
 class InternalFunction;
 class JSFunction;
 class Structure;
-struct CallLinkInfo;
+class CallLinkInfo;
 
 class CallLinkStatus {
 public:
     CallLinkStatus()
-        : m_executable(0)
-        , m_structure(0)
-        , m_couldTakeSlowPath(false)
+        : m_couldTakeSlowPath(false)
         , m_isProved(false)
     {
     }
@@ -61,28 +61,34 @@ public:
     
     explicit CallLinkStatus(JSValue);
     
-    CallLinkStatus(ExecutableBase* executable, Structure* structure)
-        : m_executable(executable)
-        , m_structure(structure)
+    CallLinkStatus(CallVariant variant)
+        : m_variants(1, variant)
         , m_couldTakeSlowPath(false)
         , m_isProved(false)
     {
-        ASSERT(!!executable == !!structure);
-    }
-    
-    CallLinkStatus& setIsProved(bool isProved)
-    {
-        m_isProved = isProved;
-        return *this;
     }
     
     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);
+    
 #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&, CodeBlock*, CallLinkInfo&);
+    static CallLinkStatus computeFor(
+        const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&, ExitSiteData);
 #endif
     
     typedef HashMap<CodeOrigin, CallLinkStatus, CodeOriginApproximateHash> ContextMap;
@@ -96,39 +102,40 @@ public:
     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 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:
-    void makeClosureCall()
-    {
-        ASSERT(!m_isProved);
-        // Turn this into a closure call.
-        m_callTarget = JSValue();
-    }
+    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;
+    CallVariantList m_variants;
     bool m_couldTakeSlowPath;
     bool m_isProved;
+    unsigned m_maxNumArguments;
 };
 
 } // namespace JSC