Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(746)

Side by Side Diff: src/jsregexp.cc

Issue 20457: Limit how many places we generate code to flush the same actions. This gives... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/jsregexp.h ('K') | « src/jsregexp.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 if (cp_offset_ != 0) assembler->AdvanceCurrentPosition(cp_offset_); 1520 if (cp_offset_ != 0) assembler->AdvanceCurrentPosition(cp_offset_);
1521 // Create a new trivial state and generate the node with that. 1521 // Create a new trivial state and generate the node with that.
1522 Trace new_state; 1522 Trace new_state;
1523 successor->Emit(compiler, &new_state); 1523 successor->Emit(compiler, &new_state);
1524 return; 1524 return;
1525 } 1525 }
1526 1526
1527 // Generate deferred actions here along with code to undo them again. 1527 // Generate deferred actions here along with code to undo them again.
1528 OutSet affected_registers; 1528 OutSet affected_registers;
1529 1529
1530 if (backtrack() != NULL) {
1531 // Here we have a concrete backtrack location. These are set up by choice
1532 // nodes and so they indicate that we have a deferred save of the current
1533 // position which we may need to emit here.
1534 assembler->PushCurrentPosition();
1535 }
1536
1530 int max_register = FindAffectedRegisters(&affected_registers); 1537 int max_register = FindAffectedRegisters(&affected_registers);
1531 OutSet registers_to_pop; 1538 OutSet registers_to_pop;
1532 OutSet registers_to_clear; 1539 OutSet registers_to_clear;
1533 PerformDeferredActions(assembler, 1540 PerformDeferredActions(assembler,
1534 max_register, 1541 max_register,
1535 affected_registers, 1542 affected_registers,
1536 &registers_to_pop, 1543 &registers_to_pop,
1537 &registers_to_clear); 1544 &registers_to_clear);
1538 if (backtrack() != NULL) {
1539 // Here we have a concrete backtrack location. These are set up by choice
1540 // nodes and so they indicate that we have a deferred save of the current
1541 // position which we may need to emit here.
1542 assembler->PushCurrentPosition();
1543 }
1544 if (cp_offset_ != 0) { 1545 if (cp_offset_ != 0) {
1545 assembler->AdvanceCurrentPosition(cp_offset_); 1546 assembler->AdvanceCurrentPosition(cp_offset_);
1546 } 1547 }
1547 1548
1548 // Create a new trivial state and generate the node with that. 1549 // Create a new trivial state and generate the node with that.
1549 Label undo; 1550 Label undo;
1550 assembler->PushBacktrack(&undo); 1551 assembler->PushBacktrack(&undo);
1551 Trace new_state; 1552 Trace new_state;
1552 successor->Emit(compiler, &new_state); 1553 successor->Emit(compiler, &new_state);
1553 1554
1554 // On backtrack we need to restore state. 1555 // On backtrack we need to restore state.
1555 assembler->Bind(&undo); 1556 assembler->Bind(&undo);
1556 if (backtrack() != NULL) {
1557 assembler->PopCurrentPosition();
1558 }
1559 RestoreAffectedRegisters(assembler, 1557 RestoreAffectedRegisters(assembler,
1560 max_register, 1558 max_register,
1561 registers_to_pop, 1559 registers_to_pop,
1562 registers_to_clear); 1560 registers_to_clear);
1563 if (backtrack() == NULL) { 1561 if (backtrack() == NULL) {
1564 assembler->Backtrack(); 1562 assembler->Backtrack();
1565 } else { 1563 } else {
1564 assembler->PopCurrentPosition();
1566 assembler->GoTo(backtrack()); 1565 assembler->GoTo(backtrack());
1567 } 1566 }
1568 } 1567 }
1569 1568
1570 1569
1571 void NegativeSubmatchSuccess::Emit(RegExpCompiler* compiler, Trace* trace) { 1570 void NegativeSubmatchSuccess::Emit(RegExpCompiler* compiler, Trace* trace) {
1572 RegExpMacroAssembler* assembler = compiler->macro_assembler(); 1571 RegExpMacroAssembler* assembler = compiler->macro_assembler();
1573 1572
1574 // Omit flushing the trace. We discard the entire stack frame anyway. 1573 // Omit flushing the trace. We discard the entire stack frame anyway.
1575 1574
(...skipping 1415 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 explicit AlternativeGenerationList(int count) 2990 explicit AlternativeGenerationList(int count)
2992 : alt_gens_(count) { 2991 : alt_gens_(count) {
2993 for (int i = 0; i < count && i < kAFew; i++) { 2992 for (int i = 0; i < count && i < kAFew; i++) {
2994 alt_gens_.Add(a_few_alt_gens_ + i); 2993 alt_gens_.Add(a_few_alt_gens_ + i);
2995 } 2994 }
2996 for (int i = kAFew; i < count; i++) { 2995 for (int i = kAFew; i < count; i++) {
2997 alt_gens_.Add(new AlternativeGeneration()); 2996 alt_gens_.Add(new AlternativeGeneration());
2998 } 2997 }
2999 } 2998 }
3000 ~AlternativeGenerationList() { 2999 ~AlternativeGenerationList() {
3001 for (int i = 0; i < alt_gens_.length(); i++) {
3002 alt_gens_[i]->possible_success.Unuse();
3003 alt_gens_[i]->after.Unuse();
3004 }
3005 for (int i = kAFew; i < alt_gens_.length(); i++) { 3000 for (int i = kAFew; i < alt_gens_.length(); i++) {
3006 delete alt_gens_[i]; 3001 delete alt_gens_[i];
3007 alt_gens_[i] = NULL; 3002 alt_gens_[i] = NULL;
3008 } 3003 }
3009 } 3004 }
3010 3005
3011 AlternativeGeneration* at(int i) { 3006 AlternativeGeneration* at(int i) {
3012 return alt_gens_[i]; 3007 return alt_gens_[i];
3013 } 3008 }
3014 private: 3009 private:
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3108 for (int j = 0; j < guard_count; j++) { 3103 for (int j = 0; j < guard_count; j++) {
3109 ASSERT(!trace->mentions_reg(guards->at(j)->reg())); 3104 ASSERT(!trace->mentions_reg(guards->at(j)->reg()));
3110 } 3105 }
3111 } 3106 }
3112 #endif 3107 #endif
3113 3108
3114 LimitResult limit_result = LimitVersions(compiler, trace); 3109 LimitResult limit_result = LimitVersions(compiler, trace);
3115 if (limit_result == DONE) return; 3110 if (limit_result == DONE) return;
3116 ASSERT(limit_result == CONTINUE); 3111 ASSERT(limit_result == CONTINUE);
3117 3112
3113 int new_flush_budget = trace->flush_budget() / choice_count;
3114 if (trace->flush_budget() == 0 && trace->actions() != NULL) {
3115 trace->Flush(compiler, this);
3116 return;
3117 }
3118
3118 RecursionCheck rc(compiler); 3119 RecursionCheck rc(compiler);
3119 3120
3120 Trace* current_trace = trace; 3121 Trace* current_trace = trace;
3121 3122
3122 int text_length = GreedyLoopTextLength(&(alternatives_->at(0))); 3123 int text_length = GreedyLoopTextLength(&(alternatives_->at(0)));
3123 bool greedy_loop = false; 3124 bool greedy_loop = false;
3124 Label greedy_loop_label; 3125 Label greedy_loop_label;
3125 Trace counter_backtrack_trace; 3126 Trace counter_backtrack_trace;
3126 counter_backtrack_trace.set_backtrack(&greedy_loop_label); 3127 counter_backtrack_trace.set_backtrack(&greedy_loop_label);
3127 if (not_at_start()) counter_backtrack_trace.set_at_start(false); 3128 if (not_at_start()) counter_backtrack_trace.set_at_start(false);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3216 if (i != first_normal_choice) { 3217 if (i != first_normal_choice) {
3217 alt_gen->expects_preload = false; 3218 alt_gen->expects_preload = false;
3218 new_trace.set_characters_preloaded(0); 3219 new_trace.set_characters_preloaded(0);
3219 } 3220 }
3220 if (i < choice_count - 1) { 3221 if (i < choice_count - 1) {
3221 new_trace.set_backtrack(&alt_gen->after); 3222 new_trace.set_backtrack(&alt_gen->after);
3222 } 3223 }
3223 generate_full_check_inline = true; 3224 generate_full_check_inline = true;
3224 } 3225 }
3225 if (generate_full_check_inline) { 3226 if (generate_full_check_inline) {
3227 if (new_trace.actions() != NULL) {
3228 new_trace.set_flush_budget(new_flush_budget);
3229 }
3226 for (int j = 0; j < guard_count; j++) { 3230 for (int j = 0; j < guard_count; j++) {
3227 GenerateGuard(macro_assembler, guards->at(j), &new_trace); 3231 GenerateGuard(macro_assembler, guards->at(j), &new_trace);
3228 } 3232 }
3229 alternative.node()->Emit(compiler, &new_trace); 3233 alternative.node()->Emit(compiler, &new_trace);
3230 preload_is_current = false; 3234 preload_is_current = false;
3231 } 3235 }
3232 macro_assembler->Bind(&alt_gen->after); 3236 macro_assembler->Bind(&alt_gen->after);
3233 } 3237 }
3234 if (greedy_loop) { 3238 if (greedy_loop) {
3235 macro_assembler->Bind(&greedy_loop_label); 3239 macro_assembler->Bind(&greedy_loop_label);
3236 // If we have unwound to the bottom then backtrack. 3240 // If we have unwound to the bottom then backtrack.
3237 macro_assembler->CheckGreedyLoop(trace->backtrack()); 3241 macro_assembler->CheckGreedyLoop(trace->backtrack());
3238 // Otherwise try the second priority at an earlier position. 3242 // Otherwise try the second priority at an earlier position.
3239 macro_assembler->AdvanceCurrentPosition(-text_length); 3243 macro_assembler->AdvanceCurrentPosition(-text_length);
3240 macro_assembler->GoTo(&second_choice); 3244 macro_assembler->GoTo(&second_choice);
3241 } 3245 }
3246
3242 // At this point we need to generate slow checks for the alternatives where 3247 // At this point we need to generate slow checks for the alternatives where
3243 // the quick check was inlined. We can recognize these because the associated 3248 // the quick check was inlined. We can recognize these because the associated
3244 // label was bound. 3249 // label was bound.
3245 for (int i = first_normal_choice; i < choice_count - 1; i++) { 3250 for (int i = first_normal_choice; i < choice_count - 1; i++) {
3246 AlternativeGeneration* alt_gen = alt_gens.at(i); 3251 AlternativeGeneration* alt_gen = alt_gens.at(i);
3252 Trace new_trace(*current_trace);
3253 // If there are actions to be flushed we have to limit how many times
3254 // they are flushed. Take the budget of the parent trace and distribute
3255 // it fairly amongst the children.
3256 if (new_trace.actions() != NULL) {
3257 new_trace.set_flush_budget(new_flush_budget);
3258 }
3247 EmitOutOfLineContinuation(compiler, 3259 EmitOutOfLineContinuation(compiler,
3248 current_trace, 3260 &new_trace,
3249 alternatives_->at(i), 3261 alternatives_->at(i),
3250 alt_gen, 3262 alt_gen,
3251 preload_characters, 3263 preload_characters,
3252 alt_gens.at(i + 1)->expects_preload); 3264 alt_gens.at(i + 1)->expects_preload);
3253 } 3265 }
3254 } 3266 }
3255 3267
3256 3268
3257 void ChoiceNode::EmitOutOfLineContinuation(RegExpCompiler* compiler, 3269 void ChoiceNode::EmitOutOfLineContinuation(RegExpCompiler* compiler,
3258 Trace* trace, 3270 Trace* trace,
(...skipping 1625 matching lines...) Expand 10 before | Expand all | Expand 10 after
4884 EmbeddedVector<byte, 1024> codes; 4896 EmbeddedVector<byte, 1024> codes;
4885 RegExpMacroAssemblerIrregexp macro_assembler(codes); 4897 RegExpMacroAssemblerIrregexp macro_assembler(codes);
4886 return compiler.Assemble(&macro_assembler, 4898 return compiler.Assemble(&macro_assembler,
4887 node, 4899 node,
4888 data->capture_count, 4900 data->capture_count,
4889 pattern); 4901 pattern);
4890 } 4902 }
4891 4903
4892 4904
4893 }} // namespace v8::internal 4905 }} // namespace v8::internal
OLDNEW
« src/jsregexp.h ('K') | « src/jsregexp.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698