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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 __ pushl(value.ToStackSlotAddress()); | 55 __ pushl(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(EAX)); | 66 locs->set_in(0, Location::RegisterLocation(EAX)); |
67 locs->set_temp(0, Location::RegisterLocation(EDX)); | |
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 == EAX); | 76 ASSERT(result == EAX); |
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 __ cmpl(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 == EDX); | |
94 compiler->GenerateCall(0, // no token position. | |
95 &StubCode::OptimizeFunctionLabel(), | |
96 PcDescriptors::kOther, | |
97 locs()); | |
98 __ Bind(&done); | |
99 } | |
100 } else { | |
101 __ LoadObject(func_reg, function); | |
102 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | |
103 if (compiler->CanOptimizeFunction() && | |
104 compiler->parsed_function().function().is_optimizable()) { | |
105 // Do not optimize if usage count must be reported. | |
106 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), | |
107 Immediate(FLAG_optimization_counter_threshold)); | |
108 Label not_yet_hot; | |
109 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); | |
110 // Equal (or greater), optimize. | |
111 // The stub call preserves result register (EAX). | |
112 ASSERT(func_reg == EDX); | |
113 compiler->GenerateCall(0, // no token position. | |
114 &StubCode::OptimizeFunctionLabel(), | |
115 PcDescriptors::kOther, | |
116 locs()); | |
117 __ Bind(¬_yet_hot); | |
118 } | |
119 } | |
120 #if defined(DEBUG) | 77 #if defined(DEBUG) |
121 // TODO(srdjan): Fix for functions with finally clause. | 78 // TODO(srdjan): Fix for functions with finally clause. |
122 // 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 |
123 // has its own return instruction. Method that have finally are currently | 80 // has its own return instruction. Method that have finally are currently |
124 // not optimized. | 81 // not optimized. |
125 if (!compiler->HasFinally()) { | 82 if (!compiler->HasFinally()) { |
126 __ Comment("Stack Check"); | 83 __ Comment("Stack Check"); |
127 Label done; | 84 Label done; |
128 __ movl(EDI, EBP); | 85 __ movl(EDI, EBP); |
129 __ subl(EDI, ESP); | 86 __ subl(EDI, ESP); |
(...skipping 2711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2841 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 2798 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
2842 __ pxor(value, XMM0); | 2799 __ pxor(value, XMM0); |
2843 } | 2800 } |
2844 | 2801 |
2845 | 2802 |
2846 } // namespace dart | 2803 } // namespace dart |
2847 | 2804 |
2848 #undef __ | 2805 #undef __ |
2849 | 2806 |
2850 #endif // defined TARGET_ARCH_X64 | 2807 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |