]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - jit/JITCode.h
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / jit / JITCode.h
index 082d2a73756a4bf4245dd2420c0e32b8a4f1496a..010392368ce452064193b6a6c4d8841454606286 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2013 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 JITCode_h
 #define JITCode_h
 
-#if ENABLE(JIT)
-
+#include "ArityCheckMode.h"
 #include "CallFrame.h"
-#include "JSValue.h"
+#include "Disassembler.h"
+#include "JITStubs.h"
+#include "JSCJSValue.h"
+#include "LegacyProfiler.h"
 #include "MacroAssemblerCodeRef.h"
-#include "Profiler.h"
+#include "RegisterPreservationMode.h"
 
 namespace JSC {
 
-    class JSGlobalData;
-    class RegisterFile;
+namespace DFG {
+class CommonData;
+class JITCode;
+}
+namespace FTL {
+class ForOSREntryJITCode;
+class JITCode;
+}
 
-    class JITCode {
-        typedef MacroAssemblerCodeRef CodeRef;
-        typedef MacroAssemblerCodePtr CodePtr;
-    public:
-        JITCode()
-        {
-        }
+struct ProtoCallFrame;
+class VM;
 
-        JITCode(const CodeRef ref)
-            : m_ref(ref)
-        {
-        }
+class JITCode : public ThreadSafeRefCounted<JITCode> {
+public:
+    typedef MacroAssemblerCodeRef CodeRef;
+    typedef MacroAssemblerCodePtr CodePtr;
 
-        bool operator !() const
-        {
-            return !m_ref.m_code.executableAddress();
+    enum JITType : uint8_t {
+        None,
+        HostCallThunk,
+        InterpreterThunk,
+        BaselineJIT,
+        DFGJIT,
+        FTLJIT
+    };
+    
+    static JITType bottomTierJIT()
+    {
+        return BaselineJIT;
+    }
+    
+    static JITType topTierJIT()
+    {
+        return FTLJIT;
+    }
+    
+    static JITType nextTierJIT(JITType jitType)
+    {
+        switch (jitType) {
+        case BaselineJIT:
+            return DFGJIT;
+        case DFGJIT:
+            return FTLJIT;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return None;
         }
-
-        CodePtr addressForCall()
-        {
-            return m_ref.m_code;
+    }
+    
+    static bool isExecutableScript(JITType jitType)
+    {
+        switch (jitType) {
+        case None:
+        case HostCallThunk:
+            return false;
+        default:
+            return true;
         }
-
-        // This function returns the offset in bytes of 'pointerIntoCode' into
-        // this block of code.  The pointer provided must be a pointer into this
-        // block of code.  It is ASSERTed that no codeblock >4gb in size.
-        unsigned offsetOf(void* pointerIntoCode)
-        {
-            intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - reinterpret_cast<intptr_t>(m_ref.m_code.executableAddress());
-            ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result);
-            return static_cast<unsigned>(result);
+    }
+    
+    static bool couldBeInterpreted(JITType jitType)
+    {
+        switch (jitType) {
+        case InterpreterThunk:
+        case BaselineJIT:
+            return true;
+        default:
+            return false;
         }
-
-        // Execute the code!
-        inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData)
-        {
-            JSValue result = JSValue::decode(ctiTrampoline(m_ref.m_code.executableAddress(), registerFile, callFrame, 0, Profiler::enabledProfilerReference(), globalData));
-            return globalData->exception ? jsNull() : result;
+    }
+    
+    static bool isJIT(JITType jitType)
+    {
+        switch (jitType) {
+        case BaselineJIT:
+        case DFGJIT:
+        case FTLJIT:
+            return true;
+        default:
+            return false;
         }
+    }
+    
+    static bool isLowerTier(JITType expectedLower, JITType expectedHigher)
+    {
+        RELEASE_ASSERT(isExecutableScript(expectedLower));
+        RELEASE_ASSERT(isExecutableScript(expectedHigher));
+        return expectedLower < expectedHigher;
+    }
+    
+    static bool isHigherTier(JITType expectedHigher, JITType expectedLower)
+    {
+        return isLowerTier(expectedLower, expectedHigher);
+    }
+    
+    static bool isLowerOrSameTier(JITType expectedLower, JITType expectedHigher)
+    {
+        return !isHigherTier(expectedLower, expectedHigher);
+    }
+    
+    static bool isHigherOrSameTier(JITType expectedHigher, JITType expectedLower)
+    {
+        return isLowerOrSameTier(expectedLower, expectedHigher);
+    }
+    
+    static bool isOptimizingJIT(JITType jitType)
+    {
+        return jitType == DFGJIT || jitType == FTLJIT;
+    }
+    
+    static bool isBaselineCode(JITType jitType)
+    {
+        return jitType == InterpreterThunk || jitType == BaselineJIT;
+    }
+    
+protected:
+    JITCode(JITType);
+    
+public:
+    virtual ~JITCode();
+    
+    JITType jitType() const
+    {
+        return m_jitType;
+    }
+    
+    template<typename PointerType>
+    static JITType jitTypeFor(PointerType jitCode)
+    {
+        if (!jitCode)
+            return None;
+        return jitCode->jitType();
+    }
+    
+    virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) = 0;
+    virtual void* executableAddressAtOffset(size_t offset) = 0;
+    void* executableAddress() { return executableAddressAtOffset(0); }
+    virtual void* dataAddressAtOffset(size_t offset) = 0;
+    virtual unsigned offsetOf(void* pointerIntoCode) = 0;
+    
+    virtual DFG::CommonData* dfgCommon();
+    virtual DFG::JITCode* dfg();
+    virtual FTL::JITCode* ftl();
+    virtual FTL::ForOSREntryJITCode* ftlForOSREntry();
+    
+    JSValue execute(VM*, ProtoCallFrame*);
+    
+    void* start() { return dataAddressAtOffset(0); }
+    virtual size_t size() = 0;
+    void* end() { return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(start()) + size()); }
+    
+    virtual bool contains(void*) = 0;
 
-        void* start()
-        {
-            return m_ref.m_code.dataLocation();
-        }
+private:
+    JITType m_jitType;
+};
 
-        size_t size()
-        {
-            ASSERT(m_ref.m_code.executableAddress());
-            return m_ref.m_size;
-        }
+class JITCodeWithCodeRef : public JITCode {
+protected:
+    JITCodeWithCodeRef(JITType);
+    JITCodeWithCodeRef(CodeRef, JITType);
 
-        ExecutablePool* getExecutablePool()
-        {
-            return m_ref.m_executablePool.get();
-        }
+public:
+    virtual ~JITCodeWithCodeRef();
 
-        // Host functions are a bit special; they have a m_code pointer but they
-        // do not individully ref the executable pool containing the trampoline.
-        static JITCode HostFunction(CodePtr code)
-        {
-            return JITCode(code.dataLocation(), 0, 0);
-        }
+    virtual void* executableAddressAtOffset(size_t offset) override;
+    virtual void* dataAddressAtOffset(size_t offset) override;
+    virtual unsigned offsetOf(void* pointerIntoCode) override;
+    virtual size_t size() override;
+    virtual bool contains(void*) override;
 
-        void clear()
-        {
-            m_ref.~CodeRef();
-            new (&m_ref) CodeRef();
-        }
+protected:
+    CodeRef m_ref;
+};
 
-    private:
-        JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
-            : m_ref(code, executablePool, size)
-        {
-        }
+class DirectJITCode : public JITCodeWithCodeRef {
+public:
+    DirectJITCode(JITType);
+    DirectJITCode(CodeRef, CodePtr withArityCheck, JITType);
+    virtual ~DirectJITCode();
+    
+    void initializeCodeRef(CodeRef, CodePtr withArityCheck);
 
-        CodeRef m_ref;
+    virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) override;
+
+private:
+    struct RegisterPreservationWrappers {
+        CodeRef withoutArityCheck;
+        CodeRef withArityCheck;
     };
 
+    RegisterPreservationWrappers* ensureWrappers();
+    
+    CodePtr m_withArityCheck;
+    
+    std::unique_ptr<RegisterPreservationWrappers> m_wrappers;
 };
 
-#endif
+class NativeJITCode : public JITCodeWithCodeRef {
+public:
+    NativeJITCode(JITType);
+    NativeJITCode(CodeRef, JITType);
+    virtual ~NativeJITCode();
+    
+    void initializeCodeRef(CodeRef);
+
+    virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) override;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+void printInternal(PrintStream&, JSC::JITCode::JITType);
+
+} // namespace WTF
 
 #endif