// Copyright (c) 2016, 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/become.h"

#include "platform/assert.h"
#include "platform/utils.h"

#include "vm/dart_api_state.h"
#include "vm/isolate_reload.h"
#include "vm/object.h"
#include "vm/raw_object.h"
#include "vm/safepoint.h"
#include "vm/timeline.h"
#include "vm/visitor.h"

namespace dart {

ForwardingCorpse* ForwardingCorpse::AsForwarder(uword addr, intptr_t size) {
  ASSERT(size >= kObjectAlignment);
  ASSERT(Utils::IsAligned(size, kObjectAlignment));

  ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr);

  uword tags = 0;
  tags = RawObject::SizeTag::update(size, tags);
  tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags);

  result->tags_ = tags;
  if (size > RawObject::SizeTag::kMaxSizeTag) {
    *result->SizeAddress() = size;
  }
  result->set_target(Object::null());
  return result;
}


void ForwardingCorpse::InitOnce() {
  ASSERT(sizeof(ForwardingCorpse) == kObjectAlignment);
  ASSERT(OFFSET_OF(ForwardingCorpse, tags_) == Object::tags_offset());
}


// Free list elements are used as a marker for forwarding objects. This is
// safe because we cannot reach free list elements from live objects. Ideally
// forwarding objects would have their own class id. See TODO below.
static bool IsForwardingObject(RawObject* object) {
  return object->IsHeapObject() && object->IsForwardingCorpse();
}


static RawObject* GetForwardedObject(RawObject* object) {
  ASSERT(IsForwardingObject(object));
  uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag;
  ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
  return forwarder->target();
}


static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
  const intptr_t size_before = before_obj->Size();

  uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
  ForwardingCorpse* forwarder =
      ForwardingCorpse::AsForwarder(corpse_addr, size_before);
  forwarder->set_target(after_obj);
  if (!IsForwardingObject(before_obj)) {
    FATAL("become: ForwardObjectTo failure.");
  }
  // Still need to be able to iterate over the forwarding corpse.
  const intptr_t size_after = before_obj->Size();
  if (size_before != size_after) {
    FATAL("become: Before and after sizes do not match.");
  }
}


class ForwardPointersVisitor : public ObjectPointerVisitor {
 public:
  explicit ForwardPointersVisitor(Isolate* isolate)
      : ObjectPointerVisitor(isolate), visiting_object_(NULL), count_(0) {}

  virtual void VisitPointers(RawObject** first, RawObject** last) {
    for (RawObject** p = first; p <= last; p++) {
      RawObject* old_target = *p;
      if (IsForwardingObject(old_target)) {
        RawObject* new_target = GetForwardedObject(old_target);
        if (visiting_object_ == NULL) {
          *p = new_target;
        } else {
          visiting_object_->StorePointer(p, new_target);
        }
        count_++;
      }
    }
  }

  void VisitingObject(RawObject* obj) { visiting_object_ = obj; }

  intptr_t count() const { return count_; }

 private:
  RawObject* visiting_object_;
  intptr_t count_;

  DISALLOW_COPY_AND_ASSIGN(ForwardPointersVisitor);
};


class ForwardHeapPointersVisitor : public ObjectVisitor {
 public:
  explicit ForwardHeapPointersVisitor(ForwardPointersVisitor* pointer_visitor)
      : pointer_visitor_(pointer_visitor) {}

  virtual void VisitObject(RawObject* obj) {
    pointer_visitor_->VisitingObject(obj);
    obj->VisitPointers(pointer_visitor_);
  }

 private:
  ForwardPointersVisitor* pointer_visitor_;

  DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersVisitor);
};


class ForwardHeapPointersHandleVisitor : public HandleVisitor {
 public:
  ForwardHeapPointersHandleVisitor()
      : HandleVisitor(Thread::Current()), count_(0) {}

  virtual void VisitHandle(uword addr) {
    FinalizablePersistentHandle* handle =
        reinterpret_cast<FinalizablePersistentHandle*>(addr);
    if (IsForwardingObject(handle->raw())) {
      *handle->raw_addr() = GetForwardedObject(handle->raw());
      count_++;
    }
  }

  intptr_t count() const { return count_; }

 private:
  int count_;

  DISALLOW_COPY_AND_ASSIGN(ForwardHeapPointersHandleVisitor);
};


// On IA32, object pointers are embedded directly in the instruction stream,
// which is normally write-protected, so we need to make it temporarily writable
// to forward the pointers. On all other architectures, object pointers are
// accessed through ObjectPools.
#if defined(TARGET_ARCH_IA32)
class WritableCodeLiteralsScope : public ValueObject {
 public:
  explicit WritableCodeLiteralsScope(Heap* heap) : heap_(heap) {
    if (FLAG_write_protect_code) {
      heap_->WriteProtectCode(false);
    }
  }

  ~WritableCodeLiteralsScope() {
    if (FLAG_write_protect_code) {
      heap_->WriteProtectCode(true);
    }
  }

 private:
  Heap* heap_;
};
#else
class WritableCodeLiteralsScope : public ValueObject {
 public:
  explicit WritableCodeLiteralsScope(Heap* heap) {}
  ~WritableCodeLiteralsScope() {}
};
#endif


void Become::MakeDummyObject(const Instance& instance) {
  // Make the forward pointer point to itself.
  // This is needed to distinguish it from a real forward object.
  ForwardObjectTo(instance.raw(), instance.raw());
}


static bool IsDummyObject(RawObject* object) {
  if (!object->IsForwardingCorpse()) return false;
  return GetForwardedObject(object) == object;
}


void Become::CrashDump(RawObject* before_obj, RawObject* after_obj) {
  OS::PrintErr("DETECTED FATAL ISSUE IN BECOME MAPPINGS\n");

  OS::PrintErr("BEFORE ADDRESS: %p\n", before_obj);
  OS::PrintErr("BEFORE IS HEAP OBJECT: %s",
               before_obj->IsHeapObject() ? "YES" : "NO");
  OS::PrintErr("BEFORE IS VM HEAP OBJECT: %s",
               before_obj->IsVMHeapObject() ? "YES" : "NO");

  OS::PrintErr("AFTER ADDRESS: %p\n", after_obj);
  OS::PrintErr("AFTER IS HEAP OBJECT: %s",
               after_obj->IsHeapObject() ? "YES" : "NO");
  OS::PrintErr("AFTER IS VM HEAP OBJECT: %s",
               after_obj->IsVMHeapObject() ? "YES" : "NO");

  if (before_obj->IsHeapObject()) {
    OS::PrintErr("BEFORE OBJECT CLASS ID=%" Pd "\n", before_obj->GetClassId());
    const Object& obj = Object::Handle(before_obj);
    OS::PrintErr("BEFORE OBJECT AS STRING=%s\n", obj.ToCString());
  }

  if (after_obj->IsHeapObject()) {
    OS::PrintErr("AFTER OBJECT CLASS ID=%" Pd "\n", after_obj->GetClassId());
    const Object& obj = Object::Handle(after_obj);
    OS::PrintErr("AFTER OBJECT AS STRING=%s\n", obj.ToCString());
  }
}


void Become::ElementsForwardIdentity(const Array& before, const Array& after) {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  Heap* heap = isolate->heap();

  TIMELINE_FUNCTION_GC_DURATION(thread, "Become::ElementsForwardIdentity");
  HeapIterationScope his;

  // Setup forwarding pointers.
  ASSERT(before.Length() == after.Length());
  for (intptr_t i = 0; i < before.Length(); i++) {
    RawObject* before_obj = before.At(i);
    RawObject* after_obj = after.At(i);

    if (before_obj == after_obj) {
      FATAL("become: Cannot self-forward");
    }
    if (!before_obj->IsHeapObject()) {
      CrashDump(before_obj, after_obj);
      FATAL("become: Cannot forward immediates");
    }
    if (!after_obj->IsHeapObject()) {
      CrashDump(before_obj, after_obj);
      FATAL("become: Cannot become immediates");
    }
    if (before_obj->IsVMHeapObject()) {
      CrashDump(before_obj, after_obj);
      FATAL("become: Cannot forward VM heap objects");
    }
    if (before_obj->IsForwardingCorpse() && !IsDummyObject(before_obj)) {
      FATAL("become: Cannot forward to multiple targets");
    }
    if (after_obj->IsForwardingCorpse()) {
      // The Smalltalk become does allow this, and for very special cases
      // it is important (shape changes to Class or Mixin), but as these
      // cases do not arise in Dart, better to prohibit it.
      FATAL("become: No indirect chains of forwarding");
    }

    ForwardObjectTo(before_obj, after_obj);

    // Forward the identity hash too if it has one.
    intptr_t hash = heap->GetHash(before_obj);
    if (hash != 0) {
      ASSERT(heap->GetHash(after_obj) == 0);
      heap->SetHash(after_obj, hash);
    }
  }

  {
    // Follow forwarding pointers.

    // C++ pointers
    ForwardPointersVisitor pointer_visitor(isolate);
    isolate->VisitObjectPointers(&pointer_visitor, true);

    // Weak persistent handles.
    ForwardHeapPointersHandleVisitor handle_visitor;
    isolate->VisitWeakPersistentHandles(&handle_visitor);

    //   Heap pointers (may require updating the remembered set)
    {
      WritableCodeLiteralsScope writable_code(heap);
      ForwardHeapPointersVisitor object_visitor(&pointer_visitor);
      heap->VisitObjects(&object_visitor);
      pointer_visitor.VisitingObject(NULL);
    }

#if !defined(PRODUCT)
    tds.SetNumArguments(2);
    tds.FormatArgument(0, "Remapped objects", "%" Pd, before.Length());
    tds.FormatArgument(1, "Remapped references", "%" Pd,
                       pointer_visitor.count() + handle_visitor.count());
#endif
  }

#if defined(DEBUG)
  for (intptr_t i = 0; i < before.Length(); i++) {
    ASSERT(before.At(i) == after.At(i));
  }
#endif
}

}  // namespace dart
