| Index: src/interpreter-irregexp.cc
|
| ===================================================================
|
| --- src/interpreter-irregexp.cc (revision 2340)
|
| +++ src/interpreter-irregexp.cc (working copy)
|
| @@ -142,6 +142,49 @@
|
| }
|
|
|
|
|
| +// A simple abstraction over the backtracking stack used by the interpreter.
|
| +// This backtracking stack does not grow automatically, but it ensures that the
|
| +// the memory held by the stack is released or remembered in a cache if the
|
| +// matching terminates.
|
| +class BacktrackStack {
|
| + public:
|
| + explicit BacktrackStack() {
|
| + if (cache_ != NULL) {
|
| + // If the cache is not empty reuse the previously allocated stack.
|
| + data_ = cache_;
|
| + cache_ = NULL;
|
| + } else {
|
| + // Cache was empty. Allocate a new backtrack stack.
|
| + data_ = NewArray<int>(kBacktrackStackSize);
|
| + }
|
| + }
|
| +
|
| + ~BacktrackStack() {
|
| + if (cache_ == NULL) {
|
| + // The cache is empty. Keep this backtrack stack around.
|
| + cache_ = data_;
|
| + } else {
|
| + // A backtrack stack was already cached, just release this one.
|
| + DeleteArray(data_);
|
| + }
|
| + }
|
| +
|
| + int* data() const { return data_; }
|
| +
|
| + int max_size() const { return kBacktrackStackSize; }
|
| +
|
| + private:
|
| + static const int kBacktrackStackSize = 10000;
|
| +
|
| + int* data_;
|
| + static int* cache_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BacktrackStack);
|
| +};
|
| +
|
| +int* BacktrackStack::cache_ = NULL;
|
| +
|
| +
|
| template <typename Char>
|
| static bool RawMatch(const byte* code_base,
|
| Vector<const Char> subject,
|
| @@ -149,13 +192,13 @@
|
| int current,
|
| uint32_t current_char) {
|
| const byte* pc = code_base;
|
| - static const int kBacktrackStackSize = 10000;
|
| - // Use a SmartPointer here to ensure that the memory gets freed when the
|
| - // matching finishes.
|
| - SmartPointer<int> backtrack_stack(NewArray<int>(kBacktrackStackSize));
|
| - int* backtrack_stack_base = *backtrack_stack;
|
| + // BacktrackStack ensures that the memory allocated for the backtracking stack
|
| + // is returned to the system or cached if there is no stack being cached at
|
| + // the moment.
|
| + BacktrackStack backtrack_stack;
|
| + int* backtrack_stack_base = backtrack_stack.data();
|
| int* backtrack_sp = backtrack_stack_base;
|
| - int backtrack_stack_space = kBacktrackStackSize;
|
| + int backtrack_stack_space = backtrack_stack.max_size();
|
| #ifdef DEBUG
|
| if (FLAG_trace_regexp_bytecodes) {
|
| PrintF("\n\nStart bytecode interpreter\n\n");
|
| @@ -210,7 +253,7 @@
|
| break;
|
| BYTECODE(SET_SP_TO_REGISTER)
|
| backtrack_sp = backtrack_stack_base + registers[insn >> BYTECODE_SHIFT];
|
| - backtrack_stack_space = kBacktrackStackSize -
|
| + backtrack_stack_space = backtrack_stack.max_size() -
|
| (backtrack_sp - backtrack_stack_base);
|
| pc += BC_SET_SP_TO_REGISTER_LENGTH;
|
| break;
|
|
|