35 void SetStackLimit(uintptr_t limit);
40 void SetStackLimitForStackSwitching(uintptr_t limit);
46 void AdjustStackLimitForSimulator();
48 void ResetStackLimitForSimulator();
52 char* ArchiveStackGuard(
char* to);
53 char* RestoreStackGuard(
char* from);
55 void FreeThreadResources();
66 static constexpr int kNumberOfInterruptLevels = 3;
68#define INTERRUPT_LIST(V) \
69 V(TERMINATE_EXECUTION, TerminateExecution, 0, InterruptLevel::kNoGC) \
70 V(GC_REQUEST, GC, 1, InterruptLevel::kNoHeapWrites) \
71 V(INSTALL_CODE, InstallCode, 2, InterruptLevel::kAnyEffect) \
72 V(INSTALL_BASELINE_CODE, InstallBaselineCode, 3, InterruptLevel::kAnyEffect) \
73 V(API_INTERRUPT, ApiInterrupt, 4, InterruptLevel::kNoHeapWrites) \
74 V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 5, \
75 InterruptLevel::kNoHeapWrites) \
76 V(GROW_SHARED_MEMORY, GrowSharedMemory, 6, InterruptLevel::kAnyEffect) \
77 V(LOG_WASM_CODE, LogWasmCode, 7, InterruptLevel::kAnyEffect) \
78 V(WASM_CODE_GC, WasmCodeGC, 8, InterruptLevel::kNoHeapWrites) \
79 V(INSTALL_MAGLEV_CODE, InstallMaglevCode, 9, InterruptLevel::kAnyEffect) \
80 V(GLOBAL_SAFEPOINT, GlobalSafepoint, 10, InterruptLevel::kNoHeapWrites) \
81 V(START_INCREMENTAL_MARKING, StartIncrementalMarking, 11, \
82 InterruptLevel::kNoHeapWrites)
84#define V(NAME, Name, id, interrupt_level) \
85 inline bool Check##Name() { return CheckInterrupt(NAME); } \
86 inline void Request##Name() { RequestInterrupt(NAME); } \
87 inline void Clear##Name() { ClearInterrupt(NAME); }
93#define V(NAME, Name, id, interrupt_level) NAME = (1 << id),
96#define V(NAME, Name, id, interrupt_level) NAME |
100 static_assert(InterruptFlag::ALL_INTERRUPTS <
101 std::numeric_limits<uint32_t>::max());
104#define V(NAME, Name, id, interrupt_level) \
105 | (interrupt_level <= level ? NAME : 0)
112 return thread_local_.climit();
114 return thread_local_.jslimit();
117 uintptr_t
jslimit() {
return thread_local_.jslimit(); }
123 return thread_local_.real_climit_;
125 return thread_local_.real_jslimit_;
130 return reinterpret_cast<Address
>(&thread_local_.jslimit_);
133 return reinterpret_cast<Address
>(&thread_local_.real_jslimit_);
136 return reinterpret_cast<Address
>(
137 &thread_local_.interrupt_requested_[
static_cast<int>(level)]);
155 InterruptLevel level = InterruptLevel::kAnyEffect);
160 bool HasTerminationRequest();
165 return thread_storage + ArchiveSpacePerThread();
169 bool CheckInterrupt(InterruptFlag flag);
170 void RequestInterrupt(InterruptFlag flag);
171 void ClearInterrupt(InterruptFlag flag);
172 int FetchAndClearInterrupts(InterruptLevel level);
174 void SetStackLimitInternal(
const ExecutionAccess& lock, uintptr_t limit,
179 return thread_local_.interrupt_flags_ != 0;
183 inline void update_interrupt_requests_and_stack_limits(
186#if V8_TARGET_ARCH_64_BIT
187 static const uintptr_t kInterruptLimit = uintptr_t{0xfffffffffffffffe};
188 static const uintptr_t kIllegalLimit = uintptr_t{0xfffffffffffffff8};
190 static const uintptr_t kInterruptLimit = 0xfffffffe;
191 static const uintptr_t kIllegalLimit = 0xfffffff8;
195 void PopInterruptsScope();
212 uintptr_t real_jslimit_ = kIllegalLimit;
215 uintptr_t real_climit_ = kIllegalLimit;
242 return base::bit_cast<uintptr_t>(base::Relaxed_Load(&jslimit_));
245 return base::Relaxed_Store(&jslimit_,
250 return base::bit_cast<uintptr_t>(base::Relaxed_Load(&climit_));
252 void set_climit(uintptr_t limit) {
253 return base::Relaxed_Store(&climit_,
261 false,
false,
false};
264 base::Relaxed_Store(&interrupt_requested_[
static_cast<int>(level)],
269 return base::Relaxed_Load(&interrupt_requested_[
static_cast<int>(level)]);
273 uint32_t interrupt_flags_ = 0;
285 static_assert(std::is_standard_layout<ThreadLocal>::value);