simulator.h 4.35 KB
Newer Older
1
// Copyright 2009 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8_SIMULATOR_H_
#define V8_SIMULATOR_H_

8
#include "src/globals.h"
9
#include "src/objects/code.h"
10

11
#if V8_TARGET_ARCH_IA32
12
#include "src/ia32/simulator-ia32.h"
13
#elif V8_TARGET_ARCH_X64
14
#include "src/x64/simulator-x64.h"
15
#elif V8_TARGET_ARCH_ARM64
16
#include "src/arm64/simulator-arm64.h"
17
#elif V8_TARGET_ARCH_ARM
18
#include "src/arm/simulator-arm.h"
19 20
#elif V8_TARGET_ARCH_PPC
#include "src/ppc/simulator-ppc.h"
21
#elif V8_TARGET_ARCH_MIPS
22
#include "src/mips/simulator-mips.h"
23 24
#elif V8_TARGET_ARCH_MIPS64
#include "src/mips64/simulator-mips64.h"
25 26
#elif V8_TARGET_ARCH_S390
#include "src/s390/simulator-s390.h"
27 28 29 30
#else
#error Unsupported target architecture.
#endif

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
namespace v8 {
namespace internal {

#if defined(USE_SIMULATOR)
// Running with a simulator.

// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code.  The JS-based limit normally points near the end of
// the simulator stack.  When the C-based limit is exhausted we reflect that by
// lowering the JS-based limit as well, to make stack checks trigger.
class SimulatorStack : public v8::internal::AllStatic {
 public:
  static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
                                            uintptr_t c_limit) {
    return Simulator::current(isolate)->StackLimit(c_limit);
  }

  static inline uintptr_t RegisterCTryCatch(v8::internal::Isolate* isolate,
                                            uintptr_t try_catch_address) {
    return Simulator::current(isolate)->PushAddress(try_catch_address);
  }

  static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
    Simulator::current(isolate)->PopAddress();
  }
};

#else  // defined(USE_SIMULATOR)
// Running without a simulator on a native platform.

// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code uses the C stack, we just use
// the C stack limit.
class SimulatorStack : public v8::internal::AllStatic {
 public:
  static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
                                            uintptr_t c_limit) {
    USE(isolate);
    return c_limit;
  }

  static inline uintptr_t RegisterCTryCatch(v8::internal::Isolate* isolate,
                                            uintptr_t try_catch_address) {
    USE(isolate);
    return try_catch_address;
  }

  static inline void UnregisterCTryCatch(v8::internal::Isolate* isolate) {
    USE(isolate);
  }
};

83
#endif  // defined(USE_SIMULATOR)
84

85 86 87 88 89 90
// Use this class either as {GeneratedCode<ret, arg1, arg2>} or
// {GeneratedCode<ret(arg1, arg2)>} (see specialization below).
template <typename Return, typename... Args>
class GeneratedCode {
 public:
  using Signature = Return(Args...);
91

92
  static GeneratedCode FromAddress(Isolate* isolate, Address addr) {
93 94
    return GeneratedCode(isolate, reinterpret_cast<Signature*>(addr));
  }
95

96 97 98 99
  static GeneratedCode FromBuffer(Isolate* isolate, byte* buffer) {
    return GeneratedCode(isolate, reinterpret_cast<Signature*>(buffer));
  }

100 101 102 103 104 105 106 107
  static GeneratedCode FromCode(Code* code) {
    return FromAddress(code->GetIsolate(), code->entry());
  }

#ifdef USE_SIMULATOR
  // Defined in simulator-base.h.
  Return Call(Args... args) {
    return Simulator::current(isolate_)->template Call<Return>(
108
        reinterpret_cast<Address>(fn_ptr_), args...);
109 110
  }
#else
111
  DISABLE_CFI_ICALL Return Call(Args... args) {
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    // When running without a simulator we call the entry directly.
    return fn_ptr_(args...);
  }
#endif

 private:
  friend class GeneratedCode<Return(Args...)>;
  Isolate* isolate_;
  Signature* fn_ptr_;
  GeneratedCode(Isolate* isolate, Signature* fn_ptr)
      : isolate_(isolate), fn_ptr_(fn_ptr) {}
};

// Allow to use {GeneratedCode<ret(arg1, arg2)>} instead of
// {GeneratedCode<ret, arg1, arg2>}.
template <typename Return, typename... Args>
class GeneratedCode<Return(Args...)> : public GeneratedCode<Return, Args...> {
 public:
  // Automatically convert from {GeneratedCode<ret, arg1, arg2>} to
  // {GeneratedCode<ret(arg1, arg2)>}.
  GeneratedCode(GeneratedCode<Return, Args...> other)
      : GeneratedCode<Return, Args...>(other.isolate_, other.fn_ptr_) {}
};
135 136 137 138

}  // namespace internal
}  // namespace v8

139
#endif  // V8_SIMULATOR_H_