OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 return *reinterpret_cast<const int32_t *>(pc); | 135 return *reinterpret_cast<const int32_t *>(pc); |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 static int32_t Load16Aligned(const byte* pc) { | 139 static int32_t Load16Aligned(const byte* pc) { |
140 ASSERT((reinterpret_cast<intptr_t>(pc) & 1) == 0); | 140 ASSERT((reinterpret_cast<intptr_t>(pc) & 1) == 0); |
141 return *reinterpret_cast<const uint16_t *>(pc); | 141 return *reinterpret_cast<const uint16_t *>(pc); |
142 } | 142 } |
143 | 143 |
144 | 144 |
| 145 // A simple abstraction over the backtracking stack used by the interpreter. |
| 146 // This backtracking stack does not grow automatically, but it ensures that the |
| 147 // the memory held by the stack is released or remembered in a cache if the |
| 148 // matching terminates. |
| 149 class BacktrackStack { |
| 150 public: |
| 151 explicit BacktrackStack() { |
| 152 if (cache_ != NULL) { |
| 153 // If the cache is not empty reuse the previously allocated stack. |
| 154 data_ = cache_; |
| 155 cache_ = NULL; |
| 156 } else { |
| 157 // Cache was empty. Allocate a new backtrack stack. |
| 158 data_ = NewArray<int>(kBacktrackStackSize); |
| 159 } |
| 160 } |
| 161 |
| 162 ~BacktrackStack() { |
| 163 if (cache_ == NULL) { |
| 164 // The cache is empty. Keep this backtrack stack around. |
| 165 cache_ = data_; |
| 166 } else { |
| 167 // A backtrack stack was already cached, just release this one. |
| 168 DeleteArray(data_); |
| 169 } |
| 170 } |
| 171 |
| 172 int* data() const { return data_; } |
| 173 |
| 174 int max_size() const { return kBacktrackStackSize; } |
| 175 |
| 176 private: |
| 177 static const int kBacktrackStackSize = 10000; |
| 178 |
| 179 int* data_; |
| 180 static int* cache_; |
| 181 |
| 182 DISALLOW_COPY_AND_ASSIGN(BacktrackStack); |
| 183 }; |
| 184 |
| 185 int* BacktrackStack::cache_ = NULL; |
| 186 |
| 187 |
145 template <typename Char> | 188 template <typename Char> |
146 static bool RawMatch(const byte* code_base, | 189 static bool RawMatch(const byte* code_base, |
147 Vector<const Char> subject, | 190 Vector<const Char> subject, |
148 int* registers, | 191 int* registers, |
149 int current, | 192 int current, |
150 uint32_t current_char) { | 193 uint32_t current_char) { |
151 const byte* pc = code_base; | 194 const byte* pc = code_base; |
152 static const int kBacktrackStackSize = 10000; | 195 // BacktrackStack ensures that the memory allocated for the backtracking stack |
153 // Use a SmartPointer here to ensure that the memory gets freed when the | 196 // is returned to the system or cached if there is no stack being cached at |
154 // matching finishes. | 197 // the moment. |
155 SmartPointer<int> backtrack_stack(NewArray<int>(kBacktrackStackSize)); | 198 BacktrackStack backtrack_stack; |
156 int* backtrack_stack_base = *backtrack_stack; | 199 int* backtrack_stack_base = backtrack_stack.data(); |
157 int* backtrack_sp = backtrack_stack_base; | 200 int* backtrack_sp = backtrack_stack_base; |
158 int backtrack_stack_space = kBacktrackStackSize; | 201 int backtrack_stack_space = backtrack_stack.max_size(); |
159 #ifdef DEBUG | 202 #ifdef DEBUG |
160 if (FLAG_trace_regexp_bytecodes) { | 203 if (FLAG_trace_regexp_bytecodes) { |
161 PrintF("\n\nStart bytecode interpreter\n\n"); | 204 PrintF("\n\nStart bytecode interpreter\n\n"); |
162 } | 205 } |
163 #endif | 206 #endif |
164 while (true) { | 207 while (true) { |
165 int32_t insn = Load32Aligned(pc); | 208 int32_t insn = Load32Aligned(pc); |
166 switch (insn & BYTECODE_MASK) { | 209 switch (insn & BYTECODE_MASK) { |
167 BYTECODE(BREAK) | 210 BYTECODE(BREAK) |
168 UNREACHABLE(); | 211 UNREACHABLE(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 BYTECODE(SET_CP_TO_REGISTER) | 246 BYTECODE(SET_CP_TO_REGISTER) |
204 current = registers[insn >> BYTECODE_SHIFT]; | 247 current = registers[insn >> BYTECODE_SHIFT]; |
205 pc += BC_SET_CP_TO_REGISTER_LENGTH; | 248 pc += BC_SET_CP_TO_REGISTER_LENGTH; |
206 break; | 249 break; |
207 BYTECODE(SET_REGISTER_TO_SP) | 250 BYTECODE(SET_REGISTER_TO_SP) |
208 registers[insn >> BYTECODE_SHIFT] = backtrack_sp - backtrack_stack_base; | 251 registers[insn >> BYTECODE_SHIFT] = backtrack_sp - backtrack_stack_base; |
209 pc += BC_SET_REGISTER_TO_SP_LENGTH; | 252 pc += BC_SET_REGISTER_TO_SP_LENGTH; |
210 break; | 253 break; |
211 BYTECODE(SET_SP_TO_REGISTER) | 254 BYTECODE(SET_SP_TO_REGISTER) |
212 backtrack_sp = backtrack_stack_base + registers[insn >> BYTECODE_SHIFT]; | 255 backtrack_sp = backtrack_stack_base + registers[insn >> BYTECODE_SHIFT]; |
213 backtrack_stack_space = kBacktrackStackSize - | 256 backtrack_stack_space = backtrack_stack.max_size() - |
214 (backtrack_sp - backtrack_stack_base); | 257 (backtrack_sp - backtrack_stack_base); |
215 pc += BC_SET_SP_TO_REGISTER_LENGTH; | 258 pc += BC_SET_SP_TO_REGISTER_LENGTH; |
216 break; | 259 break; |
217 BYTECODE(POP_CP) | 260 BYTECODE(POP_CP) |
218 backtrack_stack_space++; | 261 backtrack_stack_space++; |
219 --backtrack_sp; | 262 --backtrack_sp; |
220 current = *backtrack_sp; | 263 current = *backtrack_sp; |
221 pc += BC_POP_CP_LENGTH; | 264 pc += BC_POP_CP_LENGTH; |
222 break; | 265 break; |
223 BYTECODE(POP_BT) | 266 BYTECODE(POP_BT) |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 if (start_position != 0) previous_char = subject_vector[start_position - 1]; | 634 if (start_position != 0) previous_char = subject_vector[start_position - 1]; |
592 return RawMatch(code_base, | 635 return RawMatch(code_base, |
593 subject_vector, | 636 subject_vector, |
594 registers, | 637 registers, |
595 start_position, | 638 start_position, |
596 previous_char); | 639 previous_char); |
597 } | 640 } |
598 } | 641 } |
599 | 642 |
600 } } // namespace v8::internal | 643 } } // namespace v8::internal |
OLD | NEW |