// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_PROTOTYPE_INFO_H_
#define V8_OBJECTS_PROTOTYPE_INFO_H_

#include "src/objects.h"
#include "src/objects/fixed-array.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

// Container for metadata stored on each prototype map.
class PrototypeInfo : public Struct {
 public:
  static const int UNREGISTERED = -1;

  // [module_namespace]: A backpointer to JSModuleNamespace from its
  // PrototypeInfo (or undefined). This field is only used for JSModuleNamespace
  // maps.  TODO(jkummerow): Figure out if there's a way to store the namespace
  // pointer elsewhere to save memory.
  DECL_ACCESSORS(module_namespace, Object)

  // [prototype_users]: WeakArrayList containing weak references to maps using
  // this prototype, or Smi(0) if uninitialized.
  DECL_ACCESSORS(prototype_users, Object)

  // [object_create_map]: A field caching the map for Object.create(prototype).
  static inline void SetObjectCreateMap(Handle<PrototypeInfo> info,
                                        Handle<Map> map);
  inline Map* ObjectCreateMap();
  inline bool HasObjectCreateMap();

  // [registry_slot]: Slot in prototype's user registry where this user
  // is stored. Returns UNREGISTERED if this prototype has not been registered.
  inline int registry_slot() const;
  inline void set_registry_slot(int slot);

  // [bit_field]
  inline int bit_field() const;
  inline void set_bit_field(int bit_field);

  DECL_BOOLEAN_ACCESSORS(should_be_fast_map)

  DECL_CAST(PrototypeInfo)

  // Dispatched behavior.
  DECL_PRINTER(PrototypeInfo)
  DECL_VERIFIER(PrototypeInfo)

  static const int kJSModuleNamespaceOffset = HeapObject::kHeaderSize;
  static const int kPrototypeUsersOffset =
      kJSModuleNamespaceOffset + kPointerSize;
  static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
  static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
  static const int kObjectCreateMapOffset = kValidityCellOffset + kPointerSize;
  static const int kBitFieldOffset = kObjectCreateMapOffset + kPointerSize;
  static const int kSize = kBitFieldOffset + kPointerSize;

  // Bit field usage.
  static const int kShouldBeFastBit = 0;

  class BodyDescriptor;

 private:
  DECL_ACCESSORS(object_create_map, MaybeObject)

  DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
};

// A growing array with an additional API for marking slots "empty". When adding
// new elements, we reuse the empty slots instead of growing the array.
class PrototypeUsers : public WeakArrayList {
 public:
  static Handle<WeakArrayList> Add(Isolate* isolate,
                                   Handle<WeakArrayList> array,
                                   Handle<Map> value, int* assigned_index);

  static inline void MarkSlotEmpty(WeakArrayList* array, int index);

  // The callback is called when a weak pointer to HeapObject "object" is moved
  // from index "from_index" to index "to_index" during compaction. The callback
  // must not cause GC.
  typedef void (*CompactionCallback)(HeapObject* object, int from_index,
                                     int to_index);
  static WeakArrayList* Compact(Handle<WeakArrayList> array, Heap* heap,
                                CompactionCallback callback,
                                PretenureFlag pretenure = NOT_TENURED);

#ifdef VERIFY_HEAP
  static void Verify(WeakArrayList* array);
#endif  // VERIFY_HEAP

  static const int kEmptySlotIndex = 0;
  static const int kFirstIndex = 1;

  static const int kNoEmptySlotsMarker = 0;

 private:
  static inline Smi* empty_slot_index(WeakArrayList* array);
  static inline void set_empty_slot_index(WeakArrayList* array, int index);

  static void IsSlotEmpty(WeakArrayList* array, int index);

  DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeUsers);
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_PROTOTYPE_INFO_H_
