Chromium Code Reviews| Index: runtime/vm/regexp_assembler.cc |
| diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc |
| index 4285e12ab52cbf08011f7427324bf132dba1ba6f..36aee2b0ec23bc34384d8976daa94239e77a8206 100644 |
| --- a/runtime/vm/regexp_assembler.cc |
| +++ b/runtime/vm/regexp_assembler.cc |
| @@ -35,7 +35,7 @@ DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps"); |
| 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.
|
| -static const intptr_t kNoTokenPos = -1; |
| +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.
|
| void PrintUtf16(uint16_t c) { |
| @@ -123,6 +123,11 @@ IRRegExpMacroAssembler::IRRegExpMacroAssembler( |
| exit_block_ = |
| new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); |
| + // Allocate offsets table mapping ids of backtracking blocks to addresses. |
| + GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle( |
| + isolate, GrowableObjectArray::New(Heap::kOld)); |
| + entry_block_->set_indirect_entry_offsets(&offsets); |
| + |
| GenerateEntryBlock(); |
| GenerateSuccessBlock(); |
| GenerateBacktrackBlock(); |
| @@ -725,8 +730,7 @@ void IRRegExpMacroAssembler::Backtrack() { |
| TAG(); |
| CheckPreemption(); |
| - GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle( |
| - I, GrowableObjectArray::New(Heap::kOld)); |
| + 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.
|
| PushArgumentInstr* block_offsets_push = |
| PushArgument(Bind(new(I) ConstantInstr(offsets))); |
| @@ -737,7 +741,7 @@ void IRRegExpMacroAssembler::Backtrack() { |
| block_offsets_push, |
| block_id_push)); |
| - IndirectGotoInstr* igoto = new(I) IndirectGotoInstr(&offsets, offset_value); |
| + IndirectGotoInstr* igoto = new(I) IndirectGotoInstr(offset_value); |
| CloseBlockWith(igoto); |
| igotos_.Add(igoto); |
| } |
| @@ -779,43 +783,31 @@ 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::FinalizeBlockOffsetTable(Isolate* isolate, |
| + GraphEntryInstr* graph) { |
| + const GrowableArray<IndirectEntryInstr*>& entries = graph->indirect_entries(); |
| + const intptr_t count = entries.length(); |
| + 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.
|
| + GrowableObjectArray* offsets = graph->indirect_entry_offsets(); |
| + if (offsets->Capacity() < count) { |
| + offsets->Grow(count, Heap::kOld); |
| + } |
| + if (offsets->Length() < count) { |
| + offsets->SetLength(count); |
| + } |
| + for (intptr_t i = 0; i < count; ++i) { |
| + IndirectEntryInstr* entry = entries[i]; |
| + if (entry->offset() <= 0) { |
| + // An invalid offset signifies an unreachable block. |
| + // TODO(zerny): We should guard against usage of an invalid index. |
| + continue; |
| } |
| + intptr_t offset = entry->offset() - Assembler::EntryPointToPcMarkerOffset(); |
| + offsets->SetAt(i, Smi::ZoneHandle(isolate, Smi::New(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++) { |