| 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_);
|
|
|