OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 } else { | 53 } else { |
54 ASSERT(value.IsStackSlot()); | 54 ASSERT(value.IsStackSlot()); |
55 __ pushq(value.ToStackSlotAddress()); | 55 __ pushq(value.ToStackSlotAddress()); |
56 } | 56 } |
57 } | 57 } |
58 } | 58 } |
59 | 59 |
60 | 60 |
61 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 61 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
62 const intptr_t kNumInputs = 1; | 62 const intptr_t kNumInputs = 1; |
63 const intptr_t kNumTemps = 1; | 63 const intptr_t kNumTemps = 0; |
64 LocationSummary* locs = | 64 LocationSummary* locs = |
65 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 65 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
66 locs->set_in(0, Location::RegisterLocation(RAX)); | 66 locs->set_in(0, Location::RegisterLocation(RAX)); |
67 locs->set_temp(0, Location::RegisterLocation(RDX)); | |
68 return locs; | 67 return locs; |
69 } | 68 } |
70 | 69 |
71 | 70 |
72 // Attempt optimized compilation at return instruction instead of at the entry. | 71 // Attempt optimized compilation at return instruction instead of at the entry. |
73 // The entry needs to be patchable, no inlined objects are allowed in the area | 72 // The entry needs to be patchable, no inlined objects are allowed in the area |
74 // that will be overwritten by the patch instruction: a jump). | 73 // that will be overwritten by the patch instruction: a jump). |
75 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 74 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
76 const Function& function = | |
77 Function::ZoneHandle(compiler->parsed_function().function().raw()); | |
78 Register result = locs()->in(0).reg(); | 75 Register result = locs()->in(0).reg(); |
79 Register func_reg = locs()->temp(0).reg(); | |
80 ASSERT(result == RAX); | 76 ASSERT(result == RAX); |
81 if (compiler->is_optimizing()) { | |
82 if (compiler->may_reoptimize()) { | |
83 // Increment of counter occurs only in optimized IC calls, as they | |
84 // can cause reoptimization. | |
85 Label done; | |
86 __ LoadObject(func_reg, function); | |
87 __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()), | |
88 Immediate(FLAG_optimization_counter_threshold)); | |
89 __ j(LESS, &done, Assembler::kNearJump); | |
90 // Equal (or greater), optimize. Note that counter can reach equality | |
91 // only at return instruction. | |
92 // The stub call preserves result register (EAX). | |
93 ASSERT(func_reg == RDX); | |
94 compiler->GenerateCall(0, // no token position. | |
95 &StubCode::OptimizeFunctionLabel(), | |
96 PcDescriptors::kOther, | |
97 locs()); | |
98 __ Bind(&done); | |
99 } | |
100 } else { | |
101 __ Comment("Check function counter"); | |
102 // Count only in unoptimized code. | |
103 // TODO(srdjan): Replace the counting code with a type feedback | |
104 // collection and counting stub. | |
105 __ LoadObject(func_reg, function); | |
106 __ incq(FieldAddress(func_reg, Function::usage_counter_offset())); | |
107 if (compiler->CanOptimizeFunction() && | |
108 compiler->parsed_function().function().is_optimizable()) { | |
109 // Do not optimize if usage count must be reported. | |
110 __ cmpq(FieldAddress(func_reg, Function::usage_counter_offset()), | |
111 Immediate(FLAG_optimization_counter_threshold)); | |
112 Label not_yet_hot; | |
113 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); | |
114 // Equal (or greater), optimize. | |
115 // The stub call preserves result register(RAX) | |
116 ASSERT(func_reg == RDX); | |
117 compiler->GenerateCall(0, // no token position. | |
118 &StubCode::OptimizeFunctionLabel(), | |
119 PcDescriptors::kOther, | |
120 locs()); | |
121 __ Bind(¬_yet_hot); | |
122 } | |
123 } | |
124 #if defined(DEBUG) | 77 #if defined(DEBUG) |
125 // TODO(srdjan): Fix for functions with finally clause. | 78 // TODO(srdjan): Fix for functions with finally clause. |
126 // A finally clause may leave a previously pushed return value if it | 79 // A finally clause may leave a previously pushed return value if it |
127 // has its own return instruction. Method that have finally are currently | 80 // has its own return instruction. Method that have finally are currently |
128 // not optimized. | 81 // not optimized. |
129 if (!compiler->HasFinally()) { | 82 if (!compiler->HasFinally()) { |
130 Label done; | 83 Label done; |
131 __ movq(RDI, RBP); | 84 __ movq(RDI, RBP); |
132 __ subq(RDI, RSP); | 85 __ subq(RDI, RSP); |
133 // + 1 for Pc marker. | 86 // + 1 for Pc marker. |
(...skipping 2354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2488 | 2441 |
2489 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2442 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2490 UNIMPLEMENTED(); | 2443 UNIMPLEMENTED(); |
2491 } | 2444 } |
2492 | 2445 |
2493 } // namespace dart | 2446 } // namespace dart |
2494 | 2447 |
2495 #undef __ | 2448 #undef __ |
2496 | 2449 |
2497 #endif // defined TARGET_ARCH_X64 | 2450 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |