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