v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
regexp-stack.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_REGEXP_REGEXP_STACK_H_
6#define V8_REGEXP_REGEXP_STACK_H_
7
8#include "src/base/logging.h"
9#include "src/base/macros.h"
10#include "src/common/globals.h"
11
12namespace v8 {
13namespace internal {
14
15class RegExpStack;
16
17// Maintains a per-v8thread stack area that can be used by irregexp
18// implementation for its backtracking stack.
20 public:
21 // Create and delete an instance to control the life-time of a growing stack.
22
23 // Initializes the stack memory area if necessary.
24 explicit RegExpStackScope(Isolate* isolate);
25 ~RegExpStackScope(); // Releases the stack if it has grown.
28
29 RegExpStack* stack() const { return regexp_stack_; }
30
31 private:
33 const ptrdiff_t old_sp_top_delta_;
34};
35
36class RegExpStack final {
37 public:
40 RegExpStack(const RegExpStack&) = delete;
42
43#if defined(V8_TARGET_ARCH_PPC64) || defined(V8_TARGET_ARCH_S390X)
44 static constexpr int kSlotSize = kSystemPointerSize;
45#else
46 static constexpr int kSlotSize = kInt32Size;
47#endif
48 // Number of allocated locations on the stack below the limit. No sequence of
49 // pushes must be longer than this without doing a stack-limit check.
50 static constexpr int kStackLimitSlackSlotCount = 32;
51 static constexpr int kStackLimitSlackSize =
53
54 Address begin() const {
55 return reinterpret_cast<Address>(thread_local_.memory_);
56 }
63 Address memory_top() const { return end(); }
64
66 return reinterpret_cast<Address>(thread_local_.stack_pointer_);
67 }
68
69 size_t memory_size() const { return thread_local_.memory_size_; }
70
71 // If the stack pointer gets below the limit, we should react and
72 // either grow the stack or report an out-of-stack exception.
73 // There is only a limited number of locations below the stack limit,
74 // so users of the stack should check the stack limit during any
75 // sequence of pushes longer that this.
77
78 // Ensures that there is a memory area with at least the specified size.
79 // If passing zero, the default/minimum size buffer is allocated.
80 Address EnsureCapacity(size_t size);
81
82 // Thread local archiving.
83 static constexpr int ArchiveSpacePerThread() {
84 return static_cast<int>(kThreadLocalSize);
85 }
86 char* ArchiveStack(char* to);
87 char* RestoreStack(char* from);
89
90 // Maximal size of allocated stack area.
91 static constexpr size_t kMaximumStackSize = 64 * MB;
92
93 private:
94 // Artificial limit used when the thread-local state has been destroyed.
95 static const Address kMemoryTop =
96 static_cast<Address>(static_cast<uintptr_t>(-1));
97
98 // In addition to dynamically-allocated, variable-sized stacks, we also have
99 // a statically allocated and sized area that is used whenever no dynamic
100 // stack is allocated. This guarantees that a stack is always available and
101 // we can skip availability-checks later on.
102 static constexpr size_t kStaticStackSize = 1 * KB;
103 // It's at least double the slack size to ensure that we have a bit of
104 // breathing room before NativeRegExpMacroAssembler::GrowStack must be
105 // called.
106 static_assert(kStaticStackSize >= 2 * kStackLimitSlackSize);
107 static_assert(kStaticStackSize <= kMaximumStackSize);
109
110 // Minimal size of dynamically-allocated stack area.
111 static constexpr size_t kMinimumDynamicStackSize = 2 * KB;
112 static_assert(kMinimumDynamicStackSize == 2 * kStaticStackSize);
113
114 // Structure holding the allocated memory, size and limit. Thread switching
115 // archives and restores this struct.
116 struct ThreadLocal {
117 explicit ThreadLocal(RegExpStack* regexp_stack) {
118 ResetToStaticStack(regexp_stack);
119 }
120
121 // If memory_size_ > 0 then
122 // - memory_, memory_top_, stack_pointer_ must be non-nullptr
123 // - memory_top_ = memory_ + memory_size_
124 // - memory_ <= stack_pointer_ <= memory_top_
125 uint8_t* memory_ = nullptr;
126 uint8_t* memory_top_ = nullptr;
127 size_t memory_size_ = 0;
128 uint8_t* stack_pointer_ = nullptr;
130 bool owns_memory_ = false; // Whether memory_ is owned and must be freed.
131
132 void ResetToStaticStack(RegExpStack* regexp_stack);
134 if (stack_pointer_ == memory_top_) ResetToStaticStack(regexp_stack);
135 }
136 void FreeAndInvalidate();
137 };
138 static constexpr size_t kThreadLocalSize = sizeof(ThreadLocal);
139
141 return reinterpret_cast<Address>(&thread_local_.memory_top_);
142 }
143
145 return reinterpret_cast<Address>(&thread_local_.stack_pointer_);
146 }
147
148 // A position-independent representation of the stack pointer.
149 ptrdiff_t sp_top_delta() const {
150 ptrdiff_t result =
151 reinterpret_cast<intptr_t>(thread_local_.stack_pointer_) -
152 reinterpret_cast<intptr_t>(thread_local_.memory_top_);
153 DCHECK_LE(result, 0);
154 return result;
155 }
156
157 // Resets the buffer if it has grown beyond the default/minimum size and is
158 // empty.
160
161 // Whether the ThreadLocal storage has been invalidated.
162 bool IsValid() const { return thread_local_.memory_ != nullptr; }
163
165
166 friend class ExternalReference;
167 friend class RegExpStackScope;
168};
169
170} // namespace internal
171} // namespace v8
172
173#endif // V8_REGEXP_REGEXP_STACK_H_
RegExpStack *const regexp_stack_
RegExpStackScope(const RegExpStackScope &)=delete
const ptrdiff_t old_sp_top_delta_
RegExpStackScope & operator=(const RegExpStackScope &)=delete
RegExpStack * stack() const
static constexpr size_t kThreadLocalSize
Address memory_top() const
char * ArchiveStack(char *to)
static constexpr int kStackLimitSlackSlotCount
size_t memory_size() const
static constexpr int kStackLimitSlackSize
static const Address kMemoryTop
ptrdiff_t sp_top_delta() const
RegExpStack & operator=(const RegExpStack &)=delete
static constexpr size_t kStaticStackSize
Address EnsureCapacity(size_t size)
Address stack_pointer() const
static constexpr int ArchiveSpacePerThread()
char * RestoreStack(char *from)
static constexpr int kSlotSize
uint8_t static_stack_[kStaticStackSize]
Address * limit_address_address()
RegExpStack(const RegExpStack &)=delete
static constexpr size_t kMinimumDynamicStackSize
static constexpr size_t kMaximumStackSize
ZoneVector< RpoNumber > & result
constexpr int kSystemPointerSize
Definition globals.h:410
constexpr int kInt32Size
Definition globals.h:401
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
static constexpr Address kNullAddress
Definition v8-internal.h:53
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage * MB
Definition flags.cc:2197
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
ThreadLocal(RegExpStack *regexp_stack)
void ResetToStaticStackIfEmpty(RegExpStack *regexp_stack)
void ResetToStaticStack(RegExpStack *regexp_stack)
#define V8_NODISCARD
Definition v8config.h:693