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

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

Issue 722243002: Indirectly dispatch all backtracking jumps through the same block. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: return on unreachable 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 GenerateEntryBlock(); 126 GenerateEntryBlock();
127 GenerateSuccessBlock(); 127 GenerateSuccessBlock();
128 GenerateBacktrackBlock();
129 GenerateExitBlock(); 128 GenerateExitBlock();
130 129
131 blocks_.Add(entry_block_); 130 blocks_.Add(entry_block_);
132 blocks_.Add(entry_block_->normal_entry()); 131 blocks_.Add(entry_block_->normal_entry());
133 blocks_.Add(start_block_); 132 blocks_.Add(start_block_);
134 blocks_.Add(success_block_); 133 blocks_.Add(success_block_);
135 blocks_.Add(backtrack_block_); 134 blocks_.Add(backtrack_block_);
136 blocks_.Add(exit_block_); 135 blocks_.Add(exit_block_);
137 136
138 // Begin emission at the start_block_. 137 // Begin emission at the start_block_.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 StoreLocal(current_position_, Bind(Sub(start_index_push, length_push))); 200 StoreLocal(current_position_, Bind(Sub(start_index_push, length_push)));
202 201
203 // Jump to the start block. 202 // Jump to the start block.
204 current_instruction_->Goto(start_block_); 203 current_instruction_->Goto(start_block_);
205 } 204 }
206 205
207 206
208 void IRRegExpMacroAssembler::GenerateBacktrackBlock() { 207 void IRRegExpMacroAssembler::GenerateBacktrackBlock() {
209 set_current_instruction(backtrack_block_); 208 set_current_instruction(backtrack_block_);
210 TAG(); 209 TAG();
211 Backtrack(); 210 CheckPreemption();
211
212 const intptr_t entries_count = entry_block_->indirect_entries().length();
213
214 GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle(
215 I, GrowableObjectArray::New(entries_count, Heap::kOld));
216
217 PushArgumentInstr* block_offsets_push =
218 PushArgument(Bind(new(I) ConstantInstr(offsets)));
219 PushArgumentInstr* block_id_push = PushArgument(PopStack());
220
221 Value* offset_value =
222 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
223 block_offsets_push,
224 block_id_push));
225
226 backtrack_goto_ = new(I) IndirectGotoInstr(&offsets, offset_value);
227 CloseBlockWith(backtrack_goto_);
228
229 // Add an edge from the "indirect" goto to each of the targets.
230 for (intptr_t j = 0; j < entries_count; j++) {
231 backtrack_goto_->AddSuccessor(
232 TargetWithJoinGoto(entry_block_->indirect_entries().At(j)));
233 }
212 } 234 }
213 235
214 236
215 void IRRegExpMacroAssembler::GenerateSuccessBlock() { 237 void IRRegExpMacroAssembler::GenerateSuccessBlock() {
216 set_current_instruction(success_block_); 238 set_current_instruction(success_block_);
217 TAG(); 239 TAG();
218 240
219 Definition* type_args_null_def = new(I) ConstantInstr( 241 Definition* type_args_null_def = new(I) ConstantInstr(
220 TypeArguments::ZoneHandle(I, TypeArguments::null())); 242 TypeArguments::ZoneHandle(I, TypeArguments::null()));
221 PushArgumentInstr* type_arg_push = PushArgument(Bind(type_args_null_def)); 243 PushArgumentInstr* type_arg_push = PushArgument(Bind(type_args_null_def));
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 if (by != 0) { 738 if (by != 0) {
717 PushArgumentInstr* reg_push = PushLocal(position_register(reg)); 739 PushArgumentInstr* reg_push = PushLocal(position_register(reg));
718 PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by))); 740 PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by)));
719 StoreLocal(position_register(reg), Bind(Add(reg_push, by_push))); 741 StoreLocal(position_register(reg), Bind(Add(reg_push, by_push)));
720 } 742 }
721 } 743 }
722 744
723 745
724 void IRRegExpMacroAssembler::Backtrack() { 746 void IRRegExpMacroAssembler::Backtrack() {
725 TAG(); 747 TAG();
726 CheckPreemption(); 748 GoTo(backtrack_block_);
727
728 GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle(
729 I, GrowableObjectArray::New(Heap::kOld));
730
731 PushArgumentInstr* block_offsets_push =
732 PushArgument(Bind(new(I) ConstantInstr(offsets)));
733 PushArgumentInstr* block_id_push = PushArgument(PopStack());
734
735 Value* offset_value =
736 Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
737 block_offsets_push,
738 block_id_push));
739
740 IndirectGotoInstr* igoto = new(I) IndirectGotoInstr(&offsets, offset_value);
741 CloseBlockWith(igoto);
742 igotos_.Add(igoto);
743 } 749 }
744 750
745 751
746 // A BindBlock is analogous to assigning a label to a basic block. 752 // 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. 753 // 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. 754 // If there is a current instruction, append a goto to the bound block.
749 void IRRegExpMacroAssembler::BindBlock(BlockLabel* label) { 755 void IRRegExpMacroAssembler::BindBlock(BlockLabel* label) {
750 ASSERT(!label->IsBound()); 756 ASSERT(!label->IsBound());
751 ASSERT(label->block()->next() == NULL); 757 ASSERT(label->block()->next() == NULL);
752 758
(...skipping 19 matching lines...) Expand all
772 LocalVariable* IRRegExpMacroAssembler::position_register(intptr_t index) { 778 LocalVariable* IRRegExpMacroAssembler::position_register(intptr_t index) {
773 // Create position registers as needed. 779 // Create position registers as needed.
774 for (intptr_t i = position_registers_.length(); i < index + 1; i++) { 780 for (intptr_t i = position_registers_.length(); i < index + 1; i++) {
775 position_registers_.Add(Local(Symbols::position_registers_())); 781 position_registers_.Add(Local(Symbols::position_registers_()));
776 } 782 }
777 783
778 return position_registers_[index]; 784 return position_registers_[index];
779 } 785 }
780 786
781 787
782 // TODO(zerny): Move the offset table outside to avoid having to keep
783 // the assembler around until after code generation; both function or regexp
784 // would work.
785 void IRRegExpMacroAssembler::FinalizeBlockOffsetTable() {
786 for (intptr_t i = 0; i < igotos_.length(); i++) {
787 IndirectGotoInstr* igoto = igotos_[i];
788 igoto->SetOffsetCount(I, indirect_id_.Count());
789
790 for (intptr_t j = 0; j < igoto->SuccessorCount(); j++) {
791 TargetEntryInstr* target = igoto->SuccessorAt(j);
792
793 // Optimizations might have modified the immediate target block, but
794 // it must end with a goto to the indirect entry.
795 Instruction* instr = target;
796 while (instr != NULL && !instr->IsGoto()) {
797 instr = instr->next();
798 }
799 ASSERT(instr->IsGoto());
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 }
816 }
817 }
818
819 void IRRegExpMacroAssembler::FinalizeIndirectGotos() {
820 for (intptr_t i = 0; i < igotos_.length(); i++) {
821 for (intptr_t j = 0; j < entry_block_->indirect_entries().length(); j++) {
822 igotos_.At(i)->AddSuccessor(
823 TargetWithJoinGoto(entry_block_->indirect_entries().At(j)));
824 }
825 }
826 }
827
828
829 void IRRegExpMacroAssembler::CheckCharacter(uint32_t c, BlockLabel* on_equal) { 788 void IRRegExpMacroAssembler::CheckCharacter(uint32_t c, BlockLabel* on_equal) {
830 TAG(); 789 TAG();
831 Definition* cur_char_def = LoadLocal(current_character_); 790 Definition* cur_char_def = LoadLocal(current_character_);
832 Definition* char_def = Uint64Constant(c); 791 Definition* char_def = Uint64Constant(c);
833 792
834 BranchOrBacktrack(Comparison(kEQ, cur_char_def, char_def), 793 BranchOrBacktrack(Comparison(kEQ, cur_char_def, char_def),
835 on_equal); 794 on_equal);
836 } 795 }
837 796
838 797
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 index, 1803 index,
1845 characters, 1804 characters,
1846 specialization_cid_, 1805 specialization_cid_,
1847 Scanner::kNoSourcePos)); 1806 Scanner::kNoSourcePos));
1848 } 1807 }
1849 1808
1850 1809
1851 #undef __ 1810 #undef __
1852 1811
1853 } // namespace dart 1812 } // 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