| Index: runtime/vm/intermediate_language.cc
|
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
|
| index 250651e3bb61c3cee1b4fec56e64c5add6da63d7..17e86baedb6d2c771b6198e9d64adebf5f2ea91a 100644
|
| --- a/runtime/vm/intermediate_language.cc
|
| +++ b/runtime/vm/intermediate_language.cc
|
| @@ -2530,6 +2530,41 @@ void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
|
|
| +void IndirectGotoInstr::ComputeOffsetTable(Isolate* isolate) {
|
| + if (GetBlock()->offset() < 0) {
|
| + // Don't generate a table when contained in an unreachable block.
|
| + return;
|
| + }
|
| + ASSERT(SuccessorCount() == offsets_.Capacity());
|
| + offsets_.SetLength(SuccessorCount());
|
| + for (intptr_t i = 0; i < SuccessorCount(); i++) {
|
| + TargetEntryInstr* target = SuccessorAt(i);
|
| + intptr_t offset = target->offset();
|
| +
|
| + // The intermediate block might be compacted, if so, use the indirect entry.
|
| + if (offset < 0) {
|
| + // Optimizations might have modified the immediate target block, but it
|
| + // must end with a goto to the indirect entry. Also, we can't use
|
| + // last_instruction because 'target' is compacted/unreachable.
|
| + Instruction* last = target->next();
|
| + while (last != NULL && !last->IsGoto()) {
|
| + last = last->next();
|
| + }
|
| + ASSERT(last);
|
| + IndirectEntryInstr* ientry =
|
| + last->AsGoto()->successor()->AsIndirectEntry();
|
| + ASSERT(ientry != NULL);
|
| + ASSERT(ientry->indirect_id() == i);
|
| + offset = ientry->offset();
|
| + }
|
| +
|
| + ASSERT(offset > 0);
|
| + offset -= Assembler::EntryPointToPcMarkerOffset();
|
| + offsets_.SetAt(i, Smi::ZoneHandle(isolate, Smi::New(offset)));
|
| + }
|
| +}
|
| +
|
| +
|
| LocationSummary* IndirectEntryInstr::MakeLocationSummary(
|
| Isolate* isolate, bool optimizing) const {
|
| return JoinEntryInstr::MakeLocationSummary(isolate, optimizing);
|
|
|