]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecode/CallLinkInfo.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / CallLinkInfo.h
index 88094ff619e5279375acced9cf3fc7a66835111c..0277ecf977293e036679c01c37642f4d81fcea63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 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
 #ifndef CallLinkInfo_h
 #define CallLinkInfo_h
 
-#include "ClosureCallStubRoutine.h"
 #include "CodeLocation.h"
 #include "CodeSpecializationKind.h"
 #include "JITWriteBarrier.h"
 #include "JSFunction.h"
 #include "Opcode.h"
+#include "PolymorphicCallStubRoutine.h"
 #include "WriteBarrier.h"
 #include <wtf/SentinelLinkedList.h>
 
@@ -41,7 +41,8 @@ namespace JSC {
 
 class RepatchBuffer;
 
-struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
+class CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
+public:
     enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs };
     static CallType callTypeFor(OpcodeID opcodeID)
     {
@@ -54,62 +55,234 @@ struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
         ASSERT(opcodeID == op_call_varargs);
         return CallVarargs;
     }
-        
+    
     CallLinkInfo()
-        : isFTL(false)
-        , hasSeenShouldRepatch(false)
-        , hasSeenClosure(false)
-        , callType(None)
-        , slowPathCount(0)
+        : m_isFTL(false)
+        , m_hasSeenShouldRepatch(false)
+        , m_hasSeenClosure(false)
+        , m_clearedByGC(false)
+        , m_callType(None)
+        , m_maxNumArguments(0)
+        , m_slowPathCount(0)
     {
     }
         
     ~CallLinkInfo()
     {
+        clearStub();
+
         if (isOnList())
             remove();
     }
     
-    CodeSpecializationKind specializationKind() const
+    static CodeSpecializationKind specializationKindFor(CallType callType)
     {
         return specializationFromIsConstruct(callType == Construct || callType == ConstructVarargs);
     }
+    CodeSpecializationKind specializationKind() const
+    {
+        return specializationKindFor(static_cast<CallType>(m_callType));
+    }
 
-    CodeLocationNearCall callReturnLocation;
-    CodeLocationDataLabelPtr hotPathBegin;
-    CodeLocationNearCall hotPathOther;
-    JITWriteBarrier<JSFunction> callee;
-    WriteBarrier<JSFunction> lastSeenCallee;
-    RefPtr<ClosureCallStubRoutine> stub;
-    bool isFTL : 1;
-    bool hasSeenShouldRepatch : 1;
-    bool hasSeenClosure : 1;
-    unsigned callType : 5; // CallType
-    unsigned calleeGPR : 8;
-    unsigned slowPathCount;
-    CodeOrigin codeOrigin;
-
-    bool isLinked() { return stub || callee; }
+    bool isLinked() { return m_stub || m_callee; }
     void unlink(RepatchBuffer&);
 
+    void setUpCall(CallType callType, CodeOrigin codeOrigin, unsigned calleeGPR)
+    {
+        m_callType = callType;
+        m_codeOrigin = codeOrigin;
+        m_calleeGPR = calleeGPR;
+    }
+
+    void setCallLocations(CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
+        CodeLocationNearCall hotPathOther)
+    {
+        m_callReturnLocation = callReturnLocation;
+        m_hotPathBegin = hotPathBegin;
+        m_hotPathOther = hotPathOther;
+    }
+
+    void setUpCallFromFTL(CallType callType, CodeOrigin codeOrigin,
+        CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
+        CodeLocationNearCall hotPathOther, unsigned calleeGPR)
+    {
+        m_isFTL = true;
+        m_callType = callType;
+        m_codeOrigin = codeOrigin;
+        m_callReturnLocation = callReturnLocation;
+        m_hotPathBegin = hotPathBegin;
+        m_hotPathOther = hotPathOther;
+        m_calleeGPR = calleeGPR;
+    }
+
+    CodeLocationNearCall callReturnLocation()
+    {
+        return m_callReturnLocation;
+    }
+
+    CodeLocationDataLabelPtr hotPathBegin()
+    {
+        return m_hotPathBegin;
+    }
+
+    CodeLocationNearCall hotPathOther()
+    {
+        return m_hotPathOther;
+    }
+
+    void setCallee(VM& vm, CodeLocationDataLabelPtr location, JSCell* owner, JSFunction* callee)
+    {
+        m_callee.set(vm, location, owner, callee);
+    }
+
+    void clearCallee()
+    {
+        m_callee.clear();
+    }
+
+    JSFunction* callee()
+    {
+        return m_callee.get();
+    }
+
+    void setLastSeenCallee(VM& vm, const JSCell* owner, JSFunction* callee)
+    {
+        m_lastSeenCallee.set(vm, owner, callee);
+    }
+
+    void clearLastSeenCallee()
+    {
+        m_lastSeenCallee.clear();
+    }
+
+    JSFunction* lastSeenCallee()
+    {
+        return m_lastSeenCallee.get();
+    }
+
+    bool haveLastSeenCallee()
+    {
+        return !!m_lastSeenCallee;
+    }
+
+    void setStub(PassRefPtr<PolymorphicCallStubRoutine> newStub)
+    {
+        clearStub();
+        m_stub = newStub;
+    }
+
+    void clearStub();
+
+    PolymorphicCallStubRoutine* stub()
+    {
+        return m_stub.get();
+    }
+
     bool seenOnce()
     {
-        return hasSeenShouldRepatch;
+        return m_hasSeenShouldRepatch;
+    }
+
+    void clearSeen()
+    {
+        m_hasSeenShouldRepatch = false;
     }
 
     void setSeen()
     {
-        hasSeenShouldRepatch = true;
+        m_hasSeenShouldRepatch = true;
     }
-    
+
+    bool hasSeenClosure()
+    {
+        return m_hasSeenClosure;
+    }
+
+    void setHasSeenClosure()
+    {
+        m_hasSeenClosure = true;
+    }
+
+    bool clearedByGC()
+    {
+        return m_clearedByGC;
+    }
+
+    void setCallType(CallType callType)
+    {
+        m_callType = callType;
+    }
+
+    CallType callType()
+    {
+        return static_cast<CallType>(m_callType);
+    }
+
+    uint8_t* addressOfMaxNumArguments()
+    {
+        return &m_maxNumArguments;
+    }
+
+    uint8_t maxNumArguments()
+    {
+        return m_maxNumArguments;
+    }
+
+    static ptrdiff_t offsetOfSlowPathCount()
+    {
+        return OBJECT_OFFSETOF(CallLinkInfo, m_slowPathCount);
+    }
+
+    void setCalleeGPR(unsigned calleeGPR)
+    {
+        m_calleeGPR = calleeGPR;
+    }
+
+    unsigned calleeGPR()
+    {
+        return m_calleeGPR;
+    }
+
+    uint32_t slowPathCount()
+    {
+        return m_slowPathCount;
+    }
+
+    void setCodeOrigin(CodeOrigin codeOrigin)
+    {
+        m_codeOrigin = codeOrigin;
+    }
+
+    CodeOrigin codeOrigin()
+    {
+        return m_codeOrigin;
+    }
+
     void visitWeak(RepatchBuffer&);
-    
+
     static CallLinkInfo& dummy();
+
+private:
+    CodeLocationNearCall m_callReturnLocation;
+    CodeLocationDataLabelPtr m_hotPathBegin;
+    CodeLocationNearCall m_hotPathOther;
+    JITWriteBarrier<JSFunction> m_callee;
+    WriteBarrier<JSFunction> m_lastSeenCallee;
+    RefPtr<PolymorphicCallStubRoutine> m_stub;
+    bool m_isFTL : 1;
+    bool m_hasSeenShouldRepatch : 1;
+    bool m_hasSeenClosure : 1;
+    bool m_clearedByGC : 1;
+    unsigned m_callType : 4; // CallType
+    unsigned m_calleeGPR : 8;
+    uint8_t m_maxNumArguments; // Only used for varargs calls.
+    uint32_t m_slowPathCount;
+    CodeOrigin m_codeOrigin;
 };
 
 inline CodeOrigin getCallLinkInfoCodeOrigin(CallLinkInfo& callLinkInfo)
 {
-    return callLinkInfo.codeOrigin;
+    return callLinkInfo.codeOrigin();
 }
 
 typedef HashMap<CodeOrigin, CallLinkInfo*, CodeOriginApproximateHash> CallLinkInfoMap;