| 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 |