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,
®isters_to_pop,
®isters_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
-~----------~----~----~----~------~----~------~--~---