X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/jit/JITCode.cpp?ds=inline diff --git a/jit/JITCode.cpp b/jit/JITCode.cpp index 5cfa630..e86b5c3 100644 --- a/jit/JITCode.cpp +++ b/jit/JITCode.cpp @@ -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,32 +26,239 @@ #include "config.h" #include "JITCode.h" +#include "LLIntThunks.h" +#include "JSCInlines.h" +#include "ProtoCallFrame.h" +#include "RegisterPreservationWrapperGenerator.h" #include -namespace WTF { +namespace JSC { -void printInternal(PrintStream& out, JSC::JITCode::JITType type) +JITCode::JITCode(JITType jitType) + : m_jitType(jitType) +{ +} + +JITCode::~JITCode() +{ +} + +const char* JITCode::typeName(JITType jitType) { - switch (type) { - case JSC::JITCode::None: - out.print("None"); - return; - case JSC::JITCode::HostCallThunk: - out.print("Host"); - return; - case JSC::JITCode::InterpreterThunk: - out.print("LLInt"); - return; - case JSC::JITCode::BaselineJIT: - out.print("Baseline"); - return; - case JSC::JITCode::DFGJIT: - out.print("DFG"); - return; + switch (jitType) { + case None: + return "None"; + case HostCallThunk: + return "Host"; + case InterpreterThunk: + return "LLInt"; + case BaselineJIT: + return "Baseline"; + case DFGJIT: + return "DFG"; + case FTLJIT: + return "FTL"; default: CRASH(); - return; + return ""; + } +} + +void JITCode::validateReferences(const TrackedReferences&) +{ +} + +JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame) +{ + void* entryAddress; + JSFunction* function = jsDynamicCast(protoCallFrame->callee()); + + if (!function || !protoCallFrame->needArityCheck()) { + ASSERT(!protoCallFrame->needArityCheck()); + entryAddress = executableAddress(); + } else + entryAddress = addressForCall(*vm, function->executable(), MustCheckArity, RegisterPreservationNotRequired).executableAddress(); + JSValue result = JSValue::decode(vmEntryToJavaScript(entryAddress, vm, protoCallFrame)); + return vm->exception() ? jsNull() : result; +} + +DFG::CommonData* JITCode::dfgCommon() +{ + RELEASE_ASSERT_NOT_REACHED(); + return 0; +} + +DFG::JITCode* JITCode::dfg() +{ + RELEASE_ASSERT_NOT_REACHED(); + return 0; +} + +FTL::JITCode* JITCode::ftl() +{ + RELEASE_ASSERT_NOT_REACHED(); + return 0; +} + +FTL::ForOSREntryJITCode* JITCode::ftlForOSREntry() +{ + RELEASE_ASSERT_NOT_REACHED(); + return 0; +} + +JITCodeWithCodeRef::JITCodeWithCodeRef(JITType jitType) + : JITCode(jitType) +{ +} + +JITCodeWithCodeRef::JITCodeWithCodeRef(CodeRef ref, JITType jitType) + : JITCode(jitType) + , m_ref(ref) +{ +} + +JITCodeWithCodeRef::~JITCodeWithCodeRef() +{ +} + +void* JITCodeWithCodeRef::executableAddressAtOffset(size_t offset) +{ + RELEASE_ASSERT(m_ref); + return reinterpret_cast(m_ref.code().executableAddress()) + offset; +} + +void* JITCodeWithCodeRef::dataAddressAtOffset(size_t offset) +{ + RELEASE_ASSERT(m_ref); + 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(m_ref.code().dataLocation()) + offset; +} + +unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode) +{ + RELEASE_ASSERT(m_ref); + intptr_t result = reinterpret_cast(pointerIntoCode) - reinterpret_cast(m_ref.code().executableAddress()); + ASSERT(static_cast(static_cast(result)) == result); + return static_cast(result); +} + +size_t JITCodeWithCodeRef::size() +{ + RELEASE_ASSERT(m_ref); + return m_ref.size(); +} + +bool JITCodeWithCodeRef::contains(void* address) +{ + RELEASE_ASSERT(m_ref); + return m_ref.executableMemory()->contains(address); +} + +DirectJITCode::DirectJITCode(JITType jitType) + : JITCodeWithCodeRef(jitType) +{ +} + +DirectJITCode::DirectJITCode(JITCode::CodeRef ref, JITCode::CodePtr withArityCheck, JITType jitType) + : JITCodeWithCodeRef(ref, jitType) + , m_withArityCheck(withArityCheck) +{ +} + +DirectJITCode::~DirectJITCode() +{ +} + +void DirectJITCode::initializeCodeRef(JITCode::CodeRef ref, JITCode::CodePtr withArityCheck) +{ + RELEASE_ASSERT(!m_ref); + m_ref = ref; + m_withArityCheck = withArityCheck; +} + +DirectJITCode::RegisterPreservationWrappers* DirectJITCode::ensureWrappers() +{ + if (!m_wrappers) + m_wrappers = std::make_unique(); + return m_wrappers.get(); +} + +JITCode::CodePtr DirectJITCode::addressForCall( + VM& vm, ExecutableBase* executable, ArityCheckMode arity, + RegisterPreservationMode registers) +{ + switch (arity) { + case ArityCheckNotRequired: + switch (registers) { + case RegisterPreservationNotRequired: + RELEASE_ASSERT(m_ref); + return m_ref.code(); + case MustPreserveRegisters: { +#if ENABLE(JIT) + RegisterPreservationWrappers* wrappers = ensureWrappers(); + if (!wrappers->withoutArityCheck) + wrappers->withoutArityCheck = generateRegisterPreservationWrapper(vm, executable, m_ref.code()); + return wrappers->withoutArityCheck.code(); +#else + UNUSED_PARAM(vm); + UNUSED_PARAM(executable); + RELEASE_ASSERT_NOT_REACHED(); +#endif + } } + case MustCheckArity: + switch (registers) { + case RegisterPreservationNotRequired: + RELEASE_ASSERT(m_withArityCheck); + return m_withArityCheck; + case MustPreserveRegisters: { +#if ENABLE(JIT) + RegisterPreservationWrappers* wrappers = ensureWrappers(); + if (!wrappers->withArityCheck) + wrappers->withArityCheck = generateRegisterPreservationWrapper(vm, executable, m_withArityCheck); + return wrappers->withArityCheck.code(); +#else + RELEASE_ASSERT_NOT_REACHED(); +#endif + } } } + RELEASE_ASSERT_NOT_REACHED(); + return CodePtr(); +} + +NativeJITCode::NativeJITCode(JITType jitType) + : JITCodeWithCodeRef(jitType) +{ +} + +NativeJITCode::NativeJITCode(CodeRef ref, JITType jitType) + : JITCodeWithCodeRef(ref, jitType) +{ +} + +NativeJITCode::~NativeJITCode() +{ +} + +void NativeJITCode::initializeCodeRef(CodeRef ref) +{ + ASSERT(!m_ref); + m_ref = ref; +} + +JITCode::CodePtr NativeJITCode::addressForCall( + VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) +{ + RELEASE_ASSERT(!!m_ref); + return m_ref.code(); +} + +} // namespace JSC + +namespace WTF { + +void printInternal(PrintStream& out, JSC::JITCode::JITType type) +{ + out.print(JSC::JITCode::typeName(type)); } } // namespace WTF