// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #include "vm/deferred_objects.h" #include "vm/deopt_instructions.h" #include "vm/flags.h" #include "vm/object.h" namespace dart { DECLARE_FLAG(bool, trace_deoptimization_verbose); void DeferredDouble::Materialize(DeoptContext* deopt_context) { RawDouble** double_slot = reinterpret_cast(slot()); *double_slot = Double::New(value()); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr("materializing double at %" Px ": %g\n", reinterpret_cast(slot()), value()); } } void DeferredMint::Materialize(DeoptContext* deopt_context) { RawMint** mint_slot = reinterpret_cast(slot()); ASSERT(!Smi::IsValid(value())); Mint& mint = Mint::Handle(); mint ^= Integer::New(value()); *mint_slot = mint.raw(); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n", reinterpret_cast(slot()), value()); } } void DeferredFloat32x4::Materialize(DeoptContext* deopt_context) { RawFloat32x4** float32x4_slot = reinterpret_cast(slot()); RawFloat32x4* raw_float32x4 = Float32x4::New(value()); *float32x4_slot = raw_float32x4; if (FLAG_trace_deoptimization_verbose) { float x = raw_float32x4->x(); float y = raw_float32x4->y(); float z = raw_float32x4->z(); float w = raw_float32x4->w(); OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n", reinterpret_cast(slot()), x, y, z, w); } } void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) { RawFloat64x2** float64x2_slot = reinterpret_cast(slot()); RawFloat64x2* raw_float64x2 = Float64x2::New(value()); *float64x2_slot = raw_float64x2; if (FLAG_trace_deoptimization_verbose) { double x = raw_float64x2->x(); double y = raw_float64x2->y(); OS::PrintErr("materializing Float64x2 at %" Px ": %g,%g\n", reinterpret_cast(slot()), x, y); } } void DeferredInt32x4::Materialize(DeoptContext* deopt_context) { RawInt32x4** int32x4_slot = reinterpret_cast(slot()); RawInt32x4* raw_int32x4 = Int32x4::New(value()); *int32x4_slot = raw_int32x4; if (FLAG_trace_deoptimization_verbose) { uint32_t x = raw_int32x4->x(); uint32_t y = raw_int32x4->y(); uint32_t z = raw_int32x4->z(); uint32_t w = raw_int32x4->w(); OS::PrintErr("materializing Int32x4 at %" Px ": %x,%x,%x,%x\n", reinterpret_cast(slot()), x, y, z, w); } } void DeferredObjectRef::Materialize(DeoptContext* deopt_context) { DeferredObject* obj = deopt_context->GetDeferredObject(index()); *slot() = obj->object(); if (FLAG_trace_deoptimization_verbose) { const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( Object::Handle(obj->object()).GetClassId())); OS::PrintErr("writing instance of class %s ref at %" Px ".\n", cls.ToCString(), reinterpret_cast(slot())); } } RawObject* DeferredObject::object() { if (object_ == NULL) { Create(); } return object_->raw(); } void DeferredObject::Create() { if (object_ != NULL) { return; } Class& cls = Class::Handle(); cls ^= GetClass(); if (cls.raw() == Object::context_class()) { intptr_t num_variables = Smi::Cast(Object::Handle(GetLength())).Value(); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr( "materializing context of length %" Pd " (%" Px ", %" Pd " vars)\n", num_variables, reinterpret_cast(args_), field_count_); } object_ = &Context::ZoneHandle(Context::New(num_variables)); } else { if (FLAG_trace_deoptimization_verbose) { OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n", cls.ToCString(), reinterpret_cast(args_), field_count_); } object_ = &Instance::ZoneHandle(Instance::New(cls)); } } static intptr_t ToContextIndex(intptr_t offset_in_bytes) { intptr_t result = (offset_in_bytes - Context::variable_offset(0)) / kWordSize; ASSERT(result >= 0); return result; } void DeferredObject::Fill() { Create(); // Ensure instance is created. Class& cls = Class::Handle(); cls ^= GetClass(); if (cls.raw() == Object::context_class()) { const Context& context = Context::Cast(*object_); Smi& offset = Smi::Handle(); Object& value = Object::Handle(); for (intptr_t i = 0; i < field_count_; i++) { offset ^= GetFieldOffset(i); if (offset.Value() == Context::parent_offset()) { // Copy parent. Context& parent = Context::Handle(); parent ^= GetValue(i); context.set_parent(parent); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr(" ctx@parent (offset %" Pd ") <- %s\n", offset.Value(), value.ToCString()); } } else { intptr_t context_index = ToContextIndex(offset.Value()); value = GetValue(i); context.SetAt(context_index, value); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr(" ctx@%" Pd " (offset %" Pd ") <- %s\n", context_index, offset.Value(), value.ToCString()); } } } } else { const Instance& obj = Instance::Cast(*object_); Smi& offset = Smi::Handle(); Field& field = Field::Handle(); Object& value = Object::Handle(); const Array& offset_map = Array::Handle(cls.OffsetToFieldMap()); for (intptr_t i = 0; i < field_count_; i++) { offset ^= GetFieldOffset(i); field ^= offset_map.At(offset.Value() / kWordSize); value = GetValue(i); if (!field.IsNull()) { obj.SetField(field, value); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr(" %s <- %s\n", String::Handle(field.name()).ToCString(), value.ToCString()); } } else { ASSERT(cls.IsSignatureClass() || (offset.Value() == cls.type_arguments_field_offset())); obj.SetFieldAtOffset(offset.Value(), value); if (FLAG_trace_deoptimization_verbose) { OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", offset.Value(), value.ToCString()); } } } } } } // namespace dart