// 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/code_patcher.h"
#include "vm/compiler.h"
#include "vm/deopt_instructions.h"
#include "vm/flags.h"
#include "vm/object.h"

namespace dart {

DECLARE_FLAG(bool, trace_deoptimization);
DECLARE_FLAG(bool, trace_deoptimization_verbose);


void DeferredDouble::Materialize(DeoptContext* deopt_context) {
  RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
  *double_slot = Double::New(value());

  if (FLAG_trace_deoptimization_verbose) {
    OS::PrintErr("materializing double at %" Px ": %g\n",
                 reinterpret_cast<uword>(slot()), value());
  }
}


void DeferredMint::Materialize(DeoptContext* deopt_context) {
  RawMint** mint_slot = reinterpret_cast<RawMint**>(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<uword>(slot()), value());
  }
}


void DeferredFloat32x4::Materialize(DeoptContext* deopt_context) {
  RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(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<uword>(slot()), x, y, z, w);
  }
}


void DeferredFloat64x2::Materialize(DeoptContext* deopt_context) {
  RawFloat64x2** float64x2_slot = reinterpret_cast<RawFloat64x2**>(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<uword>(slot()), x, y);
  }
}


void DeferredInt32x4::Materialize(DeoptContext* deopt_context) {
  RawInt32x4** int32x4_slot = reinterpret_cast<RawInt32x4**>(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<uword>(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<uword>(slot()));
  }
}


void DeferredRetAddr::Materialize(DeoptContext* deopt_context) {
  Thread* thread = deopt_context->thread();
  Zone* zone = deopt_context->zone();
  Function& function = Function::Handle(zone);
  function ^= deopt_context->ObjectAt(index_);
  const Error& error = Error::Handle(zone,
      Compiler::EnsureUnoptimizedCode(thread, function));
  if (!error.IsNull()) {
    Exceptions::PropagateError(error);
  }
  const Code& code = Code::Handle(zone, function.unoptimized_code());
  // Check that deopt_id exists.
  // TODO(vegorov): verify after deoptimization targets as well.
#ifdef DEBUG
  ASSERT(Thread::IsDeoptAfter(deopt_id_) ||
         (code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kDeopt) != 0));
#endif

  uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
                                              RawPcDescriptors::kDeopt);
  ASSERT(continue_at_pc != 0);
  uword* dest_addr = reinterpret_cast<uword*>(slot());
  *dest_addr = continue_at_pc;

  if (FLAG_trace_deoptimization_verbose) {
    OS::PrintErr("materializing return addr at 0x%" Px ": 0x%" Px "\n",
                 reinterpret_cast<uword>(slot()), continue_at_pc);
  }

  uword pc = code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kIcCall);
  if (pc != 0) {
    // If the deoptimization happened at an IC call, update the IC data
    // to avoid repeated deoptimization at the same site next time around.
    ICData& ic_data = ICData::Handle(zone);
    CodePatcher::GetInstanceCallAt(pc, code, &ic_data);
    if (!ic_data.IsNull()) {
      ic_data.AddDeoptReason(deopt_context->deopt_reason());
      // Propagate the reason to all ICData-s with same deopt_id since
      // only unoptimized-code ICData (IC calls) are propagated.
      function.SetDeoptReasonForAll(ic_data.deopt_id(),
                                    deopt_context->deopt_reason());
    }
  } else {
    if (deopt_context->HasDeoptFlag(ICData::kHoisted)) {
      // Prevent excessive deoptimization.
      function.set_allows_hoisting_check_class(false);
    }

    if (deopt_context->HasDeoptFlag(ICData::kGeneralized)) {
      function.set_allows_bounds_check_generalization(false);
    }
  }
}


void DeferredPcMarker::Materialize(DeoptContext* deopt_context) {
  Thread* thread = deopt_context->thread();
  Zone* zone = deopt_context->zone();
  uword* dest_addr = reinterpret_cast<uword*>(slot());
  Function& function = Function::Handle(zone);
  function ^= deopt_context->ObjectAt(index_);
  ASSERT(!function.IsNull());
  const Error& error = Error::Handle(zone,
      Compiler::EnsureUnoptimizedCode(thread, function));
  if (!error.IsNull()) {
    Exceptions::PropagateError(error);
  }
  const Code& code = Code::Handle(zone, function.unoptimized_code());
  ASSERT(!code.IsNull());
  ASSERT(function.HasCode());
  *reinterpret_cast<RawObject**>(dest_addr) = code.raw();

  if (FLAG_trace_deoptimization_verbose) {
    OS::PrintErr("materializing pc marker at 0x%" Px ": %s, %s\n",
                 reinterpret_cast<uword>(slot()), code.ToCString(),
                 function.ToCString());
  }

  // Increment the deoptimization counter. This effectively increments each
  // function occurring in the optimized frame.
  function.set_deoptimization_counter(function.deoptimization_counter() + 1);
  if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
    OS::PrintErr("Deoptimizing %s (count %d)\n",
        function.ToFullyQualifiedCString(),
        function.deoptimization_counter());
  }
  // Clear invocation counter so that hopefully the function gets reoptimized
  // only after more feedback has been collected.
  function.set_usage_counter(0);
  if (function.HasOptimizedCode()) {
    function.SwitchToUnoptimizedCode();
  }
}


void DeferredPp::Materialize(DeoptContext* deopt_context) {
  Thread* thread = deopt_context->thread();
  Zone* zone = deopt_context->zone();
  Function& function = Function::Handle(zone);
  function ^= deopt_context->ObjectAt(index_);
  ASSERT(!function.IsNull());
  const Error& error = Error::Handle(zone,
      Compiler::EnsureUnoptimizedCode(thread, function));
  if (!error.IsNull()) {
    Exceptions::PropagateError(error);
  }
  const Code& code = Code::Handle(zone, function.unoptimized_code());
  ASSERT(!code.IsNull());
  ASSERT(code.GetObjectPool() != Object::null());
  *slot() = code.GetObjectPool();

  if (FLAG_trace_deoptimization_verbose) {
    OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n",
                 reinterpret_cast<uword>(slot()),
                 reinterpret_cast<uword>(code.GetObjectPool()));
  }
}


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