Author: [email protected]
Date: Thu Feb 19 00:24:28 2009
New Revision: 1309

Modified:
    branches/bleeding_edge/src/jsregexp.cc
    branches/bleeding_edge/src/jsregexp.h

Log:
Limit how many places we generate code to flush the same actions.  This  
gives a
13% code size reduction in the php regexp with no discernable performance  
loss.
Review URL: http://codereview.chromium.org/20457

Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc      (original)
+++ branches/bleeding_edge/src/jsregexp.cc      Thu Feb 19 00:24:28 2009
@@ -1527,6 +1527,13 @@
    // Generate deferred actions here along with code to undo them again.
    OutSet affected_registers;

+  if (backtrack() != NULL) {
+    // Here we have a concrete backtrack location.  These are set up by  
choice
+    // nodes and so they indicate that we have a deferred save of the  
current
+    // position which we may need to emit here.
+    assembler->PushCurrentPosition();
+  }
+
    int max_register = FindAffectedRegisters(&affected_registers);
    OutSet registers_to_pop;
    OutSet registers_to_clear;
@@ -1535,12 +1542,6 @@
                           affected_registers,
                           &registers_to_pop,
                           &registers_to_clear);
-  if (backtrack() != NULL) {
-    // Here we have a concrete backtrack location.  These are set up by  
choice
-    // nodes and so they indicate that we have a deferred save of the  
current
-    // position which we may need to emit here.
-    assembler->PushCurrentPosition();
-  }
    if (cp_offset_ != 0) {
      assembler->AdvanceCurrentPosition(cp_offset_);
    }
@@ -1553,9 +1554,6 @@

    // On backtrack we need to restore state.
    assembler->Bind(&undo);
-  if (backtrack() != NULL) {
-    assembler->PopCurrentPosition();
-  }
    RestoreAffectedRegisters(assembler,
                             max_register,
                             registers_to_pop,
@@ -1563,6 +1561,7 @@
    if (backtrack() == NULL) {
      assembler->Backtrack();
    } else {
+    assembler->PopCurrentPosition();
      assembler->GoTo(backtrack());
    }
  }
@@ -3053,10 +3052,6 @@
      }
    }
    ~AlternativeGenerationList() {
-    for (int i = 0; i < alt_gens_.length(); i++) {
-      alt_gens_[i]->possible_success.Unuse();
-      alt_gens_[i]->after.Unuse();
-    }
      for (int i = kAFew; i < alt_gens_.length(); i++) {
        delete alt_gens_[i];
        alt_gens_[i] = NULL;
@@ -3170,6 +3165,12 @@
    if (limit_result == DONE) return;
    ASSERT(limit_result == CONTINUE);

+  int new_flush_budget = trace->flush_budget() / choice_count;
+  if (trace->flush_budget() == 0 && trace->actions() != NULL) {
+    trace->Flush(compiler, this);
+    return;
+  }
+
    RecursionCheck rc(compiler);

    Trace* current_trace = trace;
@@ -3278,6 +3279,9 @@
        generate_full_check_inline = true;
      }
      if (generate_full_check_inline) {
+      if (new_trace.actions() != NULL) {
+        new_trace.set_flush_budget(new_flush_budget);
+      }
        for (int j = 0; j < guard_count; j++) {
          GenerateGuard(macro_assembler, guards->at(j), &new_trace);
        }
@@ -3294,13 +3298,21 @@
      macro_assembler->AdvanceCurrentPosition(-text_length);
      macro_assembler->GoTo(&second_choice);
    }
+
    // At this point we need to generate slow checks for the alternatives  
where
    // the quick check was inlined.  We can recognize these because the  
associated
    // label was bound.
    for (int i = first_normal_choice; i < choice_count - 1; i++) {
      AlternativeGeneration* alt_gen = alt_gens.at(i);
+    Trace new_trace(*current_trace);
+    // If there are actions to be flushed we have to limit how many times
+    // they are flushed.  Take the budget of the parent trace and  
distribute
+    // it fairly amongst the children.
+    if (new_trace.actions() != NULL) {
+      new_trace.set_flush_budget(new_flush_budget);
+    }
      EmitOutOfLineContinuation(compiler,
-                              current_trace,
+                              &new_trace,
                                alternatives_->at(i),
                                alt_gen,
                                preload_characters,

Modified: branches/bleeding_edge/src/jsregexp.h
==============================================================================
--- branches/bleeding_edge/src/jsregexp.h       (original)
+++ branches/bleeding_edge/src/jsregexp.h       Thu Feb 19 00:24:28 2009
@@ -1180,6 +1180,7 @@
          loop_label_(NULL),
          characters_preloaded_(0),
          bound_checked_up_to_(0),
+        flush_budget_(100),
          at_start_(UNKNOWN) { }

    // End the trace.  This involves flushing the deferred actions in the  
trace
@@ -1215,6 +1216,7 @@
    RegExpNode* stop_node() { return stop_node_; }
    int characters_preloaded() { return characters_preloaded_; }
    int bound_checked_up_to() { return bound_checked_up_to_; }
+  int flush_budget() { return flush_budget_; }
    QuickCheckDetails* quick_check_performed() { return  
&quick_check_performed_; }
    bool mentions_reg(int reg);
    // Returns true if a deferred position store exists to the specified
@@ -1233,6 +1235,7 @@
    void set_loop_label(Label* label) { loop_label_ = label; }
    void set_characters_preloaded(int cpre) { characters_preloaded_ = cpre; }
    void set_bound_checked_up_to(int to) { bound_checked_up_to_ = to; }
+  void set_flush_budget(int to) { flush_budget_ = to; }
    void set_quick_check_performed(QuickCheckDetails* d) {
      quick_check_performed_ = *d;
    }
@@ -1257,6 +1260,7 @@
    int characters_preloaded_;
    int bound_checked_up_to_;
    QuickCheckDetails quick_check_performed_;
+  int flush_budget_;
    TriBool at_start_;
  };


--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to