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 700478 : 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(thread_local_.memory_size_ != 0);
49 700983 : return thread_local_.memory_ + thread_local_.memory_size_;
50 : }
51 :
52 : // The total size of the memory allocated for the stack.
53 : size_t stack_capacity() { return thread_local_.memory_size_; }
54 :
55 : // If the stack pointer gets below the limit, we should react and
56 : // either grow the stack or report an out-of-stack exception.
57 : // There is only a limited number of locations below the stack limit,
58 : // so users of the stack should check the stack limit during any
59 : // sequence of pushes longer that this.
60 : Address* limit_address() { return &(thread_local_.limit_); }
61 :
62 : // Ensures that there is a memory area with at least the specified size.
63 : // If passing zero, the default/minimum size buffer is allocated.
64 : Address EnsureCapacity(size_t size);
65 :
66 : // Thread local archiving.
67 : static int ArchiveSpacePerThread() {
68 : return static_cast<int>(sizeof(ThreadLocal));
69 : }
70 : char* ArchiveStack(char* to);
71 : char* RestoreStack(char* from);
72 6863 : void FreeThreadResources() { thread_local_.Free(); }
73 :
74 : private:
75 : RegExpStack();
76 : ~RegExpStack();
77 :
78 : // Artificial limit used when no memory has been allocated.
79 : static const uintptr_t kMemoryTop = static_cast<uintptr_t>(-1);
80 :
81 : // Minimal size of allocated stack area.
82 : static const size_t kMinimumStackSize = 1 * KB;
83 :
84 : // Maximal size of allocated stack area.
85 : static const size_t kMaximumStackSize = 64 * MB;
86 :
87 : // Structure holding the allocated memory, size and limit.
88 : struct ThreadLocal {
89 : ThreadLocal() { Clear(); }
90 : // If memory_size_ > 0 then memory_ must be non-NULL.
91 : Address memory_;
92 : size_t memory_size_;
93 : Address limit_;
94 : void Clear() {
95 65949 : memory_ = NULL;
96 65949 : memory_size_ = 0;
97 65949 : limit_ = reinterpret_cast<Address>(kMemoryTop);
98 : }
99 : void Free();
100 : };
101 :
102 : // Address of allocated memory.
103 : Address memory_address() {
104 : return reinterpret_cast<Address>(&thread_local_.memory_);
105 : }
106 :
107 : // Address of size of allocated memory.
108 : Address memory_size_address() {
109 : return reinterpret_cast<Address>(&thread_local_.memory_size_);
110 : }
111 :
112 : // Resets the buffer if it has grown beyond the default/minimum size.
113 : // After this, the buffer is either the default size, or it is empty, so
114 : // you have to call EnsureCapacity before using it again.
115 : void Reset();
116 :
117 : ThreadLocal thread_local_;
118 : Isolate* isolate_;
119 :
120 : friend class ExternalReference;
121 : friend class Isolate;
122 : friend class RegExpStackScope;
123 :
124 : DISALLOW_COPY_AND_ASSIGN(RegExpStack);
125 : };
126 :
127 : } // namespace internal
128 : } // namespace v8
129 :
130 : #endif // V8_REGEXP_REGEXP_STACK_H_
|