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" | 7 #include "vm/code_patcher.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/deopt_instructions.h" | 9 #include "vm/deopt_instructions.h" |
10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
11 #include "vm/object.h" | 11 #include "vm/object.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 DECLARE_FLAG(bool, trace_deoptimization); | 15 DECLARE_FLAG(bool, trace_deoptimization); |
16 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 16 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
17 | 17 |
18 | |
19 void DeferredDouble::Materialize(DeoptContext* deopt_context) { | 18 void DeferredDouble::Materialize(DeoptContext* deopt_context) { |
20 RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot()); | 19 RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot()); |
21 *double_slot = Double::New(value()); | 20 *double_slot = Double::New(value()); |
22 | 21 |
23 if (FLAG_trace_deoptimization_verbose) { | 22 if (FLAG_trace_deoptimization_verbose) { |
24 OS::PrintErr("materializing double at %" Px ": %g\n", | 23 OS::PrintErr("materializing double at %" Px ": %g\n", |
25 reinterpret_cast<uword>(slot()), value()); | 24 reinterpret_cast<uword>(slot()), value()); |
26 } | 25 } |
27 } | 26 } |
28 | 27 |
29 | |
30 void DeferredMint::Materialize(DeoptContext* deopt_context) { | 28 void DeferredMint::Materialize(DeoptContext* deopt_context) { |
31 RawMint** mint_slot = reinterpret_cast<RawMint**>(slot()); | 29 RawMint** mint_slot = reinterpret_cast<RawMint**>(slot()); |
32 ASSERT(!Smi::IsValid(value())); | 30 ASSERT(!Smi::IsValid(value())); |
33 Mint& mint = Mint::Handle(); | 31 Mint& mint = Mint::Handle(); |
34 mint ^= Integer::New(value()); | 32 mint ^= Integer::New(value()); |
35 *mint_slot = mint.raw(); | 33 *mint_slot = mint.raw(); |
36 | 34 |
37 if (FLAG_trace_deoptimization_verbose) { | 35 if (FLAG_trace_deoptimization_verbose) { |
38 OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n", | 36 OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n", |
39 reinterpret_cast<uword>(slot()), value()); | 37 reinterpret_cast<uword>(slot()), value()); |
40 } | 38 } |
41 } | 39 } |
42 | 40 |
43 | |
44 void DeferredFloat32x4::Materialize(DeoptContext* deopt_context) { | 41 void DeferredFloat32x4::Materialize(DeoptContext* deopt_context) { |
45 RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot()); | 42 RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot()); |
46 RawFloat32x4* raw_float32x4 = Float32x4::New(value()); | 43 RawFloat32x4* raw_float32x4 = Float32x4::New(value()); |
47 *float32x4_slot = raw_float32x4; | 44 *float32x4_slot = raw_float32x4; |
48 | 45 |
49 if (FLAG_trace_deoptimization_verbose) { | 46 if (FLAG_trace_deoptimization_verbose) { |
50 float x = raw_float32x4->x(); | 47 float x = raw_float32x4->x(); |
51 float y = raw_float32x4->y(); | 48 float y = raw_float32x4->y(); |
52 float z = raw_float32x4->z(); | 49 float z = raw_float32x4->z(); |
53 float w = raw_float32x4->w(); | 50 float w = raw_float32x4->w(); |
54 OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n", | 51 OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n", |
55 reinterpret_cast<uword>(slot()), x, y, z, w); | 52 reinterpret_cast<uword>(slot()), x, y, z, w); |
56 } | 53 } |
57 } | 54 } |
58 | 55 |
59 | |
60 void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) { | 56 void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) { |
61 RawFloat64x2** float64x2_slot = reinterpret_cast<RawFloat64x2**>(slot()); | 57 RawFloat64x2** float64x2_slot = reinterpret_cast<RawFloat64x2**>(slot()); |
62 RawFloat64x2* raw_float64x2 = Float64x2::New(value()); | 58 RawFloat64x2* raw_float64x2 = Float64x2::New(value()); |
63 *float64x2_slot = raw_float64x2; | 59 *float64x2_slot = raw_float64x2; |
64 | 60 |
65 if (FLAG_trace_deoptimization_verbose) { | 61 if (FLAG_trace_deoptimization_verbose) { |
66 double x = raw_float64x2->x(); | 62 double x = raw_float64x2->x(); |
67 double y = raw_float64x2->y(); | 63 double y = raw_float64x2->y(); |
68 OS::PrintErr("materializing Float64x2 at %" Px ": %g,%g\n", | 64 OS::PrintErr("materializing Float64x2 at %" Px ": %g,%g\n", |
69 reinterpret_cast<uword>(slot()), x, y); | 65 reinterpret_cast<uword>(slot()), x, y); |
70 } | 66 } |
71 } | 67 } |
72 | 68 |
73 | |
74 void DeferredInt32x4::Materialize(DeoptContext* deopt_context) { | 69 void DeferredInt32x4::Materialize(DeoptContext* deopt_context) { |
75 RawInt32x4** int32x4_slot = reinterpret_cast<RawInt32x4**>(slot()); | 70 RawInt32x4** int32x4_slot = reinterpret_cast<RawInt32x4**>(slot()); |
76 RawInt32x4* raw_int32x4 = Int32x4::New(value()); | 71 RawInt32x4* raw_int32x4 = Int32x4::New(value()); |
77 *int32x4_slot = raw_int32x4; | 72 *int32x4_slot = raw_int32x4; |
78 | 73 |
79 if (FLAG_trace_deoptimization_verbose) { | 74 if (FLAG_trace_deoptimization_verbose) { |
80 uint32_t x = raw_int32x4->x(); | 75 uint32_t x = raw_int32x4->x(); |
81 uint32_t y = raw_int32x4->y(); | 76 uint32_t y = raw_int32x4->y(); |
82 uint32_t z = raw_int32x4->z(); | 77 uint32_t z = raw_int32x4->z(); |
83 uint32_t w = raw_int32x4->w(); | 78 uint32_t w = raw_int32x4->w(); |
84 OS::PrintErr("materializing Int32x4 at %" Px ": %x,%x,%x,%x\n", | 79 OS::PrintErr("materializing Int32x4 at %" Px ": %x,%x,%x,%x\n", |
85 reinterpret_cast<uword>(slot()), x, y, z, w); | 80 reinterpret_cast<uword>(slot()), x, y, z, w); |
86 } | 81 } |
87 } | 82 } |
88 | 83 |
89 | |
90 void DeferredObjectRef::Materialize(DeoptContext* deopt_context) { | 84 void DeferredObjectRef::Materialize(DeoptContext* deopt_context) { |
91 DeferredObject* obj = deopt_context->GetDeferredObject(index()); | 85 DeferredObject* obj = deopt_context->GetDeferredObject(index()); |
92 *slot() = obj->object(); | 86 *slot() = obj->object(); |
93 if (FLAG_trace_deoptimization_verbose) { | 87 if (FLAG_trace_deoptimization_verbose) { |
94 const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( | 88 const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( |
95 Object::Handle(obj->object()).GetClassId())); | 89 Object::Handle(obj->object()).GetClassId())); |
96 OS::PrintErr("writing instance of class %s ref at %" Px ".\n", | 90 OS::PrintErr("writing instance of class %s ref at %" Px ".\n", |
97 cls.ToCString(), reinterpret_cast<uword>(slot())); | 91 cls.ToCString(), reinterpret_cast<uword>(slot())); |
98 } | 92 } |
99 } | 93 } |
100 | 94 |
101 | |
102 void DeferredRetAddr::Materialize(DeoptContext* deopt_context) { | 95 void DeferredRetAddr::Materialize(DeoptContext* deopt_context) { |
103 Thread* thread = deopt_context->thread(); | 96 Thread* thread = deopt_context->thread(); |
104 Zone* zone = deopt_context->zone(); | 97 Zone* zone = deopt_context->zone(); |
105 Function& function = Function::Handle(zone); | 98 Function& function = Function::Handle(zone); |
106 function ^= deopt_context->ObjectAt(index_); | 99 function ^= deopt_context->ObjectAt(index_); |
107 const Error& error = | 100 const Error& error = |
108 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); | 101 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); |
109 if (!error.IsNull()) { | 102 if (!error.IsNull()) { |
110 Exceptions::PropagateError(error); | 103 Exceptions::PropagateError(error); |
111 } | 104 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 // Prevent excessive deoptimization. | 139 // Prevent excessive deoptimization. |
147 function.set_allows_hoisting_check_class(false); | 140 function.set_allows_hoisting_check_class(false); |
148 } | 141 } |
149 | 142 |
150 if (deopt_context->HasDeoptFlag(ICData::kGeneralized)) { | 143 if (deopt_context->HasDeoptFlag(ICData::kGeneralized)) { |
151 function.set_allows_bounds_check_generalization(false); | 144 function.set_allows_bounds_check_generalization(false); |
152 } | 145 } |
153 } | 146 } |
154 } | 147 } |
155 | 148 |
156 | |
157 void DeferredPcMarker::Materialize(DeoptContext* deopt_context) { | 149 void DeferredPcMarker::Materialize(DeoptContext* deopt_context) { |
158 Thread* thread = deopt_context->thread(); | 150 Thread* thread = deopt_context->thread(); |
159 Zone* zone = deopt_context->zone(); | 151 Zone* zone = deopt_context->zone(); |
160 uword* dest_addr = reinterpret_cast<uword*>(slot()); | 152 uword* dest_addr = reinterpret_cast<uword*>(slot()); |
161 Function& function = Function::Handle(zone); | 153 Function& function = Function::Handle(zone); |
162 function ^= deopt_context->ObjectAt(index_); | 154 function ^= deopt_context->ObjectAt(index_); |
163 ASSERT(!function.IsNull()); | 155 ASSERT(!function.IsNull()); |
164 const Error& error = | 156 const Error& error = |
165 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); | 157 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); |
166 if (!error.IsNull()) { | 158 if (!error.IsNull()) { |
(...skipping 21 matching lines...) Expand all Loading... |
188 function.deoptimization_counter()); | 180 function.deoptimization_counter()); |
189 } | 181 } |
190 // Clear invocation counter so that hopefully the function gets reoptimized | 182 // Clear invocation counter so that hopefully the function gets reoptimized |
191 // only after more feedback has been collected. | 183 // only after more feedback has been collected. |
192 function.set_usage_counter(0); | 184 function.set_usage_counter(0); |
193 if (function.HasOptimizedCode()) { | 185 if (function.HasOptimizedCode()) { |
194 function.SwitchToUnoptimizedCode(); | 186 function.SwitchToUnoptimizedCode(); |
195 } | 187 } |
196 } | 188 } |
197 | 189 |
198 | |
199 void DeferredPp::Materialize(DeoptContext* deopt_context) { | 190 void DeferredPp::Materialize(DeoptContext* deopt_context) { |
200 Thread* thread = deopt_context->thread(); | 191 Thread* thread = deopt_context->thread(); |
201 Zone* zone = deopt_context->zone(); | 192 Zone* zone = deopt_context->zone(); |
202 Function& function = Function::Handle(zone); | 193 Function& function = Function::Handle(zone); |
203 function ^= deopt_context->ObjectAt(index_); | 194 function ^= deopt_context->ObjectAt(index_); |
204 ASSERT(!function.IsNull()); | 195 ASSERT(!function.IsNull()); |
205 const Error& error = | 196 const Error& error = |
206 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); | 197 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); |
207 if (!error.IsNull()) { | 198 if (!error.IsNull()) { |
208 Exceptions::PropagateError(error); | 199 Exceptions::PropagateError(error); |
209 } | 200 } |
210 const Code& code = Code::Handle(zone, function.unoptimized_code()); | 201 const Code& code = Code::Handle(zone, function.unoptimized_code()); |
211 ASSERT(!code.IsNull()); | 202 ASSERT(!code.IsNull()); |
212 ASSERT(code.GetObjectPool() != Object::null()); | 203 ASSERT(code.GetObjectPool() != Object::null()); |
213 *slot() = code.GetObjectPool(); | 204 *slot() = code.GetObjectPool(); |
214 | 205 |
215 if (FLAG_trace_deoptimization_verbose) { | 206 if (FLAG_trace_deoptimization_verbose) { |
216 OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n", | 207 OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n", |
217 reinterpret_cast<uword>(slot()), | 208 reinterpret_cast<uword>(slot()), |
218 reinterpret_cast<uword>(code.GetObjectPool())); | 209 reinterpret_cast<uword>(code.GetObjectPool())); |
219 } | 210 } |
220 } | 211 } |
221 | 212 |
222 | |
223 RawObject* DeferredObject::object() { | 213 RawObject* DeferredObject::object() { |
224 if (object_ == NULL) { | 214 if (object_ == NULL) { |
225 Create(); | 215 Create(); |
226 } | 216 } |
227 return object_->raw(); | 217 return object_->raw(); |
228 } | 218 } |
229 | 219 |
230 | |
231 void DeferredObject::Create() { | 220 void DeferredObject::Create() { |
232 if (object_ != NULL) { | 221 if (object_ != NULL) { |
233 return; | 222 return; |
234 } | 223 } |
235 | 224 |
236 Class& cls = Class::Handle(); | 225 Class& cls = Class::Handle(); |
237 cls ^= GetClass(); | 226 cls ^= GetClass(); |
238 | 227 |
239 if (cls.raw() == Object::context_class()) { | 228 if (cls.raw() == Object::context_class()) { |
240 intptr_t num_variables = Smi::Cast(Object::Handle(GetLength())).Value(); | 229 intptr_t num_variables = Smi::Cast(Object::Handle(GetLength())).Value(); |
241 if (FLAG_trace_deoptimization_verbose) { | 230 if (FLAG_trace_deoptimization_verbose) { |
242 OS::PrintErr("materializing context of length %" Pd " (%" Px ", %" Pd | 231 OS::PrintErr("materializing context of length %" Pd " (%" Px ", %" Pd |
243 " vars)\n", | 232 " vars)\n", |
244 num_variables, reinterpret_cast<uword>(args_), field_count_); | 233 num_variables, reinterpret_cast<uword>(args_), field_count_); |
245 } | 234 } |
246 object_ = &Context::ZoneHandle(Context::New(num_variables)); | 235 object_ = &Context::ZoneHandle(Context::New(num_variables)); |
247 | 236 |
248 } else { | 237 } else { |
249 if (FLAG_trace_deoptimization_verbose) { | 238 if (FLAG_trace_deoptimization_verbose) { |
250 OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n", | 239 OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n", |
251 cls.ToCString(), reinterpret_cast<uword>(args_), | 240 cls.ToCString(), reinterpret_cast<uword>(args_), |
252 field_count_); | 241 field_count_); |
253 } | 242 } |
254 | 243 |
255 object_ = &Instance::ZoneHandle(Instance::New(cls)); | 244 object_ = &Instance::ZoneHandle(Instance::New(cls)); |
256 } | 245 } |
257 } | 246 } |
258 | 247 |
259 | |
260 static intptr_t ToContextIndex(intptr_t offset_in_bytes) { | 248 static intptr_t ToContextIndex(intptr_t offset_in_bytes) { |
261 intptr_t result = (offset_in_bytes - Context::variable_offset(0)) / kWordSize; | 249 intptr_t result = (offset_in_bytes - Context::variable_offset(0)) / kWordSize; |
262 ASSERT(result >= 0); | 250 ASSERT(result >= 0); |
263 return result; | 251 return result; |
264 } | 252 } |
265 | 253 |
266 | |
267 void DeferredObject::Fill() { | 254 void DeferredObject::Fill() { |
268 Create(); // Ensure instance is created. | 255 Create(); // Ensure instance is created. |
269 | 256 |
270 Class& cls = Class::Handle(); | 257 Class& cls = Class::Handle(); |
271 cls ^= GetClass(); | 258 cls ^= GetClass(); |
272 | 259 |
273 if (cls.raw() == Object::context_class()) { | 260 if (cls.raw() == Object::context_class()) { |
274 const Context& context = Context::Cast(*object_); | 261 const Context& context = Context::Cast(*object_); |
275 | 262 |
276 Smi& offset = Smi::Handle(); | 263 Smi& offset = Smi::Handle(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 if (FLAG_trace_deoptimization_verbose) { | 309 if (FLAG_trace_deoptimization_verbose) { |
323 OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", | 310 OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", |
324 offset.Value(), value.ToCString()); | 311 offset.Value(), value.ToCString()); |
325 } | 312 } |
326 } | 313 } |
327 } | 314 } |
328 } | 315 } |
329 } | 316 } |
330 | 317 |
331 } // namespace dart | 318 } // namespace dart |
OLD | NEW |