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

Side by Side Diff: runtime/vm/regexp_assembler.cc

Issue 716163003: Use one offsets table per generated irregexp matching function. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « runtime/vm/regexp_assembler.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 (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/regexp_assembler.h" 5 #include "vm/regexp_assembler.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 16 matching lines...) Expand all
27 String::Handle(String::New("TAG: ")), \ 27 String::Handle(String::New("TAG: ")), \
28 String::Handle(String::New(__FUNCTION__)), Heap::kOld)))))); 28 String::Handle(String::New(__FUNCTION__)), Heap::kOld))))));
29 29
30 #define PRINT(arg) if (FLAG_trace_irregexp) { Print(arg); } 30 #define PRINT(arg) if (FLAG_trace_irregexp) { Print(arg); }
31 31
32 namespace dart { 32 namespace dart {
33 33
34 DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps"); 34 DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps");
35 35
36 36
37 static const intptr_t kInvalidTryIndex = -1; 37 static const intptr_t kInvalidTryIndex = -1;
Florian Schneider 2014/11/12 11:38:56 static const intptr_t kInvalidTryIndex = CatchClau
zerny-google 2014/11/12 11:58:47 Done.
38 static const intptr_t kNoTokenPos = -1; 38 static const intptr_t kNoTokenPos = 0;
Florian Schneider 2014/11/12 11:38:56 Define in terms of Scanner::kNoSourcePos which is
zerny-google 2014/11/12 11:58:47 Done.
39 39
40 40
41 void PrintUtf16(uint16_t c) { 41 void PrintUtf16(uint16_t c) {
42 const char* format = (0x20 <= c && c <= 0x7F) ? 42 const char* format = (0x20 <= c && c <= 0x7F) ?
43 "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x"; 43 "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x";
44 OS::Print(format, c); 44 OS::Print(format, c);
45 } 45 }
46 46
47 47
48 /* 48 /*
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 Isolate::kNoDeoptId); 116 Isolate::kNoDeoptId);
117 start_block_ = 117 start_block_ =
118 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); 118 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
119 success_block_ = 119 success_block_ =
120 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); 120 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
121 backtrack_block_ = 121 backtrack_block_ =
122 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); 122 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
123 exit_block_ = 123 exit_block_ =
124 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); 124 new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
125 125
126 // Allocate offsets table mapping ids of backtracking blocks to addresses.
127 GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle(
128 isolate, GrowableObjectArray::New(Heap::kOld));
129 entry_block_->set_indirect_entry_offsets(&offsets);
130
126 GenerateEntryBlock(); 131 GenerateEntryBlock();
127 GenerateSuccessBlock(); 132 GenerateSuccessBlock();
128 GenerateBacktrackBlock(); 133 GenerateBacktrackBlock();
129 GenerateExitBlock(); 134 GenerateExitBlock();
130 135
131 blocks_.Add(entry_block_); 136 blocks_.Add(entry_block_);
132 blocks_.Add(entry_block_->normal_entry()); 137 blocks_.Add(entry_block_->normal_entry());
133 blocks_.Add(start_block_); 138 blocks_.Add(start_block_);
134 blocks_.Add(success_block_); 139 blocks_.Add(success_block_);
135 blocks_.Add(backtrack_block_); 140 blocks_.Add(backtrack_block_);
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by))); 723 PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by)));
719 StoreLocal(position_register(reg), Bind(Add(reg_push, by_push))); 724 StoreLocal(position_register(reg), Bind(Add(reg_push, by_push)));
720 } 725 }
721 } 726 }
722 727
723 728
724 void IRRegExpMacroAssembler::Backtrack() { 729 void IRRegExpMacroAssembler::Backtrack() {
725 TAG(); 730 TAG();
726 CheckPreemption(); 731 CheckPreemption();
727 732
728 GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle( 733 GrowableObjectArray& offsets = *entry_block_->indirect_entry_offsets();
Florian Schneider 2014/11/12 11:38:56 const GrowableObjectArray&
zerny-google 2014/11/12 11:58:47 Done.
729 I, GrowableObjectArray::New(Heap::kOld));
730 734
731 PushArgumentInstr* block_offsets_push = 735 PushArgumentInstr* block_offsets_push =
732 PushArgument(Bind(new(I) ConstantInstr(offsets))); 736 PushArgument(Bind(new(I) ConstantInstr(offsets)));
733 PushArgumentInstr* block_id_push = PushArgument(PopStack()); 737 PushArgumentInstr* block_id_push = PushArgument(PopStack());
734 738
735 Value* offset_value = 739 Value* offset_value =
736 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX), 740 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
737 block_offsets_push, 741 block_offsets_push,
738 block_id_push)); 742 block_id_push));
739 743
740 IndirectGotoInstr* igoto = new(I) IndirectGotoInstr(&offsets, offset_value); 744 IndirectGotoInstr* igoto = new(I) IndirectGotoInstr(offset_value);
741 CloseBlockWith(igoto); 745 CloseBlockWith(igoto);
742 igotos_.Add(igoto); 746 igotos_.Add(igoto);
743 } 747 }
744 748
745 749
746 // A BindBlock is analogous to assigning a label to a basic block. 750 // A BindBlock is analogous to assigning a label to a basic block.
747 // If the BlockLabel does not yet contain a block, it is created. 751 // If the BlockLabel does not yet contain a block, it is created.
748 // If there is a current instruction, append a goto to the bound block. 752 // If there is a current instruction, append a goto to the bound block.
749 void IRRegExpMacroAssembler::BindBlock(BlockLabel* label) { 753 void IRRegExpMacroAssembler::BindBlock(BlockLabel* label) {
750 ASSERT(!label->IsBound()); 754 ASSERT(!label->IsBound());
(...skipping 21 matching lines...) Expand all
772 LocalVariable* IRRegExpMacroAssembler::position_register(intptr_t index) { 776 LocalVariable* IRRegExpMacroAssembler::position_register(intptr_t index) {
773 // Create position registers as needed. 777 // Create position registers as needed.
774 for (intptr_t i = position_registers_.length(); i < index + 1; i++) { 778 for (intptr_t i = position_registers_.length(); i < index + 1; i++) {
775 position_registers_.Add(Local(Symbols::position_registers_())); 779 position_registers_.Add(Local(Symbols::position_registers_()));
776 } 780 }
777 781
778 return position_registers_[index]; 782 return position_registers_[index];
779 } 783 }
780 784
781 785
782 // TODO(zerny): Move the offset table outside to avoid having to keep 786 void IRRegExpMacroAssembler::FinalizeBlockOffsetTable(Isolate* isolate,
783 // the assembler around until after code generation; both function or regexp 787 GraphEntryInstr* graph) {
784 // would work. 788 const GrowableArray<IndirectEntryInstr*>& entries = graph->indirect_entries();
785 void IRRegExpMacroAssembler::FinalizeBlockOffsetTable() { 789 const intptr_t count = entries.length();
786 for (intptr_t i = 0; i < igotos_.length(); i++) { 790 if (!count) return;
Florian Schneider 2014/11/12 11:38:56 Use count == 0 instead here.
zerny-google 2014/11/12 11:58:47 Ok. But I rather removed the early return here.
787 IndirectGotoInstr* igoto = igotos_[i]; 791 GrowableObjectArray* offsets = graph->indirect_entry_offsets();
788 igoto->SetOffsetCount(I, indirect_id_.Count()); 792 if (offsets->Capacity() < count) {
789 793 offsets->Grow(count, Heap::kOld);
790 for (intptr_t j = 0; j < igoto->SuccessorCount(); j++) { 794 }
791 TargetEntryInstr* target = igoto->SuccessorAt(j); 795 if (offsets->Length() < count) {
792 796 offsets->SetLength(count);
793 // Optimizations might have modified the immediate target block, but 797 }
794 // it must end with a goto to the indirect entry. 798 for (intptr_t i = 0; i < count; ++i) {
795 Instruction* instr = target; 799 IndirectEntryInstr* entry = entries[i];
796 while (instr != NULL && !instr->IsGoto()) { 800 if (entry->offset() <= 0) {
797 instr = instr->next(); 801 // An invalid offset signifies an unreachable block.
798 } 802 // TODO(zerny): We should guard against usage of an invalid index.
799 ASSERT(instr->IsGoto()); 803 continue;
800
801 IndirectEntryInstr* ientry =
802 instr->AsGoto()->successor()->AsIndirectEntry();
803 ASSERT(ientry != NULL);
804
805 // The intermediate block was possibly compacted, check both it and the
806 // final indirect entry for a valid offset. If neither are valid, then
807 // the indirect entry is unreachable.
808 intptr_t offset =
809 (target->offset() > 0) ? target->offset() : ientry->offset();
810 if (offset > 0) {
811 intptr_t adjusted_offset =
812 offset - Assembler::EntryPointToPcMarkerOffset();
813 igoto->SetOffsetAt(I, ientry->indirect_id(), adjusted_offset);
814 }
815 } 804 }
805 intptr_t offset = entry->offset() - Assembler::EntryPointToPcMarkerOffset();
806 offsets->SetAt(i, Smi::ZoneHandle(isolate, Smi::New(offset)));
816 } 807 }
817 } 808 }
818 809
810
819 void IRRegExpMacroAssembler::FinalizeIndirectGotos() { 811 void IRRegExpMacroAssembler::FinalizeIndirectGotos() {
820 for (intptr_t i = 0; i < igotos_.length(); i++) { 812 for (intptr_t i = 0; i < igotos_.length(); i++) {
821 for (intptr_t j = 0; j < entry_block_->indirect_entries().length(); j++) { 813 for (intptr_t j = 0; j < entry_block_->indirect_entries().length(); j++) {
822 igotos_.At(i)->AddSuccessor( 814 igotos_.At(i)->AddSuccessor(
823 TargetWithJoinGoto(entry_block_->indirect_entries().At(j))); 815 TargetWithJoinGoto(entry_block_->indirect_entries().At(j)));
824 } 816 }
825 } 817 }
826 } 818 }
827 819
828 820
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 index, 1836 index,
1845 characters, 1837 characters,
1846 specialization_cid_, 1838 specialization_cid_,
1847 Scanner::kNoSourcePos)); 1839 Scanner::kNoSourcePos));
1848 } 1840 }
1849 1841
1850 1842
1851 #undef __ 1843 #undef __
1852 1844
1853 } // namespace dart 1845 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/regexp_assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698