Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler_x64.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_compiler_x64.cc (revision 22436) |
| +++ runtime/vm/flow_graph_compiler_x64.cc (working copy) |
| @@ -642,10 +642,92 @@ |
| Scanner::kDummyTokenIndex); |
| } |
| AllocateRegistersLocally(instr); |
| + } else if (instr->MayThrow() && |
| + (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { |
| + // Optimized try-block: Sync locals to fixed stack locations. |
| + EmitTrySync(instr, CurrentTryIndex()); |
| } |
| } |
| +void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { |
|
Kevin Millikin (Google)
2013/05/08 11:42:00
Same comments as IA32.
Florian Schneider
2013/05/08 17:10:55
Done.
|
| + ASSERT(is_optimizing()); |
| + Environment* env = instr->env(); |
| + CatchBlockEntryInstr* catch_block = |
| + flow_graph().graph_entry()->GetCatchEntry(try_index); |
| + const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| + // Parameters. |
| + intptr_t i = 0; |
| + bool push_emitted = false; |
| + for (; i < flow_graph().num_non_copied_params(); ++i) { |
| + if ((*idefs)[i]->IsConstant()) continue; // common constants |
| + Location loc = env->LocationAt(i); |
| + const intptr_t index = flow_graph().num_non_copied_params() - i; |
| + Address dest(RBP, (kLastParamSlotIndex + index - 1) * kWordSize); |
| + if (loc.IsConstant()) { |
| + if (!push_emitted) { |
| + __ pushq(RAX); |
| + push_emitted = true; |
| + } |
| + __ LoadObject(RAX, loc.constant()); |
| + __ movq(dest, RAX); |
| + } else if (loc.IsRegister()) { |
| + __ movq(dest, loc.reg()); |
| + } else { |
| + Address src = loc.ToStackSlotAddress(); |
| + if (!src.Equals(dest)) { |
| + if (!push_emitted) { |
| + __ pushq(RAX); |
| + push_emitted = true; |
| + } |
| + __ movq(RAX, src); |
| + __ movq(dest, RAX); |
| + } |
| + } |
| + } |
| + // Process locals. Skip exception_var and stacktrace_var. |
| + CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| + intptr_t nncp = flow_graph_.num_non_copied_params(); |
| + intptr_t ex_idx = |
| + kFirstLocalSlotIndex - catch_entry->exception_var().index() + nncp; |
| + intptr_t st_idx = |
| + kFirstLocalSlotIndex - catch_entry->stacktrace_var().index() + nncp; |
| + for (; i < flow_graph().variable_count(); ++i) { |
| + if (i == ex_idx || i == st_idx) continue; |
| + if ((*idefs)[i]->IsConstant()) continue; |
| + Location loc = env->LocationAt(i); |
| + const intptr_t index = i - flow_graph().num_non_copied_params(); |
| + Address dest(RBP, (kFirstLocalSlotIndex - index) * kWordSize); |
| + if (loc.IsConstant()) { |
| + if (!push_emitted) { |
| + __ pushq(RAX); |
| + push_emitted = true; |
| + } |
| + __ LoadObject(RAX, loc.constant()); |
| + __ movq(dest, RAX); |
| + } else if (loc.IsRegister()) { |
| + __ movq(dest, loc.reg()); |
| + } else { |
| + Address src = loc.ToStackSlotAddress(); |
| + if (!src.Equals(dest)) { |
| + if (!push_emitted) { |
| + __ pushq(RAX); |
| + push_emitted = true; |
| + } |
| + __ movq(RAX, src); |
| + __ movq(dest, RAX); |
| + } |
| + } |
| + // Update safepoint bitmap to indicate that the target location |
| + // now contains a pointer. |
| + instr->locs()->stack_bitmap()->Set(index, true); |
| + } |
| + if (push_emitted) { |
| + __ popq(RAX); |
| + } |
| +} |
| + |
| + |
| void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
| if (is_optimizing()) return; |
| Definition* defn = instr->AsDefinition(); |
| @@ -936,7 +1018,7 @@ |
| 0); // No token position. |
| } |
| __ Comment("Enter frame"); |
| - __ EnterDartFrame((StackSize() * kWordSize)); |
| + __ EnterDartFrame(StackSize() * kWordSize); |
| } |