Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99: */
3 :
4 : // Copyright 2009 the V8 project authors. All rights reserved.
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following
13 : // disclaimer in the documentation and/or other materials provided
14 : // with the distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived
17 : // from this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : #ifndef V8_REGEXP_STACK_H_
32 : #define V8_REGEXP_STACK_H_
33 :
34 : #include "jspubtd.h"
35 : #include "js/Utility.h"
36 :
37 : namespace js {
38 : namespace irregexp {
39 :
40 : class RegExpStack;
41 :
42 : // Maintains a per-thread stack area that can be used by irregexp
43 : // implementation for its backtracking stack.
44 : //
45 : // Since there is only one stack area, the Irregexp implementation is not
46 : // re-entrant. I.e., no regular expressions may be executed in the same thread
47 : // during a preempted Irregexp execution.
48 : class RegExpStackScope
49 : {
50 : public:
51 : // Create and delete an instance to control the life-time of a growing stack.
52 :
53 : // Initializes the stack memory area if necessary.
54 : explicit RegExpStackScope(JSContext* cx);
55 :
56 : // Releases the stack if it has grown.
57 : ~RegExpStackScope();
58 :
59 : private:
60 : RegExpStack* regexp_stack;
61 : };
62 :
63 : class RegExpStack
64 : {
65 : public:
66 : // Number of allocated locations on the stack above the limit.
67 : // No sequence of pushes must be longer that this without doing a stack-limit
68 : // check.
69 : static const int kStackLimitSlack = 32;
70 :
71 : RegExpStack();
72 : ~RegExpStack();
73 : bool init();
74 :
75 : // Resets the buffer if it has grown beyond the default/minimum size.
76 : void reset();
77 :
78 : // Attempts to grow the stack by at least kStackLimitSlack entries.
79 : bool grow();
80 :
81 : // Address of allocated memory.
82 80 : static size_t offsetOfBase() { return offsetof(RegExpStack, base_); }
83 206 : static size_t offsetOfLimit() { return offsetof(RegExpStack, limit_); }
84 :
85 8 : void* base() { return base_; }
86 0 : void* limit() { return limit_; }
87 :
88 : private:
89 : // Artificial limit used when no memory has been allocated.
90 : static const uintptr_t kMemoryTop = static_cast<uintptr_t>(-1);
91 :
92 : // Minimal size of allocated stack area, in bytes.
93 : static const size_t kMinimumStackSize = 1 * 1024;
94 :
95 : // Maximal size of allocated stack area, in bytes.
96 : static const size_t kMaximumStackSize = 64 * 1024 * 1024;
97 :
98 : // If size > 0 then base must be non-nullptr.
99 : void* base_;
100 :
101 : // Length in bytes of base.
102 : size_t size;
103 :
104 : // If the stack pointer gets above the limit, we should react and
105 : // either grow the stack or report an out-of-stack exception.
106 : // There is only a limited number of locations above the stack limit,
107 : // so users of the stack should check the stack limit during any
108 : // sequence of pushes longer than this.
109 : void* limit_;
110 :
111 8 : void updateLimit() {
112 8 : MOZ_ASSERT(size >= kStackLimitSlack * sizeof(void*));
113 8 : limit_ = static_cast<uint8_t*>(base()) + size - (kStackLimitSlack * sizeof(void*));
114 8 : }
115 : };
116 :
117 : int
118 : GrowBacktrackStack(JSRuntime* rt);
119 :
120 : }} // namespace js::irregexp
121 :
122 : #endif // V8_REGEXP_STACK_H_
|