| 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 |