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

Side by Side Diff: src/jsregexp.cc

Issue 12380026: Limit EatAtLeast recursion by a budget. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 2292
2293 // If we get here code has been generated for this node too many times or 2293 // If we get here code has been generated for this node too many times or
2294 // recursion is too deep. Time to switch to a generic version. The code for 2294 // recursion is too deep. Time to switch to a generic version. The code for
2295 // generic versions above can handle deep recursion properly. 2295 // generic versions above can handle deep recursion properly.
2296 trace->Flush(compiler, this); 2296 trace->Flush(compiler, this);
2297 return DONE; 2297 return DONE;
2298 } 2298 }
2299 2299
2300 2300
2301 int ActionNode::EatsAtLeast(int still_to_find, 2301 int ActionNode::EatsAtLeast(int still_to_find,
2302 int recursion_depth, 2302 int budget,
2303 bool not_at_start) { 2303 bool not_at_start) {
2304 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2304 if (budget <= 0) return 0;
2305 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input! 2305 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input!
2306 return on_success()->EatsAtLeast(still_to_find, 2306 return on_success()->EatsAtLeast(still_to_find,
2307 recursion_depth + 1, 2307 budget - 1,
2308 not_at_start); 2308 not_at_start);
2309 } 2309 }
2310 2310
2311 2311
2312 void ActionNode::FillInBMInfo(int offset, 2312 void ActionNode::FillInBMInfo(int offset,
2313 int recursion_depth,
2314 int budget, 2313 int budget,
2315 BoyerMooreLookahead* bm, 2314 BoyerMooreLookahead* bm,
2316 bool not_at_start) { 2315 bool not_at_start) {
2317 if (type_ == BEGIN_SUBMATCH) { 2316 if (type_ == BEGIN_SUBMATCH) {
2318 bm->SetRest(offset); 2317 bm->SetRest(offset);
2319 } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) { 2318 } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
2320 on_success()->FillInBMInfo( 2319 on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
2321 offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2322 } 2320 }
2323 SaveBMInfo(bm, not_at_start, offset); 2321 SaveBMInfo(bm, not_at_start, offset);
2324 } 2322 }
2325 2323
2326 2324
2327 int AssertionNode::EatsAtLeast(int still_to_find, 2325 int AssertionNode::EatsAtLeast(int still_to_find,
2328 int recursion_depth, 2326 int budget,
2329 bool not_at_start) { 2327 bool not_at_start) {
2330 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2328 if (budget <= 0) return 0;
2331 // If we know we are not at the start and we are asked "how many characters 2329 // If we know we are not at the start and we are asked "how many characters
2332 // will you match if you succeed?" then we can answer anything since false 2330 // will you match if you succeed?" then we can answer anything since false
2333 // implies false. So lets just return the max answer (still_to_find) since 2331 // implies false. So lets just return the max answer (still_to_find) since
2334 // that won't prevent us from preloading a lot of characters for the other 2332 // that won't prevent us from preloading a lot of characters for the other
2335 // branches in the node graph. 2333 // branches in the node graph.
2336 if (type() == AT_START && not_at_start) return still_to_find; 2334 if (type() == AT_START && not_at_start) return still_to_find;
2337 return on_success()->EatsAtLeast(still_to_find, 2335 return on_success()->EatsAtLeast(still_to_find,
2338 recursion_depth + 1, 2336 budget - 1,
2339 not_at_start); 2337 not_at_start);
2340 } 2338 }
2341 2339
2342 2340
2343 void AssertionNode::FillInBMInfo(int offset, 2341 void AssertionNode::FillInBMInfo(int offset,
2344 int recursion_depth,
2345 int budget, 2342 int budget,
2346 BoyerMooreLookahead* bm, 2343 BoyerMooreLookahead* bm,
2347 bool not_at_start) { 2344 bool not_at_start) {
2348 // Match the behaviour of EatsAtLeast on this node. 2345 // Match the behaviour of EatsAtLeast on this node.
2349 if (type() == AT_START && not_at_start) return; 2346 if (type() == AT_START && not_at_start) return;
2350 on_success()->FillInBMInfo( 2347 on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
2351 offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2352 SaveBMInfo(bm, not_at_start, offset); 2348 SaveBMInfo(bm, not_at_start, offset);
2353 } 2349 }
2354 2350
2355 2351
2356 int BackReferenceNode::EatsAtLeast(int still_to_find, 2352 int BackReferenceNode::EatsAtLeast(int still_to_find,
2357 int recursion_depth, 2353 int budget,
2358 bool not_at_start) { 2354 bool not_at_start) {
2359 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2355 if (budget <= 0) return 0;
2360 return on_success()->EatsAtLeast(still_to_find, 2356 return on_success()->EatsAtLeast(still_to_find,
2361 recursion_depth + 1, 2357 budget - 1,
2362 not_at_start); 2358 not_at_start);
2363 } 2359 }
2364 2360
2365 2361
2366 int TextNode::EatsAtLeast(int still_to_find, 2362 int TextNode::EatsAtLeast(int still_to_find,
2367 int recursion_depth, 2363 int budget,
2368 bool not_at_start) { 2364 bool not_at_start) {
2369 int answer = Length(); 2365 int answer = Length();
2370 if (answer >= still_to_find) return answer; 2366 if (answer >= still_to_find) return answer;
2371 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer; 2367 if (budget <= 0) return answer;
2372 // We are not at start after this node so we set the last argument to 'true'. 2368 // We are not at start after this node so we set the last argument to 'true'.
2373 return answer + on_success()->EatsAtLeast(still_to_find - answer, 2369 return answer + on_success()->EatsAtLeast(still_to_find - answer,
2374 recursion_depth + 1, 2370 budget - 1,
2375 true); 2371 true);
2376 } 2372 }
2377 2373
2378 2374
2379 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find, 2375 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find,
2380 int recursion_depth, 2376 int budget,
2381 bool not_at_start) { 2377 bool not_at_start) {
2382 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2378 if (budget <= 0) return 0;
2383 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2379 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2384 // afterwards. 2380 // afterwards.
2385 RegExpNode* node = alternatives_->at(1).node(); 2381 RegExpNode* node = alternatives_->at(1).node();
2386 return node->EatsAtLeast(still_to_find, recursion_depth + 1, not_at_start); 2382 return node->EatsAtLeast(still_to_find, budget - 1, not_at_start);
2387 } 2383 }
2388 2384
2389 2385
2390 void NegativeLookaheadChoiceNode::GetQuickCheckDetails( 2386 void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
2391 QuickCheckDetails* details, 2387 QuickCheckDetails* details,
2392 RegExpCompiler* compiler, 2388 RegExpCompiler* compiler,
2393 int filled_in, 2389 int filled_in,
2394 bool not_at_start) { 2390 bool not_at_start) {
2395 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2391 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2396 // afterwards. 2392 // afterwards.
2397 RegExpNode* node = alternatives_->at(1).node(); 2393 RegExpNode* node = alternatives_->at(1).node();
2398 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start); 2394 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start);
2399 } 2395 }
2400 2396
2401 2397
2402 int ChoiceNode::EatsAtLeastHelper(int still_to_find, 2398 int ChoiceNode::EatsAtLeastHelper(int still_to_find,
2403 int recursion_depth, 2399 int budget,
2404 RegExpNode* ignore_this_node, 2400 RegExpNode* ignore_this_node,
2405 bool not_at_start) { 2401 bool not_at_start) {
2406 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2402 if (budget <= 0) return 0;
2407 int min = 100; 2403 int min = 100;
2408 int choice_count = alternatives_->length(); 2404 int choice_count = alternatives_->length();
2405 budget = (budget - 1) / choice_count;
2409 for (int i = 0; i < choice_count; i++) { 2406 for (int i = 0; i < choice_count; i++) {
2410 RegExpNode* node = alternatives_->at(i).node(); 2407 RegExpNode* node = alternatives_->at(i).node();
2411 if (node == ignore_this_node) continue; 2408 if (node == ignore_this_node) continue;
2412 int node_eats_at_least = node->EatsAtLeast(still_to_find, 2409 int node_eats_at_least =
2413 recursion_depth + 1, 2410 node->EatsAtLeast(still_to_find, budget, not_at_start);
2414 not_at_start);
2415 if (node_eats_at_least < min) min = node_eats_at_least; 2411 if (node_eats_at_least < min) min = node_eats_at_least;
2412 if (min == 0) return 0;
2416 } 2413 }
2417 return min; 2414 return min;
2418 } 2415 }
2419 2416
2420 2417
2421 int LoopChoiceNode::EatsAtLeast(int still_to_find, 2418 int LoopChoiceNode::EatsAtLeast(int still_to_find,
2422 int recursion_depth, 2419 int budget,
2423 bool not_at_start) { 2420 bool not_at_start) {
2424 return EatsAtLeastHelper(still_to_find, 2421 return EatsAtLeastHelper(still_to_find,
2425 recursion_depth, 2422 budget - 1,
2426 loop_node_, 2423 loop_node_,
2427 not_at_start); 2424 not_at_start);
2428 } 2425 }
2429 2426
2430 2427
2431 int ChoiceNode::EatsAtLeast(int still_to_find, 2428 int ChoiceNode::EatsAtLeast(int still_to_find,
2432 int recursion_depth, 2429 int budget,
2433 bool not_at_start) { 2430 bool not_at_start) {
2434 return EatsAtLeastHelper(still_to_find, 2431 return EatsAtLeastHelper(still_to_find,
2435 recursion_depth, 2432 budget,
2436 NULL, 2433 NULL,
2437 not_at_start); 2434 not_at_start);
2438 } 2435 }
2439 2436
2440 2437
2441 // Takes the left-most 1-bit and smears it out, setting all bits to its right. 2438 // Takes the left-most 1-bit and smears it out, setting all bits to its right.
2442 static inline uint32_t SmearBitsRight(uint32_t v) { 2439 static inline uint32_t SmearBitsRight(uint32_t v) {
2443 v |= v >> 1; 2440 v |= v >> 1;
2444 v |= v >> 2; 2441 v |= v >> 2;
2445 v |= v >> 4; 2442 v |= v >> 4;
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
2981 if (body_can_be_zero_length_ || info()->visited) return; 2978 if (body_can_be_zero_length_ || info()->visited) return;
2982 VisitMarker marker(info()); 2979 VisitMarker marker(info());
2983 return ChoiceNode::GetQuickCheckDetails(details, 2980 return ChoiceNode::GetQuickCheckDetails(details,
2984 compiler, 2981 compiler,
2985 characters_filled_in, 2982 characters_filled_in,
2986 not_at_start); 2983 not_at_start);
2987 } 2984 }
2988 2985
2989 2986
2990 void LoopChoiceNode::FillInBMInfo(int offset, 2987 void LoopChoiceNode::FillInBMInfo(int offset,
2991 int recursion_depth,
2992 int budget, 2988 int budget,
2993 BoyerMooreLookahead* bm, 2989 BoyerMooreLookahead* bm,
2994 bool not_at_start) { 2990 bool not_at_start) {
2995 if (body_can_be_zero_length_ || 2991 if (body_can_be_zero_length_ || budget <= 0) {
2996 recursion_depth > RegExpCompiler::kMaxRecursion ||
2997 budget <= 0) {
2998 bm->SetRest(offset); 2992 bm->SetRest(offset);
2999 SaveBMInfo(bm, not_at_start, offset); 2993 SaveBMInfo(bm, not_at_start, offset);
3000 return; 2994 return;
3001 } 2995 }
3002 ChoiceNode::FillInBMInfo( 2996 ChoiceNode::FillInBMInfo(offset, budget - 1, bm, not_at_start);
3003 offset, recursion_depth + 1, budget - 1, bm, not_at_start);
3004 SaveBMInfo(bm, not_at_start, offset); 2997 SaveBMInfo(bm, not_at_start, offset);
3005 } 2998 }
3006 2999
3007 3000
3008 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, 3001 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
3009 RegExpCompiler* compiler, 3002 RegExpCompiler* compiler,
3010 int characters_filled_in, 3003 int characters_filled_in,
3011 bool not_at_start) { 3004 bool not_at_start) {
3012 not_at_start = (not_at_start || not_at_start_); 3005 not_at_start = (not_at_start || not_at_start_);
3013 int choice_count = alternatives_->length(); 3006 int choice_count = alternatives_->length();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 3083
3091 3084
3092 // Emit the code to handle \b and \B (word-boundary or non-word-boundary). 3085 // Emit the code to handle \b and \B (word-boundary or non-word-boundary).
3093 void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { 3086 void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
3094 RegExpMacroAssembler* assembler = compiler->macro_assembler(); 3087 RegExpMacroAssembler* assembler = compiler->macro_assembler();
3095 Trace::TriBool next_is_word_character = Trace::UNKNOWN; 3088 Trace::TriBool next_is_word_character = Trace::UNKNOWN;
3096 bool not_at_start = (trace->at_start() == Trace::FALSE); 3089 bool not_at_start = (trace->at_start() == Trace::FALSE);
3097 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 3090 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
3098 if (lookahead == NULL) { 3091 if (lookahead == NULL) {
3099 int eats_at_least = 3092 int eats_at_least =
3100 Min(kMaxLookaheadForBoyerMoore, 3093 Min(kMaxLookaheadForBoyerMoore, EatsAtLeast(kMaxLookaheadForBoyerMoore,
3101 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 3094 kFillInBMBudget,
3095 not_at_start));
3102 if (eats_at_least >= 1) { 3096 if (eats_at_least >= 1) {
3103 BoyerMooreLookahead* bm = 3097 BoyerMooreLookahead* bm =
3104 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); 3098 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone());
3105 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 3099 FillInBMInfo(0, kFillInBMBudget, bm, not_at_start);
3106 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 3100 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
3107 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; 3101 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
3108 } 3102 }
3109 } else { 3103 } else {
3110 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 3104 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
3111 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; 3105 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE;
3112 } 3106 }
3113 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); 3107 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY);
3114 if (next_is_word_character == Trace::UNKNOWN) { 3108 if (next_is_word_character == Trace::UNKNOWN) {
3115 Label before_non_word; 3109 Label before_non_word;
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after
4027 // At this point we know that we are at a non-greedy loop that will eat 4021 // At this point we know that we are at a non-greedy loop that will eat
4028 // any character one at a time. Any non-anchored regexp has such a 4022 // any character one at a time. Any non-anchored regexp has such a
4029 // loop prepended to it in order to find where it starts. We look for 4023 // loop prepended to it in order to find where it starts. We look for
4030 // a pattern of the form ...abc... where we can look 6 characters ahead 4024 // a pattern of the form ...abc... where we can look 6 characters ahead
4031 // and step forwards 3 if the character is not one of abc. Abc need 4025 // and step forwards 3 if the character is not one of abc. Abc need
4032 // not be atoms, they can be any reasonably limited character class or 4026 // not be atoms, they can be any reasonably limited character class or
4033 // small alternation. 4027 // small alternation.
4034 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. 4028 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes.
4035 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 4029 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
4036 if (lookahead == NULL) { 4030 if (lookahead == NULL) {
4037 eats_at_least = 4031 eats_at_least = Min(kMaxLookaheadForBoyerMoore,
4038 Min(kMaxLookaheadForBoyerMoore, 4032 EatsAtLeast(kMaxLookaheadForBoyerMoore,
4039 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 4033 kFillInBMBudget,
4034 not_at_start));
4040 if (eats_at_least >= 1) { 4035 if (eats_at_least >= 1) {
4041 BoyerMooreLookahead* bm = 4036 BoyerMooreLookahead* bm =
4042 new(zone()) BoyerMooreLookahead(eats_at_least, 4037 new(zone()) BoyerMooreLookahead(eats_at_least,
4043 compiler, 4038 compiler,
4044 zone()); 4039 zone());
4045 GuardedAlternative alt0 = alternatives_->at(0); 4040 GuardedAlternative alt0 = alternatives_->at(0);
4046 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 4041 alt0.node()->FillInBMInfo(0, kFillInBMBudget, bm, not_at_start);
4047 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); 4042 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
4048 } 4043 }
4049 } else { 4044 } else {
4050 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); 4045 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler);
4051 } 4046 }
4052 } 4047 }
4053 } 4048 }
4054 } 4049 }
4055 4050
4056 if (eats_at_least == kEatsAtLeastNotYetInitialized) { 4051 if (eats_at_least == kEatsAtLeastNotYetInitialized) {
4057 // Save some time by looking at most one machine word ahead. 4052 // Save some time by looking at most one machine word ahead.
4058 eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start); 4053 eats_at_least =
4054 EatsAtLeast(compiler->ascii() ? 4 : 2, kFillInBMBudget, not_at_start);
4059 } 4055 }
4060 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least); 4056 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least);
4061 4057
4062 bool preload_is_current = !skip_was_emitted && 4058 bool preload_is_current = !skip_was_emitted &&
4063 (current_trace->characters_preloaded() == preload_characters); 4059 (current_trace->characters_preloaded() == preload_characters);
4064 bool preload_has_checked_bounds = preload_is_current; 4060 bool preload_has_checked_bounds = preload_is_current;
4065 4061
4066 AlternativeGenerationList alt_gens(choice_count, zone()); 4062 AlternativeGenerationList alt_gens(choice_count, zone());
4067 4063
4068 // For now we just call all choices one after the other. The idea ultimately 4064 // For now we just call all choices one after the other. The idea ultimately
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after
5804 EnsureAnalyzed(that->on_success()); 5800 EnsureAnalyzed(that->on_success());
5805 } 5801 }
5806 5802
5807 5803
5808 void Analysis::VisitAssertion(AssertionNode* that) { 5804 void Analysis::VisitAssertion(AssertionNode* that) {
5809 EnsureAnalyzed(that->on_success()); 5805 EnsureAnalyzed(that->on_success());
5810 } 5806 }
5811 5807
5812 5808
5813 void BackReferenceNode::FillInBMInfo(int offset, 5809 void BackReferenceNode::FillInBMInfo(int offset,
5814 int recursion_depth,
5815 int budget, 5810 int budget,
5816 BoyerMooreLookahead* bm, 5811 BoyerMooreLookahead* bm,
5817 bool not_at_start) { 5812 bool not_at_start) {
5818 // Working out the set of characters that a backreference can match is too 5813 // Working out the set of characters that a backreference can match is too
5819 // hard, so we just say that any character can match. 5814 // hard, so we just say that any character can match.
5820 bm->SetRest(offset); 5815 bm->SetRest(offset);
5821 SaveBMInfo(bm, not_at_start, offset); 5816 SaveBMInfo(bm, not_at_start, offset);
5822 } 5817 }
5823 5818
5824 5819
5825 STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize == 5820 STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
5826 RegExpMacroAssembler::kTableSize); 5821 RegExpMacroAssembler::kTableSize);
5827 5822
5828 5823
5829 void ChoiceNode::FillInBMInfo(int offset, 5824 void ChoiceNode::FillInBMInfo(int offset,
5830 int recursion_depth,
5831 int budget, 5825 int budget,
5832 BoyerMooreLookahead* bm, 5826 BoyerMooreLookahead* bm,
5833 bool not_at_start) { 5827 bool not_at_start) {
5834 ZoneList<GuardedAlternative>* alts = alternatives(); 5828 ZoneList<GuardedAlternative>* alts = alternatives();
5835 budget = (budget - 1) / alts->length(); 5829 budget = (budget - 1) / alts->length();
5836 for (int i = 0; i < alts->length(); i++) { 5830 for (int i = 0; i < alts->length(); i++) {
5837 GuardedAlternative& alt = alts->at(i); 5831 GuardedAlternative& alt = alts->at(i);
5838 if (alt.guards() != NULL && alt.guards()->length() != 0) { 5832 if (alt.guards() != NULL && alt.guards()->length() != 0) {
5839 bm->SetRest(offset); // Give up trying to fill in info. 5833 bm->SetRest(offset); // Give up trying to fill in info.
5840 SaveBMInfo(bm, not_at_start, offset); 5834 SaveBMInfo(bm, not_at_start, offset);
5841 return; 5835 return;
5842 } 5836 }
5843 alt.node()->FillInBMInfo( 5837 alt.node()->FillInBMInfo(offset, budget, bm, not_at_start);
5844 offset, recursion_depth + 1, budget, bm, not_at_start);
5845 } 5838 }
5846 SaveBMInfo(bm, not_at_start, offset); 5839 SaveBMInfo(bm, not_at_start, offset);
5847 } 5840 }
5848 5841
5849 5842
5850 void TextNode::FillInBMInfo(int initial_offset, 5843 void TextNode::FillInBMInfo(int initial_offset,
5851 int recursion_depth,
5852 int budget, 5844 int budget,
5853 BoyerMooreLookahead* bm, 5845 BoyerMooreLookahead* bm,
5854 bool not_at_start) { 5846 bool not_at_start) {
5855 if (initial_offset >= bm->length()) return; 5847 if (initial_offset >= bm->length()) return;
5856 int offset = initial_offset; 5848 int offset = initial_offset;
5857 int max_char = bm->max_char(); 5849 int max_char = bm->max_char();
5858 for (int i = 0; i < elements()->length(); i++) { 5850 for (int i = 0; i < elements()->length(); i++) {
5859 if (offset >= bm->length()) { 5851 if (offset >= bm->length()) {
5860 if (initial_offset == 0) set_bm_info(not_at_start, bm); 5852 if (initial_offset == 0) set_bm_info(not_at_start, bm);
5861 return; 5853 return;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5898 } 5890 }
5899 } 5891 }
5900 offset++; 5892 offset++;
5901 } 5893 }
5902 } 5894 }
5903 if (offset >= bm->length()) { 5895 if (offset >= bm->length()) {
5904 if (initial_offset == 0) set_bm_info(not_at_start, bm); 5896 if (initial_offset == 0) set_bm_info(not_at_start, bm);
5905 return; 5897 return;
5906 } 5898 }
5907 on_success()->FillInBMInfo(offset, 5899 on_success()->FillInBMInfo(offset,
5908 recursion_depth + 1,
5909 budget - 1, 5900 budget - 1,
5910 bm, 5901 bm,
5911 true); // Not at start after a text node. 5902 true); // Not at start after a text node.
5912 if (initial_offset == 0) set_bm_info(not_at_start, bm); 5903 if (initial_offset == 0) set_bm_info(not_at_start, bm);
5913 } 5904 }
5914 5905
5915 5906
5916 // ------------------------------------------------------------------- 5907 // -------------------------------------------------------------------
5917 // Dispatch table construction 5908 // Dispatch table construction
5918 5909
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
6150 } 6141 }
6151 6142
6152 return compiler.Assemble(&macro_assembler, 6143 return compiler.Assemble(&macro_assembler,
6153 node, 6144 node,
6154 data->capture_count, 6145 data->capture_count,
6155 pattern); 6146 pattern);
6156 } 6147 }
6157 6148
6158 6149
6159 }} // namespace v8::internal 6150 }} // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698