OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/deferred_objects.h" | 5 #include "vm/deferred_objects.h" |
6 | 6 |
7 #include "vm/code_patcher.h" | |
8 #include "vm/compiler.h" | |
7 #include "vm/deopt_instructions.h" | 9 #include "vm/deopt_instructions.h" |
8 #include "vm/flags.h" | 10 #include "vm/flags.h" |
9 #include "vm/object.h" | 11 #include "vm/object.h" |
10 | 12 |
11 namespace dart { | 13 namespace dart { |
12 | 14 |
13 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 15 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
16 DECLARE_FLAG(bool, trace_deoptimization); | |
srdjan
2015/04/02 17:43:40
Reorder alphabetically.
Florian Schneider
2015/04/07 09:07:57
Done.
| |
14 | 17 |
15 | 18 |
16 void DeferredDouble::Materialize(DeoptContext* deopt_context) { | 19 void DeferredDouble::Materialize(DeoptContext* deopt_context) { |
17 RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot()); | 20 RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot()); |
18 *double_slot = Double::New(value()); | 21 *double_slot = Double::New(value()); |
19 | 22 |
20 if (FLAG_trace_deoptimization_verbose) { | 23 if (FLAG_trace_deoptimization_verbose) { |
21 OS::PrintErr("materializing double at %" Px ": %g\n", | 24 OS::PrintErr("materializing double at %" Px ": %g\n", |
22 reinterpret_cast<uword>(slot()), value()); | 25 reinterpret_cast<uword>(slot()), value()); |
23 } | 26 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 if (FLAG_trace_deoptimization_verbose) { | 93 if (FLAG_trace_deoptimization_verbose) { |
91 const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( | 94 const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( |
92 Object::Handle(obj->object()).GetClassId())); | 95 Object::Handle(obj->object()).GetClassId())); |
93 OS::PrintErr("writing instance of class %s ref at %" Px ".\n", | 96 OS::PrintErr("writing instance of class %s ref at %" Px ".\n", |
94 cls.ToCString(), | 97 cls.ToCString(), |
95 reinterpret_cast<uword>(slot())); | 98 reinterpret_cast<uword>(slot())); |
96 } | 99 } |
97 } | 100 } |
98 | 101 |
99 | 102 |
103 void DeferredRetAddr::Materialize(DeoptContext* deopt_context) { | |
104 Function& function = Function::Handle(deopt_context->zone()); | |
105 function ^= deopt_context->ObjectAt(index_); | |
106 Compiler::EnsureUnoptimizedCode(deopt_context->thread(), function); | |
107 const Code& code = | |
108 Code::Handle(deopt_context->zone(), function.unoptimized_code()); | |
109 // Check that deopt_id exists. | |
110 // TODO(vegorov): verify after deoptimization targets as well. | |
111 #ifdef DEBUG | |
112 ASSERT(Isolate::IsDeoptAfter(deopt_id_) || | |
113 (code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kDeopt) != 0)); | |
114 #endif | |
115 | |
116 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, | |
117 RawPcDescriptors::kDeopt); | |
118 ASSERT(continue_at_pc != 0); | |
119 uword* dest_addr = reinterpret_cast<uword*>(slot()); | |
120 *dest_addr = continue_at_pc; | |
121 | |
122 if (FLAG_trace_deoptimization_verbose) { | |
123 OS::PrintErr("materializing return addr at 0x%" Px ": 0x%" Px "\n", | |
124 reinterpret_cast<uword>(slot()), continue_at_pc); | |
125 } | |
126 | |
127 uword pc = code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kIcCall); | |
128 if (pc != 0) { | |
129 // If the deoptimization happened at an IC call, update the IC data | |
130 // to avoid repeated deoptimization at the same site next time around. | |
131 ICData& ic_data = ICData::Handle(); | |
132 CodePatcher::GetInstanceCallAt(pc, code, &ic_data); | |
133 if (!ic_data.IsNull()) { | |
134 ic_data.AddDeoptReason(deopt_context->deopt_reason()); | |
135 } | |
136 } else { | |
137 if (deopt_context->HasDeoptFlag(ICData::kHoisted)) { | |
138 // Prevent excessive deoptimization. | |
139 function.set_allows_hoisting_check_class(false); | |
140 } | |
141 | |
142 if (deopt_context->HasDeoptFlag(ICData::kGeneralized)) { | |
143 function.set_allows_bounds_check_generalization(false); | |
144 } | |
145 } | |
146 } | |
147 | |
148 | |
149 void DeferredPcMarker::Materialize(DeoptContext* deopt_context) { | |
150 uword* dest_addr = reinterpret_cast<uword*>(slot()); | |
151 Function& function = Function::Handle(deopt_context->zone()); | |
152 function ^= deopt_context->ObjectAt(index_); | |
153 if (function.IsNull()) { | |
154 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. | |
155 *dest_addr = 0; | |
156 return; | |
157 } | |
158 Compiler::EnsureUnoptimizedCode(deopt_context->thread(), function); | |
159 const Code& code = | |
160 Code::Handle(deopt_context->zone(), function.unoptimized_code()); | |
161 ASSERT(!code.IsNull()); | |
162 ASSERT(function.HasCode()); | |
163 const intptr_t pc_marker = | |
164 code.EntryPoint() + Assembler::EntryPointToPcMarkerOffset(); | |
165 *dest_addr = pc_marker; | |
166 | |
167 if (FLAG_trace_deoptimization_verbose) { | |
168 OS::PrintErr("materializing pc marker at 0x%" Px ": %s, %s\n", | |
169 reinterpret_cast<uword>(slot()), code.ToCString(), | |
170 function.ToCString()); | |
171 } | |
172 | |
173 // Increment the deoptimization counter. This effectively increments each | |
174 // function occurring in the optimized frame. | |
175 function.set_deoptimization_counter(function.deoptimization_counter() + 1); | |
176 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { | |
177 OS::PrintErr("Deoptimizing %s (count %d)\n", | |
178 function.ToFullyQualifiedCString(), | |
179 function.deoptimization_counter()); | |
180 } | |
181 // Clear invocation counter so that hopefully the function gets reoptimized | |
182 // only after more feedback has been collected. | |
183 function.set_usage_counter(0); | |
184 if (function.HasOptimizedCode()) { | |
185 function.SwitchToUnoptimizedCode(); | |
186 } | |
187 } | |
188 | |
189 | |
190 void DeferredPp::Materialize(DeoptContext* deopt_context) { | |
191 Function& function = Function::Handle(deopt_context->zone()); | |
192 function ^= deopt_context->ObjectAt(index_); | |
193 ASSERT(!function.IsNull()); | |
194 const Code& code = | |
195 Code::Handle(deopt_context->zone(), function.unoptimized_code()); | |
Ivan Posva
2015/04/02 17:14:00
Please add "Compiler::EnsureUnoptimizedCode(deopt_
Florian Schneider
2015/04/07 09:07:57
Good point. Done.
| |
196 ASSERT(!code.IsNull()); | |
197 ASSERT(code.ObjectPool() != Object::null()); | |
198 *slot() = code.ObjectPool(); | |
199 | |
200 if (FLAG_trace_deoptimization_verbose) { | |
201 OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n", | |
202 reinterpret_cast<uword>(slot()), | |
203 reinterpret_cast<uword>(code.ObjectPool())); | |
204 } | |
205 } | |
206 | |
207 | |
100 RawObject* DeferredObject::object() { | 208 RawObject* DeferredObject::object() { |
101 if (object_ == NULL) { | 209 if (object_ == NULL) { |
102 Create(); | 210 Create(); |
103 } | 211 } |
104 return object_->raw(); | 212 return object_->raw(); |
105 } | 213 } |
106 | 214 |
107 | 215 |
108 void DeferredObject::Create() { | 216 void DeferredObject::Create() { |
109 if (object_ != NULL) { | 217 if (object_ != NULL) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", | 315 OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", |
208 offset.Value(), | 316 offset.Value(), |
209 value.ToCString()); | 317 value.ToCString()); |
210 } | 318 } |
211 } | 319 } |
212 } | 320 } |
213 } | 321 } |
214 } | 322 } |
215 | 323 |
216 } // namespace dart | 324 } // namespace dart |
OLD | NEW |