Index: runtime/vm/regexp_assembler.cc |
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc |
index 60382d87162f5b5910e0a03e7001f705fa03a2dc..23e9c4178c354556fba7a354d40d86015169b116 100644 |
--- a/runtime/vm/regexp_assembler.cc |
+++ b/runtime/vm/regexp_assembler.cc |
@@ -125,7 +125,6 @@ IRRegExpMacroAssembler::IRRegExpMacroAssembler( |
GenerateEntryBlock(); |
GenerateSuccessBlock(); |
- GenerateBacktrackBlock(); |
GenerateExitBlock(); |
blocks_.Add(entry_block_); |
@@ -208,7 +207,30 @@ void IRRegExpMacroAssembler::GenerateEntryBlock() { |
void IRRegExpMacroAssembler::GenerateBacktrackBlock() { |
set_current_instruction(backtrack_block_); |
TAG(); |
- Backtrack(); |
+ CheckPreemption(); |
+ |
+ const intptr_t entries_count = entry_block_->indirect_entries().length(); |
+ |
+ GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle( |
+ I, GrowableObjectArray::New(entries_count, Heap::kOld)); |
+ |
+ PushArgumentInstr* block_offsets_push = |
+ PushArgument(Bind(new(I) ConstantInstr(offsets))); |
+ PushArgumentInstr* block_id_push = PushArgument(PopStack()); |
+ |
+ Value* offset_value = |
+ Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX), |
+ block_offsets_push, |
+ block_id_push)); |
+ |
+ backtrack_goto_ = new(I) IndirectGotoInstr(&offsets, offset_value); |
+ CloseBlockWith(backtrack_goto_); |
+ |
+ // Add an edge from the "indirect" goto to each of the targets. |
+ for (intptr_t j = 0; j < entries_count; j++) { |
+ backtrack_goto_->AddSuccessor( |
+ TargetWithJoinGoto(entry_block_->indirect_entries().At(j))); |
+ } |
} |
@@ -723,23 +745,7 @@ void IRRegExpMacroAssembler::AdvanceRegister(intptr_t reg, intptr_t by) { |
void IRRegExpMacroAssembler::Backtrack() { |
TAG(); |
- CheckPreemption(); |
- |
- GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle( |
- I, GrowableObjectArray::New(Heap::kOld)); |
- |
- PushArgumentInstr* block_offsets_push = |
- PushArgument(Bind(new(I) ConstantInstr(offsets))); |
- PushArgumentInstr* block_id_push = PushArgument(PopStack()); |
- |
- Value* offset_value = |
- Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX), |
- block_offsets_push, |
- block_id_push)); |
- |
- IndirectGotoInstr* igoto = new(I) IndirectGotoInstr(&offsets, offset_value); |
- CloseBlockWith(igoto); |
- igotos_.Add(igoto); |
+ GoTo(backtrack_block_); |
} |
@@ -779,53 +785,6 @@ LocalVariable* IRRegExpMacroAssembler::position_register(intptr_t index) { |
} |
-// TODO(zerny): Move the offset table outside to avoid having to keep |
-// the assembler around until after code generation; both function or regexp |
-// would work. |
-void IRRegExpMacroAssembler::FinalizeBlockOffsetTable() { |
- for (intptr_t i = 0; i < igotos_.length(); i++) { |
- IndirectGotoInstr* igoto = igotos_[i]; |
- igoto->SetOffsetCount(I, indirect_id_.Count()); |
- |
- for (intptr_t j = 0; j < igoto->SuccessorCount(); j++) { |
- TargetEntryInstr* target = igoto->SuccessorAt(j); |
- |
- // Optimizations might have modified the immediate target block, but |
- // it must end with a goto to the indirect entry. |
- Instruction* instr = target; |
- while (instr != NULL && !instr->IsGoto()) { |
- instr = instr->next(); |
- } |
- ASSERT(instr->IsGoto()); |
- |
- IndirectEntryInstr* ientry = |
- instr->AsGoto()->successor()->AsIndirectEntry(); |
- ASSERT(ientry != NULL); |
- |
- // The intermediate block was possibly compacted, check both it and the |
- // final indirect entry for a valid offset. If neither are valid, then |
- // the indirect entry is unreachable. |
- intptr_t offset = |
- (target->offset() > 0) ? target->offset() : ientry->offset(); |
- if (offset > 0) { |
- intptr_t adjusted_offset = |
- offset - Assembler::EntryPointToPcMarkerOffset(); |
- igoto->SetOffsetAt(I, ientry->indirect_id(), adjusted_offset); |
- } |
- } |
- } |
-} |
- |
-void IRRegExpMacroAssembler::FinalizeIndirectGotos() { |
- for (intptr_t i = 0; i < igotos_.length(); i++) { |
- for (intptr_t j = 0; j < entry_block_->indirect_entries().length(); j++) { |
- igotos_.At(i)->AddSuccessor( |
- TargetWithJoinGoto(entry_block_->indirect_entries().At(j))); |
- } |
- } |
-} |
- |
- |
void IRRegExpMacroAssembler::CheckCharacter(uint32_t c, BlockLabel* on_equal) { |
TAG(); |
Definition* cur_char_def = LoadLocal(current_character_); |