v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
thread-local-top.h
Go to the documentation of this file.
1// Copyright 2019 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_THREAD_LOCAL_TOP_H_
6#define V8_EXECUTION_THREAD_LOCAL_TOP_H_
7
11#include "include/v8-unwinder.h"
12#include "src/common/globals.h"
15#include "src/utils/utils.h"
16
17namespace v8 {
18
19class TryCatch;
20
21namespace internal {
22
23class EmbedderState;
24class ExternalCallbackScope;
25class Isolate;
26class Simulator;
27
29 public:
30 // TODO(all): This is not particularly beautiful. We should probably
31 // refactor this to really consist of just Addresses and 32-bit
32 // integer fields.
33 static constexpr uint32_t kSizeInBytes = 30 * kSystemPointerSize;
34
35 // Does early low-level initialization that does not depend on the
36 // isolate being present.
38
39 void Clear();
40
41 // Initialize the thread data.
42 void Initialize(Isolate*);
43
44 // Get the address of the top C++ try catch handler or nullptr if
45 // none are registered.
46 //
47 // This method always returns an address that can be compared to
48 // pointers into the JavaScript stack. When running on actual
49 // hardware, try_catch_handler_address and TryCatchHandler return
50 // the same pointer. When running on a simulator with a separate JS
51 // stack, try_catch_handler_address returns a JS stack address that
52 // corresponds to the place on the JS stack where the C++ handler
53 // would have been if the stack were not separate.
60
61 // Call depth represents nested v8 api calls. Instead of storing the nesting
62 // level as an integer, we store the stack height of the last API entry. This
63 // additional information is used when we decide whether to trigger a debug
64 // break at a function entry.
65 template <bool clear_exception, typename Scope>
66 void IncrementCallDepth(Scope* stack_allocated_scope) {
67 stack_allocated_scope->previous_stack_height_ = last_api_entry_;
68#if defined(USE_SIMULATOR) || defined(V8_USE_ADDRESS_SANITIZER)
69 StoreCurrentStackPosition();
70#else
71 last_api_entry_ = reinterpret_cast<i::Address>(stack_allocated_scope);
72#endif
73 if constexpr (clear_exception) {
75 Internals::GetRoot(reinterpret_cast<v8::Isolate*>(isolate_),
77 }
78 }
79
80#if defined(USE_SIMULATOR) || defined(V8_USE_ADDRESS_SANITIZER)
81 void StoreCurrentStackPosition();
82#endif
83
84 template <typename Scope>
85 void DecrementCallDepth(Scope* stack_allocated_scope) {
86 last_api_entry_ = stack_allocated_scope->previous_stack_height_;
87 }
88
89 bool CallDepthIsZero() const { return last_api_entry_ == kNullAddress; }
90
91 void Free();
92
93 // Group fields updated on every CEntry/CallApiCallback/CallApiGetter call
94 // together. See MacroAssembler::EnterExitFram/LeaveExitFrame.
95 // [ CEntry/CallApiCallback/CallApiGetter
96
97 // The frame pointer of the top c entry frame.
99 // C function that was called at c entry.
101 // The context where the current execution method is created and for
102 // variable lookups.
103 // TODO(3770): This field is read/written from generated code, so it would
104 // be cleaner to make it an "Address raw_context_", and construct a Context
105 // object in the getter. Same for {pending_handler_context_} below. In the
106 // meantime, assert that the memory layout is the same.
107 static_assert(sizeof(Tagged<Context>) == kSystemPointerSize);
109
110 // The "topmost script-having execution context" from the Web IDL spec
111 // (i.e. the context of the topmost user JavaScript code, see
112 // https://html.spec.whatwg.org/multipage/webappapis.html#topmost-script-having-execution-context)
113 // if known or Context::kNoContext otherwise. It's guaranteed to be valid
114 // only when read from within Api function callback or Api getter/setter
115 // callbacks. The caller context is set to the current context from generated
116 // code/builtins right before calling the Api callback when it's guaraneed
117 // that current context belongs to user JavaScript code:
118 // - when an Api getter/setter function callback is called by IC system
119 // from interpreter or baseline code,
120 // - when an Api callback is called from optimized code (Maglev or TurboFan).
121 //
122 // Once the caller context value becomes outdated it's reset to kNoContext
123 // in order to enforce the slow mechanism involving stack iteration.
124 // This happens in the following cases:
125 // - when an Api function is called as a regular JSFunction (it's not worth
126 // the efforts of properly propagating the topmost user script-having
127 // context through a potential sequence of builtin function calls),
128 // - when execution crosses C++ to JS boundary (Execution::Call*/New),
129 // - when execution crosses JS to Wasm boundary or Wasm to JS bounary
130 // (it's not worth the efforts of propagating the caller context
131 // through Wasm, especially with Wasm stack switching),
132 // - when an optimized function is deoptimized (for simplicity),
133 // - after stack unwinding because of thrown exception.
134 //
135 // GC treats this value as a weak reference and resets it back to kNoContext
136 // if the context dies.
138
139 // This field is updated along with context_ on every operation triggered
140 // via V8 Api.
142
143 // ] CEntry/CallApiCallback/CallApiGetter fields.
144
146
147 static constexpr int exception_offset() {
148 return offsetof(ThreadLocalTop, exception_);
149 }
150
151 // Communication channel between Isolate::FindHandler and the CEntry.
157
158 // The top C++ try catch handler or nullptr if none are registered.
159 //
160 // This field is not guaranteed to hold an address that can be
161 // used for comparison with addresses into the JS stack. If such
162 // an address is needed, use try_catch_handler_address.
164
165 // These two fields are updated rarely (on every thread restore).
167 std::atomic<ThreadId> thread_id_;
168
169 // TODO(all): Combine into a bitfield.
171 // Wasm Stack Switching: The central stack.
172 // If set, then we are currently executing code on the central stack.
175
176 // Communication channel between Isolate::Throw and message consumers.
178
179 // Try-blocks are chained through the stack.
181
182 // Simulator field is always present to get predictable layout.
183 Simulator* simulator_;
184
185 // The stack pointer of the bottom JS entry frame.
187 // The external callback we're currently in.
191
192 // The top entry of the v8::Context::BackupIncumbentScope stack.
194
195 // Call back function to report unsafe JS accesses.
197
198 // Address of the thread-local "thread in wasm" flag.
200
201 // On switching from the central stack these fields are set
202 // to the central stack's SP and stack limit accordingly,
203 // to use for switching from secondary stacks.
206 // On switching to the central stack these fields are set
207 // to the secondary stack's SP and stack limit accordingly.
208 // It is used if we need to check for the stack overflow condition
209 // on the secondary stack, during execution on the central stack.
212};
213
214static_assert(ThreadLocalTop::kSizeInBytes == sizeof(ThreadLocalTop));
215
216} // namespace internal
217} // namespace v8
218
219#endif // V8_EXECUTION_THREAD_LOCAL_TOP_H_
internal::Address JSStackComparableAddressPrivate()
static V8_INLINE Address GetRoot(v8::Isolate *isolate, int index)
static const int kTheHoleValueRootIndex
static constexpr Tagged< Smi > zero()
Definition smi.h:99
static constexpr uint32_t kSizeInBytes
static constexpr int exception_offset()
ExternalCallbackScope * external_callback_scope_
Tagged< Context > pending_handler_context_
void DecrementCallDepth(Scope *stack_allocated_scope)
const v8::Context::BackupIncumbentScope * top_backup_incumbent_scope_
v8::FailedAccessCheckCallback failed_access_check_callback_
void IncrementCallDepth(Scope *stack_allocated_scope)
EmbedderState * current_embedder_state_
std::atomic< ThreadId > thread_id_
Tagged< Context > topmost_script_having_context_
constexpr int kSystemPointerSize
Definition globals.h:410
static constexpr Address kNullAddress
Definition v8-internal.h:53
void(*)(Local< Object > target, AccessType type, Local< Value > data) FailedAccessCheckCallback
StateTag
Definition v8-unwinder.h:36