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