v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
simulator.h
Go to the documentation of this file.
1// Copyright 2009 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_EXECUTION_SIMULATOR_H_
6#define V8_EXECUTION_SIMULATOR_H_
7
9#include "src/objects/code.h"
10
11#if !defined(USE_SIMULATOR)
14#include "src/utils/utils.h"
15#endif
16
17#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
18// No simulator for ia32 or x64.
19#elif V8_TARGET_ARCH_ARM64
21#elif V8_TARGET_ARCH_ARM
23#elif V8_TARGET_ARCH_PPC64
25#elif V8_TARGET_ARCH_MIPS64
27#elif V8_TARGET_ARCH_LOONG64
29#elif V8_TARGET_ARCH_S390X
31#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
33#else
34#error Unsupported target architecture.
35#endif
36
37namespace heap::base {
38class StackVisitor;
39}
40
41namespace v8 {
42namespace internal {
43
44#if defined(USE_SIMULATOR)
45// Running with a simulator.
46
47// The simulator has its own stack. Thus it has a different stack limit from
48// the C-based native code. The JS-based limit normally points near the end of
49// the simulator stack. When the C-based limit is exhausted we reflect that by
50// lowering the JS-based limit as well, to make stack checks trigger.
51class SimulatorStack : public v8::internal::AllStatic {
52 public:
53 static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
54 uintptr_t c_limit) {
55 return Simulator::current(isolate)->StackLimit(c_limit);
56 }
57
58#if V8_ENABLE_WEBASSEMBLY
59 // Includes the safety stack limit gap.
60 static inline base::Vector<uint8_t> GetCentralStackView(
61 v8::internal::Isolate* isolate) {
62 return Simulator::current(isolate)->GetCentralStackView();
63 }
64
65 // Size of the safety stack limit gap.
66 static int JSStackLimitMargin() { return Simulator::JSStackLimitMargin(); }
67#endif
68
69 // Iterates the simulator registers and stack for conservative stack scanning.
70 static void IterateRegistersAndStack(Isolate* isolate,
72 DCHECK_NOT_NULL(isolate);
73 Simulator::current(isolate)->IterateRegistersAndStack(visitor);
74 }
75
76 // When running on the simulator, we should leave the C stack limits alone
77 // when switching stacks for Wasm.
78 static inline bool ShouldSwitchCStackForWasmStackSwitching() { return false; }
79
80 // Returns the current stack address on the simulator stack frame.
81 // The returned address is comparable with JS stack address.
82 static inline uintptr_t RegisterJSStackComparableAddress(
83 v8::internal::Isolate* isolate) {
84 // The value of |kPlaceHolder| is actually not used. It just occupies a
85 // single word on the stack frame of the simulator.
86 const uintptr_t kPlaceHolder = 0x4A535350u; // "JSSP" in ASCII
87 return Simulator::current(isolate)->PushAddress(kPlaceHolder);
88 }
89
90 static inline void UnregisterJSStackComparableAddress(
91 v8::internal::Isolate* isolate) {
92 Simulator::current(isolate)->PopAddress();
93 }
94};
95
96#else // defined(USE_SIMULATOR)
97// Running without a simulator on a native platform.
98
99// The stack limit beyond which we will throw stack overflow errors in
100// generated code. Because generated code uses the C stack, we just use
101// the C stack limit.
103 public:
104 static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
105 uintptr_t c_limit) {
106 USE(isolate);
107 return c_limit;
108 }
109
110#if V8_ENABLE_WEBASSEMBLY
111 static inline base::Vector<uint8_t> GetCentralStackView(
112 v8::internal::Isolate* isolate) {
113 uintptr_t upper_bound = base::Stack::GetStackStart();
114 size_t size = isolate->stack_size() + JSStackLimitMargin();
115 uintptr_t lower_bound = upper_bound - size;
116 return base::VectorOf(reinterpret_cast<uint8_t*>(lower_bound), size);
117 }
118
119 static constexpr int JSStackLimitMargin() {
121 }
122#endif
123
124 static void IterateRegistersAndStack(Isolate* isolate,
125 ::heap::base::StackVisitor* visitor) {}
126
127 // When running on real hardware, we should also switch the C stack limit
128 // when switching stacks for Wasm.
129 static inline bool ShouldSwitchCStackForWasmStackSwitching() { return true; }
130
131 // Returns the current stack address on the native stack frame.
132 // The returned address is comparable with JS stack address.
133 static inline uintptr_t RegisterJSStackComparableAddress(
134 v8::internal::Isolate* isolate) {
135 USE(isolate);
137 }
138
140 v8::internal::Isolate* isolate) {
141 USE(isolate);
142 }
143};
144
145#endif // defined(USE_SIMULATOR)
146
147// Use this class either as {GeneratedCode<ret, arg1, arg2>} or
148// {GeneratedCode<ret(arg1, arg2)>} (see specialization below).
149template <typename Return, typename... Args>
151 public:
152 using Signature = Return(Args...);
153
154 static GeneratedCode FromAddress(Isolate* isolate, Address addr) {
155 return GeneratedCode(isolate, reinterpret_cast<Signature*>(addr));
156 }
157
158 static GeneratedCode FromBuffer(Isolate* isolate, uint8_t* buffer) {
159 return GeneratedCode(isolate, reinterpret_cast<Signature*>(buffer));
160 }
161
163 return FromAddress(isolate, code->instruction_start());
164 }
165
166#ifdef USE_SIMULATOR
167 // Defined in simulator-base.h.
168 Return Call(Args... args) {
169// Starboard is a platform abstraction interface that also include Windows
170// platforms like UWP.
171#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \
172 !defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM)
173 FATAL(
174 "Generated code execution not possible during cross-compilation."
175 "Also, generic C function calls are not implemented on 32-bit arm "
176 "yet.");
177#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) &&
178 // !defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM)
179 return Simulator::current(isolate_)->template Call<Return>(
180 reinterpret_cast<Address>(fn_ptr_), args...);
181 }
182#else
183
184 DISABLE_CFI_ICALL Return Call(Args... args) {
185 // When running without a simulator we call the entry directly.
186// Starboard is a platform abstraction interface that also include Windows
187// platforms like UWP.
188#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \
189 !defined(V8_OS_STARBOARD)
190 FATAL("Generated code execution not possible during cross-compilation.");
191#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
192#if ABI_USES_FUNCTION_DESCRIPTORS
193#if V8_OS_ZOS
194 // z/OS ABI requires function descriptors (FD). Artificially create a pseudo
195 // FD to ensure correct dispatch to generated code.
196 void* function_desc[2] = {0, reinterpret_cast<void*>(fn_ptr_)};
197 asm volatile(" stg 5,%0 " : "=m"(function_desc[0])::"r5");
198 Signature* fn = reinterpret_cast<Signature*>(function_desc);
199 return fn(args...);
200#else
201 // AIX ABI requires function descriptors (FD). Artificially create a pseudo
202 // FD to ensure correct dispatch to generated code. The 'volatile'
203 // declaration is required to avoid the compiler from not observing the
204 // alias of the pseudo FD to the function pointer, and hence, optimizing the
205 // pseudo FD declaration/initialization away.
206 volatile Address function_desc[] = {reinterpret_cast<Address>(fn_ptr_), 0,
207 0};
208 Signature* fn = reinterpret_cast<Signature*>(function_desc);
209 return fn(args...);
210#endif // V8_OS_ZOS
211#else
212 return fn_ptr_(args...);
213#endif // ABI_USES_FUNCTION_DESCRIPTORS
214 }
215#endif // USE_SIMULATOR
216
217 private:
218 friend class GeneratedCode<Return(Args...)>;
221 GeneratedCode(Isolate* isolate, Signature* fn_ptr)
222 : isolate_(isolate), fn_ptr_(fn_ptr) {}
223};
224
225// Allow to use {GeneratedCode<ret(arg1, arg2)>} instead of
226// {GeneratedCode<ret, arg1, arg2>}.
227template <typename Return, typename... Args>
228class GeneratedCode<Return(Args...)> : public GeneratedCode<Return, Args...> {
229 public:
230 // Automatically convert from {GeneratedCode<ret, arg1, arg2>} to
231 // {GeneratedCode<ret(arg1, arg2)>}.
233 : GeneratedCode<Return, Args...>(other.isolate_, other.fn_ptr_) {}
234};
235
236} // namespace internal
237} // namespace v8
238
239#endif // V8_EXECUTION_SIMULATOR_H_
static StackSlot GetStackStart()
GeneratedCode(GeneratedCode< Return, Args... > other)
Definition simulator.h:232
static GeneratedCode FromAddress(Isolate *isolate, Address addr)
Definition simulator.h:154
static GeneratedCode FromBuffer(Isolate *isolate, uint8_t *buffer)
Definition simulator.h:158
DISABLE_CFI_ICALL Return Call(Args... args)
Definition simulator.h:184
static GeneratedCode FromCode(Isolate *isolate, Tagged< Code > code)
Definition simulator.h:162
GeneratedCode(Isolate *isolate, Signature *fn_ptr)
Definition simulator.h:221
Return(Args...) Signature
Definition simulator.h:152
static void UnregisterJSStackComparableAddress(v8::internal::Isolate *isolate)
Definition simulator.h:139
static bool ShouldSwitchCStackForWasmStackSwitching()
Definition simulator.h:129
static void IterateRegistersAndStack(Isolate *isolate, ::heap::base::StackVisitor *visitor)
Definition simulator.h:124
static uintptr_t JsLimitFromCLimit(v8::internal::Isolate *isolate, uintptr_t c_limit)
Definition simulator.h:104
static uintptr_t RegisterJSStackComparableAddress(v8::internal::Isolate *isolate)
Definition simulator.h:133
static constexpr int kJSLimitOffsetKB
Definition stacks.h:163
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
EmitFn fn
constexpr Vector< T > VectorOf(T *start, size_t size)
Definition vector.h:360
uintptr_t GetCurrentStackPosition()
Definition utils.cc:222
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation trace turbo cfg trace TurboFan s graph trimmer trace TurboFan s control equivalence trace TurboFan s register allocator trace stack load store counters for optimized code in run fuzzing &&concurrent_recompilation trace_turbo trace_turbo_scheduled trace_turbo_stack_accesses verify TurboFan machine graph of code stubs enable FixedArray bounds checks print TurboFan statistics of wasm compilations maximum cumulative size of bytecode considered for inlining scale factor of bytecode size used to calculate the inlining budget * KB
Definition flags.cc:1366
#define FATAL(...)
Definition logging.h:47
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define USE(...)
Definition macros.h:293
#define DISABLE_CFI_ICALL
Definition macros.h:209