Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/ast.h" | 7 #include "src/ast.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 3428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3439 } | 3439 } |
| 3440 length += node_length; | 3440 length += node_length; |
| 3441 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node); | 3441 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node); |
| 3442 node = seq_node->on_success(); | 3442 node = seq_node->on_success(); |
| 3443 } | 3443 } |
| 3444 return length; | 3444 return length; |
| 3445 } | 3445 } |
| 3446 | 3446 |
| 3447 | 3447 |
| 3448 void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) { | 3448 void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) { |
| 3449 DCHECK_EQ(loop_node_, NULL); | 3449 DCHECK(!loop_node_); |
| 3450 AddAlternative(alt); | 3450 AddAlternative(alt); |
| 3451 loop_node_ = alt.node(); | 3451 loop_node_ = alt.node(); |
| 3452 } | 3452 } |
| 3453 | 3453 |
| 3454 | 3454 |
| 3455 void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) { | 3455 void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) { |
| 3456 DCHECK_EQ(continue_node_, NULL); | 3456 DCHECK(!continue_node_); |
| 3457 AddAlternative(alt); | 3457 AddAlternative(alt); |
| 3458 continue_node_ = alt.node(); | 3458 continue_node_ = alt.node(); |
| 3459 } | 3459 } |
| 3460 | 3460 |
| 3461 | 3461 |
| 3462 void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { | 3462 void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { |
| 3463 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); | 3463 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); |
| 3464 if (trace->stop_node() == this) { | 3464 if (trace->stop_node() == this) { |
| 3465 // Back edge of greedy optimized loop node graph. | 3465 // Back edge of greedy optimized loop node graph. |
| 3466 int text_length = | 3466 int text_length = |
| 3467 GreedyLoopTextLengthForAlternative(&(alternatives_->at(0))); | 3467 GreedyLoopTextLengthForAlternative(&(alternatives_->at(0))); |
| 3468 DCHECK(text_length != kNodeIsTooComplexForGreedyLoops); | 3468 DCHECK(text_length != kNodeIsTooComplexForGreedyLoops); |
| 3469 // Update the counter-based backtracking info on the stack. This is an | 3469 // Update the counter-based backtracking info on the stack. This is an |
| 3470 // optimization for greedy loops (see below). | 3470 // optimization for greedy loops (see below). |
| 3471 DCHECK(trace->cp_offset() == text_length); | 3471 DCHECK(trace->cp_offset() == text_length); |
| 3472 macro_assembler->AdvanceCurrentPosition(text_length); | 3472 macro_assembler->AdvanceCurrentPosition(text_length); |
| 3473 macro_assembler->GoTo(trace->loop_label()); | 3473 macro_assembler->GoTo(trace->loop_label()); |
| 3474 return; | 3474 return; |
| 3475 } | 3475 } |
| 3476 DCHECK(trace->stop_node() == NULL); | 3476 DCHECK(!trace->stop_node()); |
| 3477 if (!trace->is_trivial()) { | 3477 if (!trace->is_trivial()) { |
| 3478 trace->Flush(compiler, this); | 3478 trace->Flush(compiler, this); |
| 3479 return; | 3479 return; |
| 3480 } | 3480 } |
| 3481 ChoiceNode::Emit(compiler, trace); | 3481 ChoiceNode::Emit(compiler, trace); |
| 3482 } | 3482 } |
| 3483 | 3483 |
| 3484 | 3484 |
| 3485 int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler, | 3485 int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler, |
| 3486 int eats_at_least) { | 3486 int eats_at_least) { |
| (...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5287 if (*target == NULL) *target = new(zone_) ZoneList<CharacterRange>(2, zone_); | 5287 if (*target == NULL) *target = new(zone_) ZoneList<CharacterRange>(2, zone_); |
| 5288 (*target)->Add(CharacterRange(entry.from(), entry.to()), zone_); | 5288 (*target)->Add(CharacterRange(entry.from(), entry.to()), zone_); |
| 5289 } | 5289 } |
| 5290 | 5290 |
| 5291 | 5291 |
| 5292 void CharacterRange::Split(ZoneList<CharacterRange>* base, | 5292 void CharacterRange::Split(ZoneList<CharacterRange>* base, |
| 5293 Vector<const int> overlay, | 5293 Vector<const int> overlay, |
| 5294 ZoneList<CharacterRange>** included, | 5294 ZoneList<CharacterRange>** included, |
| 5295 ZoneList<CharacterRange>** excluded, | 5295 ZoneList<CharacterRange>** excluded, |
| 5296 Zone* zone) { | 5296 Zone* zone) { |
| 5297 DCHECK_EQ(NULL, *included); | 5297 DCHECK(!*included); |
| 5298 DCHECK_EQ(NULL, *excluded); | 5298 DCHECK(!*excluded); |
| 5299 DispatchTable table(zone); | 5299 DispatchTable table(zone); |
| 5300 for (int i = 0; i < base->length(); i++) | 5300 for (int i = 0; i < base->length(); i++) |
| 5301 table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone); | 5301 table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone); |
| 5302 for (int i = 0; i < overlay.length(); i += 2) { | 5302 for (int i = 0; i < overlay.length(); i += 2) { |
| 5303 table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1), | 5303 table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1), |
| 5304 CharacterRangeSplitter::kInOverlay, zone); | 5304 CharacterRangeSplitter::kInOverlay, zone); |
| 5305 } | 5305 } |
| 5306 CharacterRangeSplitter callback(included, excluded, zone); | 5306 CharacterRangeSplitter callback(included, excluded, zone); |
| 5307 table.ForEach(&callback); | 5307 table.ForEach(&callback); |
| 5308 } | 5308 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5367 ranges->Add(CharacterRange(range_from, range_to), zone); | 5367 ranges->Add(CharacterRange(range_from, range_to), zone); |
| 5368 } | 5368 } |
| 5369 } | 5369 } |
| 5370 pos = end + 1; | 5370 pos = end + 1; |
| 5371 } | 5371 } |
| 5372 } | 5372 } |
| 5373 } | 5373 } |
| 5374 | 5374 |
| 5375 | 5375 |
| 5376 bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { | 5376 bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { |
| 5377 DCHECK_NOT_NULL(ranges); | 5377 DCHECK(ranges); |
| 5378 int n = ranges->length(); | 5378 int n = ranges->length(); |
| 5379 if (n <= 1) return true; | 5379 if (n <= 1) return true; |
| 5380 int max = ranges->at(0).to(); | 5380 int max = ranges->at(0).to(); |
| 5381 for (int i = 1; i < n; i++) { | 5381 for (int i = 1; i < n; i++) { |
| 5382 CharacterRange next_range = ranges->at(i); | 5382 CharacterRange next_range = ranges->at(i); |
| 5383 if (next_range.from() <= max + 1) return false; | 5383 if (next_range.from() <= max + 1) return false; |
| 5384 max = next_range.to(); | 5384 max = next_range.to(); |
| 5385 } | 5385 } |
| 5386 return true; | 5386 return true; |
| 5387 } | 5387 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5591 | 5591 |
| 5592 const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar; | 5592 const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar; |
| 5593 | 5593 |
| 5594 | 5594 |
| 5595 void DispatchTable::AddRange(CharacterRange full_range, int value, | 5595 void DispatchTable::AddRange(CharacterRange full_range, int value, |
| 5596 Zone* zone) { | 5596 Zone* zone) { |
| 5597 CharacterRange current = full_range; | 5597 CharacterRange current = full_range; |
| 5598 if (tree()->is_empty()) { | 5598 if (tree()->is_empty()) { |
| 5599 // If this is the first range we just insert into the table. | 5599 // If this is the first range we just insert into the table. |
| 5600 ZoneSplayTree<Config>::Locator loc; | 5600 ZoneSplayTree<Config>::Locator loc; |
| 5601 DCHECK_RESULT(tree()->Insert(current.from(), &loc)); | 5601 CHECK(tree()->Insert(current.from(), &loc)); |
|
Sven Panne
2015/01/29 17:07:04
Here and at other places: Shouldn't this be a DCHE
Benedikt Meurer
2015/01/30 05:29:32
DCHECK_RESULT has slightly different semantics. Re
| |
| 5602 loc.set_value(Entry(current.from(), current.to(), | 5602 loc.set_value(Entry(current.from(), current.to(), |
| 5603 empty()->Extend(value, zone))); | 5603 empty()->Extend(value, zone))); |
| 5604 return; | 5604 return; |
| 5605 } | 5605 } |
| 5606 // First see if there is a range to the left of this one that | 5606 // First see if there is a range to the left of this one that |
| 5607 // overlaps. | 5607 // overlaps. |
| 5608 ZoneSplayTree<Config>::Locator loc; | 5608 ZoneSplayTree<Config>::Locator loc; |
| 5609 if (tree()->FindGreatestLessThan(current.from(), &loc)) { | 5609 if (tree()->FindGreatestLessThan(current.from(), &loc)) { |
| 5610 Entry* entry = &loc.value(); | 5610 Entry* entry = &loc.value(); |
| 5611 // If we've found a range that overlaps with this one, and it | 5611 // If we've found a range that overlaps with this one, and it |
| 5612 // starts strictly to the left of this one, we have to fix it | 5612 // starts strictly to the left of this one, we have to fix it |
| 5613 // because the following code only handles ranges that start on | 5613 // because the following code only handles ranges that start on |
| 5614 // or after the start point of the range we're adding. | 5614 // or after the start point of the range we're adding. |
| 5615 if (entry->from() < current.from() && entry->to() >= current.from()) { | 5615 if (entry->from() < current.from() && entry->to() >= current.from()) { |
| 5616 // Snap the overlapping range in half around the start point of | 5616 // Snap the overlapping range in half around the start point of |
| 5617 // the range we're adding. | 5617 // the range we're adding. |
| 5618 CharacterRange left(entry->from(), current.from() - 1); | 5618 CharacterRange left(entry->from(), current.from() - 1); |
| 5619 CharacterRange right(current.from(), entry->to()); | 5619 CharacterRange right(current.from(), entry->to()); |
| 5620 // The left part of the overlapping range doesn't overlap. | 5620 // The left part of the overlapping range doesn't overlap. |
| 5621 // Truncate the whole entry to be just the left part. | 5621 // Truncate the whole entry to be just the left part. |
| 5622 entry->set_to(left.to()); | 5622 entry->set_to(left.to()); |
| 5623 // The right part is the one that overlaps. We add this part | 5623 // The right part is the one that overlaps. We add this part |
| 5624 // to the map and let the next step deal with merging it with | 5624 // to the map and let the next step deal with merging it with |
| 5625 // the range we're adding. | 5625 // the range we're adding. |
| 5626 ZoneSplayTree<Config>::Locator loc; | 5626 ZoneSplayTree<Config>::Locator loc; |
| 5627 DCHECK_RESULT(tree()->Insert(right.from(), &loc)); | 5627 CHECK(tree()->Insert(right.from(), &loc)); |
| 5628 loc.set_value(Entry(right.from(), | 5628 loc.set_value(Entry(right.from(), |
| 5629 right.to(), | 5629 right.to(), |
| 5630 entry->out_set())); | 5630 entry->out_set())); |
| 5631 } | 5631 } |
| 5632 } | 5632 } |
| 5633 while (current.is_valid()) { | 5633 while (current.is_valid()) { |
| 5634 if (tree()->FindLeastGreaterThan(current.from(), &loc) && | 5634 if (tree()->FindLeastGreaterThan(current.from(), &loc) && |
| 5635 (loc.value().from() <= current.to()) && | 5635 (loc.value().from() <= current.to()) && |
| 5636 (loc.value().to() >= current.from())) { | 5636 (loc.value().to() >= current.from())) { |
| 5637 Entry* entry = &loc.value(); | 5637 Entry* entry = &loc.value(); |
| 5638 // We have overlap. If there is space between the start point of | 5638 // We have overlap. If there is space between the start point of |
| 5639 // the range we're adding and where the overlapping range starts | 5639 // the range we're adding and where the overlapping range starts |
| 5640 // then we have to add a range covering just that space. | 5640 // then we have to add a range covering just that space. |
| 5641 if (current.from() < entry->from()) { | 5641 if (current.from() < entry->from()) { |
| 5642 ZoneSplayTree<Config>::Locator ins; | 5642 ZoneSplayTree<Config>::Locator ins; |
| 5643 DCHECK_RESULT(tree()->Insert(current.from(), &ins)); | 5643 CHECK(tree()->Insert(current.from(), &ins)); |
| 5644 ins.set_value(Entry(current.from(), | 5644 ins.set_value(Entry(current.from(), |
| 5645 entry->from() - 1, | 5645 entry->from() - 1, |
| 5646 empty()->Extend(value, zone))); | 5646 empty()->Extend(value, zone))); |
| 5647 current.set_from(entry->from()); | 5647 current.set_from(entry->from()); |
| 5648 } | 5648 } |
| 5649 DCHECK_EQ(current.from(), entry->from()); | 5649 DCHECK_EQ(current.from(), entry->from()); |
| 5650 // If the overlapping range extends beyond the one we want to add | 5650 // If the overlapping range extends beyond the one we want to add |
| 5651 // we have to snap the right part off and add it separately. | 5651 // we have to snap the right part off and add it separately. |
| 5652 if (entry->to() > current.to()) { | 5652 if (entry->to() > current.to()) { |
| 5653 ZoneSplayTree<Config>::Locator ins; | 5653 ZoneSplayTree<Config>::Locator ins; |
| 5654 DCHECK_RESULT(tree()->Insert(current.to() + 1, &ins)); | 5654 CHECK(tree()->Insert(current.to() + 1, &ins)); |
| 5655 ins.set_value(Entry(current.to() + 1, | 5655 ins.set_value(Entry(current.to() + 1, |
| 5656 entry->to(), | 5656 entry->to(), |
| 5657 entry->out_set())); | 5657 entry->out_set())); |
| 5658 entry->set_to(current.to()); | 5658 entry->set_to(current.to()); |
| 5659 } | 5659 } |
| 5660 DCHECK(entry->to() <= current.to()); | 5660 DCHECK(entry->to() <= current.to()); |
| 5661 // The overlapping range is now completely contained by the range | 5661 // The overlapping range is now completely contained by the range |
| 5662 // we're adding so we can just update it and move the start point | 5662 // we're adding so we can just update it and move the start point |
| 5663 // of the range we're adding just past it. | 5663 // of the range we're adding just past it. |
| 5664 entry->AddValue(value, zone); | 5664 entry->AddValue(value, zone); |
| 5665 // Bail out if the last interval ended at 0xFFFF since otherwise | 5665 // Bail out if the last interval ended at 0xFFFF since otherwise |
| 5666 // adding 1 will wrap around to 0. | 5666 // adding 1 will wrap around to 0. |
| 5667 if (entry->to() == String::kMaxUtf16CodeUnit) | 5667 if (entry->to() == String::kMaxUtf16CodeUnit) |
| 5668 break; | 5668 break; |
| 5669 DCHECK(entry->to() + 1 > current.from()); | 5669 DCHECK(entry->to() + 1 > current.from()); |
| 5670 current.set_from(entry->to() + 1); | 5670 current.set_from(entry->to() + 1); |
| 5671 } else { | 5671 } else { |
| 5672 // There is no overlap so we can just add the range | 5672 // There is no overlap so we can just add the range |
| 5673 ZoneSplayTree<Config>::Locator ins; | 5673 ZoneSplayTree<Config>::Locator ins; |
| 5674 DCHECK_RESULT(tree()->Insert(current.from(), &ins)); | 5674 CHECK(tree()->Insert(current.from(), &ins)); |
| 5675 ins.set_value(Entry(current.from(), | 5675 ins.set_value(Entry(current.from(), |
| 5676 current.to(), | 5676 current.to(), |
| 5677 empty()->Extend(value, zone))); | 5677 empty()->Extend(value, zone))); |
| 5678 break; | 5678 break; |
| 5679 } | 5679 } |
| 5680 } | 5680 } |
| 5681 } | 5681 } |
| 5682 | 5682 |
| 5683 | 5683 |
| 5684 OutSet* DispatchTable::Get(uc16 value) { | 5684 OutSet* DispatchTable::Get(uc16 value) { |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6153 Heap* heap = pattern->GetHeap(); | 6153 Heap* heap = pattern->GetHeap(); |
| 6154 bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize; | 6154 bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize; |
| 6155 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && | 6155 if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit && |
| 6156 heap->isolate()->memory_allocator()->SizeExecutable() > | 6156 heap->isolate()->memory_allocator()->SizeExecutable() > |
| 6157 RegExpImpl::kRegExpExecutableMemoryLimit) { | 6157 RegExpImpl::kRegExpExecutableMemoryLimit) { |
| 6158 too_much = true; | 6158 too_much = true; |
| 6159 } | 6159 } |
| 6160 return too_much; | 6160 return too_much; |
| 6161 } | 6161 } |
| 6162 }} // namespace v8::internal | 6162 }} // namespace v8::internal |
| OLD | NEW |