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++) { |