Line data Source code
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/globals.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : class RegExpStack;
16 :
17 : // Maintains a per-v8thread stack area that can be used by irregexp
18 : // implementation for its backtracking stack.
19 : // Since there is only one stack area, the Irregexp implementation is not
20 : // re-entrant. I.e., no regular expressions may be executed in the same thread
21 : // during a preempted Irregexp execution.
22 : class RegExpStackScope {
23 : public:
24 : // Create and delete an instance to control the life-time of a growing stack.
25 :
26 : // Initializes the stack memory area if necessary.
27 : explicit RegExpStackScope(Isolate* isolate);
28 : ~RegExpStackScope(); // Releases the stack if it has grown.
29 :
30 111469 : RegExpStack* stack() const { return regexp_stack_; }
31 :
32 : private:
33 : RegExpStack* regexp_stack_;
34 :
35 : DISALLOW_COPY_AND_ASSIGN(RegExpStackScope);
36 : };
37 :
38 :
39 : class RegExpStack {
40 : public:
41 : // Number of allocated locations on the stack below the limit.
42 : // No sequence of pushes must be longer that this without doing a stack-limit
43 : // check.
44 : static const int kStackLimitSlack = 32;
45 :
46 : // Gives the top of the memory used as stack.
47 : Address stack_base() {
48 : DCHECK_NE(0, thread_local_.memory_size_);
49 111819 : return reinterpret_cast<Address>(thread_local_.memory_) +
50 111819 : thread_local_.memory_size_;
51 : }
52 :
53 : // The total size of the memory allocated for the stack.
54 : size_t stack_capacity() { return thread_local_.memory_size_; }
55 :
56 : // If the stack pointer gets below the limit, we should react and
57 : // either grow the stack or report an out-of-stack exception.
58 : // There is only a limited number of locations below the stack limit,
59 : // so users of the stack should check the stack limit during any
60 : // sequence of pushes longer that this.
61 590123 : Address* limit_address() { return &(thread_local_.limit_); }
62 :
63 : // Ensures that there is a memory area with at least the specified size.
64 : // If passing zero, the default/minimum size buffer is allocated.
65 : Address EnsureCapacity(size_t size);
66 :
67 : // Thread local archiving.
68 : static int ArchiveSpacePerThread() {
69 : return static_cast<int>(sizeof(ThreadLocal));
70 : }
71 : char* ArchiveStack(char* to);
72 : char* RestoreStack(char* from);
73 5918 : void FreeThreadResources() { thread_local_.Free(); }
74 :
75 : private:
76 : RegExpStack();
77 : ~RegExpStack();
78 :
79 : // Artificial limit used when no memory has been allocated.
80 : static const Address kMemoryTop =
81 : static_cast<Address>(static_cast<uintptr_t>(-1));
82 :
83 : // Minimal size of allocated stack area.
84 : static const size_t kMinimumStackSize = 1 * KB;
85 :
86 : // Maximal size of allocated stack area.
87 : static const size_t kMaximumStackSize = 64 * MB;
88 :
89 : // Structure holding the allocated memory, size and limit.
90 : struct ThreadLocal {
91 : ThreadLocal() { Clear(); }
92 : // If memory_size_ > 0 then memory_ must be non-nullptr.
93 : byte* memory_;
94 : size_t memory_size_;
95 : Address limit_;
96 : void Clear() {
97 66566 : memory_ = nullptr;
98 66566 : memory_size_ = 0;
99 66566 : limit_ = kMemoryTop;
100 : }
101 : void Free();
102 : };
103 :
104 : // Address of allocated memory.
105 : Address memory_address() {
106 62982 : return reinterpret_cast<Address>(&thread_local_.memory_);
107 : }
108 :
109 : // Address of size of allocated memory.
110 : Address memory_size_address() {
111 62982 : return reinterpret_cast<Address>(&thread_local_.memory_size_);
112 : }
113 :
114 : // Resets the buffer if it has grown beyond the default/minimum size.
115 : // After this, the buffer is either the default size, or it is empty, so
116 : // you have to call EnsureCapacity before using it again.
117 : void Reset();
118 :
119 : ThreadLocal thread_local_;
120 : Isolate* isolate_;
121 :
122 : friend class ExternalReference;
123 : friend class Isolate;
124 : friend class RegExpStackScope;
125 :
126 : DISALLOW_COPY_AND_ASSIGN(RegExpStack);
127 : };
128 :
129 : } // namespace internal
130 : } // namespace v8
131 :
132 : #endif // V8_REGEXP_REGEXP_STACK_H_
|