diff options
Diffstat (limited to 'Source/JavaScriptCore/jit/JITCode.h')
-rw-r--r-- | Source/JavaScriptCore/jit/JITCode.h | 333 |
1 files changed, 196 insertions, 137 deletions
diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h index b7521fb21..7fb7b3134 100644 --- a/Source/JavaScriptCore/jit/JITCode.h +++ b/Source/JavaScriptCore/jit/JITCode.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2012 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 @@ -26,167 +26,226 @@ #ifndef JITCode_h #define JITCode_h -#if ENABLE(JIT) || ENABLE(LLINT) +#include "ArityCheckMode.h" #include "CallFrame.h" +#include "CodeOrigin.h" #include "Disassembler.h" -#include "JITStubs.h" #include "JSCJSValue.h" -#include "LegacyProfiler.h" #include "MacroAssemblerCodeRef.h" -#endif +#include "RegisterSet.h" +#include <wtf/Optional.h> namespace JSC { -#if ENABLE(JIT) - class VM; - class JSStack; -#endif +namespace DFG { +class CommonData; +class JITCode; +} +namespace FTL { +class ForOSREntryJITCode; +class JITCode; +} + +struct ProtoCallFrame; +class TrackedReferences; +class VM; + +class JITCode : public ThreadSafeRefCounted<JITCode> { +public: + typedef MacroAssemblerCodeRef CodeRef; + typedef MacroAssemblerCodePtr CodePtr; + + enum JITType : uint8_t { + None, + HostCallThunk, + InterpreterThunk, + BaselineJIT, + DFGJIT, + FTLJIT + }; - class JITCode { -#if ENABLE(JIT) || ENABLE(LLINT) - typedef MacroAssemblerCodeRef CodeRef; - typedef MacroAssemblerCodePtr CodePtr; -#else - JITCode() { } -#endif - public: - enum JITType { None, HostCallThunk, InterpreterThunk, BaselineJIT, DFGJIT }; - - static JITType bottomTierJIT() - { - return BaselineJIT; - } - - static JITType topTierJIT() - { - return DFGJIT; - } - - static JITType nextTierJIT(JITType jitType) - { - ASSERT_UNUSED(jitType, jitType == BaselineJIT || jitType == DFGJIT); + static const char* typeName(JITType); + + 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; } - - static bool isOptimizingJIT(JITType jitType) - { - return jitType == DFGJIT; + } + + static bool isExecutableScript(JITType jitType) + { + switch (jitType) { + case None: + case HostCallThunk: + return false; + default: + return true; } - - static bool isBaselineCode(JITType jitType) - { - return jitType == InterpreterThunk || jitType == BaselineJIT; + } + + static bool couldBeInterpreted(JITType jitType) + { + switch (jitType) { + case InterpreterThunk: + case BaselineJIT: + return true; + default: + return false; } - -#if ENABLE(JIT) || ENABLE(LLINT) - JITCode() - : m_jitType(None) - { + } + + static bool isJIT(JITType jitType) + { + switch (jitType) { + case BaselineJIT: + case DFGJIT: + case FTLJIT: + return true; + default: + return false; } + } - JITCode(const CodeRef ref, JITType jitType) - : m_ref(ref) - , m_jitType(jitType) - { - ASSERT(jitType != None); - } - - bool operator !() const - { - return !m_ref; - } + 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(ArityCheckMode) = 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(); + + virtual void validateReferences(const TrackedReferences&); + + 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; - CodePtr addressForCall() - { - return m_ref.code(); - } +#if ENABLE(JIT) + virtual RegisterSet liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock*, CallSiteIndex); + virtual Optional<CodeOrigin> findPC(CodeBlock*, void* pc) { UNUSED_PARAM(pc); return Nullopt; } +#endif - void* executableAddressAtOffset(size_t offset) const - { - ASSERT(offset < size()); - return reinterpret_cast<char*>(m_ref.code().executableAddress()) + offset; - } - - void* executableAddress() const - { - return executableAddressAtOffset(0); - } - - void* dataAddressAtOffset(size_t offset) const - { - ASSERT(offset <= size()); // use <= instead of < because it is valid to ask for an address at the exclusive end of the code. - return reinterpret_cast<char*>(m_ref.code().dataLocation()) + offset; - } +private: + JITType m_jitType; +}; - // 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.code().executableAddress()); - ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result); - return static_cast<unsigned>(result); - } +class JITCodeWithCodeRef : public JITCode { +protected: + JITCodeWithCodeRef(JITType); + JITCodeWithCodeRef(CodeRef, JITType); -#if ENABLE(JIT) - // Execute the code! - inline JSValue execute(JSStack* stack, CallFrame* callFrame, VM* vm) - { - JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), stack, callFrame, 0, 0, vm)); - return vm->exception ? jsNull() : result; - } -#endif +public: + virtual ~JITCodeWithCodeRef(); - void* start() const - { - return m_ref.code().dataLocation(); - } + 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; - size_t size() const - { - ASSERT(m_ref.code().executableAddress()); - return m_ref.size(); - } - - bool tryToDisassemble(const char* prefix) const - { - return m_ref.tryToDisassemble(prefix); - } +protected: + CodeRef m_ref; +}; - ExecutableMemoryHandle* getExecutableMemory() - { - return m_ref.executableMemory(); - } - - JITType jitType() const - { - return m_jitType; - } +class DirectJITCode : public JITCodeWithCodeRef { +public: + DirectJITCode(JITType); + DirectJITCode(CodeRef, CodePtr withArityCheck, JITType); + virtual ~DirectJITCode(); + + void initializeCodeRef(CodeRef, CodePtr withArityCheck); - // 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(CodeRef code) - { - return JITCode(code, HostCallThunk); - } + virtual CodePtr addressForCall(ArityCheckMode) override; - void clear() - { - m_ref.~CodeRef(); - new (NotNull, &m_ref) CodeRef(); - } +private: + CodePtr m_withArityCheck; +}; - private: - JITCode(PassRefPtr<ExecutableMemoryHandle> executableMemory, JITType jitType) - : m_ref(executableMemory) - , m_jitType(jitType) - { - } +class NativeJITCode : public JITCodeWithCodeRef { +public: + NativeJITCode(JITType); + NativeJITCode(CodeRef, JITType); + virtual ~NativeJITCode(); + + void initializeCodeRef(CodeRef); - CodeRef m_ref; - JITType m_jitType; -#endif // ENABLE(JIT) || ENABLE(LLINT) - }; + virtual CodePtr addressForCall(ArityCheckMode) override; +}; } // namespace JSC |