Index: runtime/vm/regexp_assembler.cc |
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc |
index 4285e12ab52cbf08011f7427324bf132dba1ba6f..c5e4ba3a5f3edcac8e41647f0e535715d534284b 100644 |
--- a/runtime/vm/regexp_assembler.cc |
+++ b/runtime/vm/regexp_assembler.cc |
@@ -34,8 +34,8 @@ namespace dart { |
DEFINE_FLAG(bool, trace_irregexp, false, "Trace irregexps"); |
-static const intptr_t kInvalidTryIndex = -1; |
-static const intptr_t kNoTokenPos = -1; |
+static const intptr_t kInvalidTryIndex = CatchClauseNode::kInvalidTryIndex; |
+static const intptr_t kNoSourcePos = Scanner::kNoSourcePos; |
void PrintUtf16(uint16_t c) { |
@@ -112,8 +112,8 @@ IRRegExpMacroAssembler::IRRegExpMacroAssembler( |
entry_block_ = |
new(isolate) GraphEntryInstr( |
parsed_function_, |
- new(isolate) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex), |
- Isolate::kNoDeoptId); |
+ new(isolate) TargetEntryInstr( |
+ block_id_.Alloc(), kInvalidTryIndex), Isolate::kNoDeoptId); |
start_block_ = |
new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex); |
success_block_ = |
@@ -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(); |
@@ -254,7 +259,7 @@ void IRRegExpMacroAssembler::GenerateSuccessBlock() { |
PRINT(PushLocal(result_)); |
// Return true on success. |
- AppendInstruction(new(I) ReturnInstr(kNoTokenPos, Bind(LoadLocal(result_)))); |
+ AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); |
} |
@@ -263,7 +268,7 @@ void IRRegExpMacroAssembler::GenerateExitBlock() { |
TAG(); |
// Return false on failure. |
- AppendInstruction(new(I) ReturnInstr(kNoTokenPos, Bind(LoadLocal(result_)))); |
+ AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); |
} |
@@ -351,7 +356,7 @@ LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name, |
intptr_t index) const { |
const Type& local_type = Type::ZoneHandle(I, Type::DynamicType()); |
LocalVariable* local = |
- new(I) LocalVariable(kNoTokenPos, name, local_type); |
+ new(I) LocalVariable(kNoSourcePos, name, local_type); |
intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index; |
local->set_index(param_frame_index); |
@@ -363,7 +368,7 @@ LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name, |
LocalVariable* IRRegExpMacroAssembler::Local(const String& name) { |
const Type& local_type = Type::ZoneHandle(I, Type::DynamicType()); |
LocalVariable* local = |
- new(I) LocalVariable(kNoTokenPos, name, local_type); |
+ new(I) LocalVariable(kNoSourcePos, name, local_type); |
local->set_index(GetNextLocalIndex()); |
return local; |
@@ -451,7 +456,7 @@ ComparisonInstr* IRRegExpMacroAssembler::Comparison( |
rhs_push)); |
Value* rhs_value = Bind(BoolConstant(true)); |
- return new(I) StrictCompareInstr(kNoTokenPos, strict_comparison, |
+ return new(I) StrictCompareInstr(kNoSourcePos, strict_comparison, |
lhs_value, rhs_value, true); |
} |
@@ -491,7 +496,7 @@ StaticCallInstr* IRRegExpMacroAssembler::StaticCall( |
StaticCallInstr* IRRegExpMacroAssembler::StaticCall( |
const Function& function, |
ZoneGrowableArray<PushArgumentInstr*>* arguments) const { |
- return new(I) StaticCallInstr(kNoTokenPos, |
+ return new(I) StaticCallInstr(kNoSourcePos, |
function, |
Object::null_array(), |
arguments, |
@@ -542,7 +547,7 @@ InstanceCallInstr* IRRegExpMacroAssembler::InstanceCall( |
const InstanceCallDescriptor& desc, |
ZoneGrowableArray<PushArgumentInstr*> *arguments) const { |
return |
- new(I) InstanceCallInstr(kNoTokenPos, |
+ new(I) InstanceCallInstr(kNoSourcePos, |
desc.name, |
desc.token_kind, |
arguments, |
@@ -725,8 +730,7 @@ void IRRegExpMacroAssembler::Backtrack() { |
TAG(); |
CheckPreemption(); |
- GrowableObjectArray& offsets = GrowableObjectArray::ZoneHandle( |
- I, GrowableObjectArray::New(Heap::kOld)); |
+ const GrowableObjectArray& offsets = *entry_block_->indirect_entry_offsets(); |
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,30 @@ 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(); |
+ 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++) { |
@@ -1774,7 +1765,7 @@ IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto( |
void IRRegExpMacroAssembler::CheckPreemption() { |
TAG(); |
- AppendInstruction(new(I) CheckStackOverflowInstr(kNoTokenPos, 0)); |
+ AppendInstruction(new(I) CheckStackOverflowInstr(kNoSourcePos, 0)); |
} |