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