]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - jit/JITCode.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / jit / JITCode.cpp
index 5cfa6304b2a37ea9942d9f73ed90372798b0f0c4..e86b5c346170b33fc4ae56ecea5135a5314827e7 100644 (file)
@@ -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
 #include "config.h"
 #include "JITCode.h"
 
+#include "LLIntThunks.h"
+#include "JSCInlines.h"
+#include "ProtoCallFrame.h"
+#include "RegisterPreservationWrapperGenerator.h"
 #include <wtf/PrintStream.h>
 
-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<JSFunction*>(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<char*>(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<char*>(m_ref.code().dataLocation()) + offset;
+}
+
+unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode)
+{
+    RELEASE_ASSERT(m_ref);
+    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);
+}
+
+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<RegisterPreservationWrappers>();
+    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