// Copyright 2017 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_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
#define V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_

#include <unordered_set>

#include "src/globals.h"
#include "src/heap/heap.h"
#include "src/interpreter/interpreter.h"
#include "src/snapshot/serializer-common.h"

namespace v8 {
namespace internal {

template <class AllocatorT>
class Deserializer;

class BuiltinDeserializer;
class BuiltinSnapshotUtils;

class BuiltinDeserializerAllocator final {
  using BSU = BuiltinSnapshotUtils;
  using Bytecode = interpreter::Bytecode;
  using OperandScale = interpreter::OperandScale;

 public:
  BuiltinDeserializerAllocator(
      Deserializer<BuiltinDeserializerAllocator>* deserializer);

  ~BuiltinDeserializerAllocator();

  // ------- Allocation Methods -------
  // Methods related to memory allocation during deserialization.

  // Allocation works differently here than in other deserializers. Instead of
  // a statically-known memory area determined at serialization-time, our
  // memory requirements here are determined at runtime. Another major
  // difference is that we create builtin Code objects up-front (before
  // deserialization) in order to avoid having to patch builtin references
  // later on. See also the kBuiltin case in deserializer.cc.
  //
  // There are three ways that we use to reserve / allocate space. In all
  // cases, required objects are requested from the GC prior to
  // deserialization. 1. pre-allocated builtin code objects are written into
  // the builtins table (this is to make deserialization of builtin references
  // easier). Pre-allocated handler code objects are 2. stored in the
  // {handler_allocations_} vector (at eager-deserialization time) and 3.
  // stored in {handler_allocation_} (at lazy-deserialization time).
  //
  // Allocate simply returns the pre-allocated object prepared by
  // InitializeFromReservations.
  Address Allocate(AllocationSpace space, int size);

  void MoveToNextChunk(AllocationSpace space) { UNREACHABLE(); }
  void SetAlignment(AllocationAlignment alignment) { UNREACHABLE(); }

  HeapObject* GetMap(uint32_t index) { UNREACHABLE(); }
  HeapObject* GetLargeObject(uint32_t index) { UNREACHABLE(); }
  HeapObject* GetObject(AllocationSpace space, uint32_t chunk_index,
                        uint32_t chunk_offset) {
    UNREACHABLE();
  }

  // ------- Reservation Methods -------
  // Methods related to memory reservations (prior to deserialization).

  // Builtin deserialization does not bake reservations into the snapshot, hence
  // this is a nop.
  void DecodeReservation(std::vector<SerializedData::Reservation> res) {}

  // These methods are used to pre-allocate builtin objects prior to
  // deserialization.
  // TODO(jgruber): Refactor reservation/allocation logic in deserializers to
  // make this less messy.
  Heap::Reservation CreateReservationsForEagerBuiltinsAndHandlers();
  void InitializeFromReservations(const Heap::Reservation& reservation);

  // Creates reservations and initializes the builtins table in preparation for
  // lazily deserializing a single builtin.
  void ReserveAndInitializeBuiltinsTableForBuiltin(int builtin_id);

  // Pre-allocates a code object preparation for lazily deserializing a single
  // handler.
  void ReserveForHandler(Bytecode bytecode, OperandScale operand_scale);

#ifdef DEBUG
  bool ReservationsAreFullyUsed() const;
#endif

 private:
  Isolate* isolate() const;
  BuiltinDeserializer* deserializer() const;

  // Used after memory allocation prior to isolate initialization, to register
  // the newly created object in code space and add it to the builtins table.
  void InitializeBuiltinFromReservation(const Heap::Chunk& chunk,
                                        int builtin_id);

  // As above, but for interpreter bytecode handlers.
  void InitializeHandlerFromReservation(
      const Heap::Chunk& chunk, interpreter::Bytecode bytecode,
      interpreter::OperandScale operand_scale);

#ifdef DEBUG
  void RegisterCodeObjectReservation(int code_object_id);
  void RegisterCodeObjectAllocation(int code_object_id);
  std::unordered_set<int> unused_reservations_;
#endif

 private:
  // The current deserializer. Note that this always points to a
  // BuiltinDeserializer instance, but we can't perform the cast during
  // construction since that makes vtable-based checks fail.
  Deserializer<BuiltinDeserializerAllocator>* const deserializer_;

  // Stores allocated space for bytecode handlers during eager deserialization.
  std::vector<Address>* handler_allocations_ = nullptr;

  // Stores the allocated space for a single handler during lazy
  // deserialization.
  Address handler_allocation_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(BuiltinDeserializerAllocator)
};

}  // namespace internal
}  // namespace v8

#endif  // V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
