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

#ifndef RUNTIME_VM_HEAP_BECOME_H_
#define RUNTIME_VM_HEAP_BECOME_H_

#include "platform/atomic.h"
#include "platform/growable_array.h"
#include "vm/allocation.h"
#include "vm/raw_object.h"

namespace dart {

class Array;

// Objects that are a source in a become are transformed into forwarding
// corpses pointing to the corresponding target. Forwarding corpses have the
// same heap sizes as the source object to ensure the heap remains walkable.
// If the heap sizes is small enough to be encoded in the size field of the
// header, a forwarding corpse consists only of a header and the target pointer.
// If the heap size is too big to be encoded in the header's size field, the
// word after the target pointer contains the size.  This is the same
// representation as a FreeListElement.
class ForwardingCorpse {
 public:
  ObjectPtr target() const { return target_; }
  void set_target(ObjectPtr target) { target_ = target; }

  intptr_t HeapSize() { return HeapSize(tags_); }
  intptr_t HeapSize(uword tags) {
    intptr_t size = UntaggedObject::SizeTag::decode(tags);
    if (size != 0) return size;
    return *SizeAddress();
  }

  static ForwardingCorpse* AsForwarder(uword addr, intptr_t size);

  static void Init();

  // Used to allocate class for forwarding corpses in Object::InitOnce.
  class FakeInstance {
   public:
    FakeInstance() {}
    static cpp_vtable vtable() { return 0; }
    static intptr_t InstanceSize() { return 0; }
    static intptr_t NextFieldOffset() { return -kWordSize; }
    static const ClassId kClassId = kForwardingCorpse;
    static bool IsInstance() { return true; }

   private:
    DISALLOW_ALLOCATION();
    DISALLOW_COPY_AND_ASSIGN(FakeInstance);
  };

 private:
  // This layout mirrors the layout of UntaggedObject.
  RelaxedAtomic<uword> tags_;
  RelaxedAtomic<ObjectPtr> target_;

  // Returns the address of the embedded size.
  intptr_t* SizeAddress() const {
    uword addr = reinterpret_cast<uword>(&target_) + kWordSize;
    return reinterpret_cast<intptr_t*>(addr);
  }

  // ForwardingCorpses cannot be allocated. Instead references to them are
  // created using the AsForwarder factory method.
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ForwardingCorpse);
};

// Forward/exchange object identity within pairs of objects.
//
// Forward: Redirects all pointers to each 'before' object to the corresponding
// 'after' object. Every 'before' object is guaranteed to be unreachable after
// the operation. The identity hash of the 'before' object is retained.
//
// This is useful for atomically applying behavior and schema changes, which can
// be done by allocating fresh objects with the new schema and forwarding the
// identity of the old objects to the new objects.
//
// Exchange: Redirect all pointers to each 'before' object to the corresponding
// 'after' object and vice versa. Both objects remain reachable after the
// operation.
//
// This is useful for implementing certain types of proxies. For example, an
// infrequently accessed object may be written to disk and swapped with a
// so-called "husk", and swapped back when it is later accessed.
//
// This operation is named 'become' after its original in Smalltalk:
//   x become: y             "exchange identity for one pair"
//   x becomeForward: y      "forward identity for one pair"
//   #(x ...) elementsExchangeIdentityWith: #(y ...)
//   #(x ...) elementsForwardIdentityTo: #(y ...)
class Become {
 public:
  Become();
  ~Become();

  void Add(const Object& before, const Object& after, const char* whence);
  void Forward();
  void Exchange() { UNIMPLEMENTED(); }

  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Convert and instance object into a dummy object,
  // making the instance independent of its class.
  // (used for morphic instances during reload).
  static void MakeDummyObject(const Instance& instance);

  // Update any references pointing to forwarding objects to point the
  // forwarding objects' targets.
  static void FollowForwardingPointers(Thread* thread);

 private:
  MallocGrowableArray<ObjectPtr> pointers_;
  MallocGrowableArray<const char*> whence_;
  DISALLOW_COPY_AND_ASSIGN(Become);
};

}  // namespace dart

#endif  // RUNTIME_VM_HEAP_BECOME_H_
