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

#include "src/snapshot/default-serializer-allocator.h"

#include "src/heap/heap-inl.h"
#include "src/snapshot/serializer.h"
#include "src/snapshot/snapshot-source-sink.h"

namespace v8 {
namespace internal {

DefaultSerializerAllocator::DefaultSerializerAllocator(
    Serializer<DefaultSerializerAllocator>* serializer)
    : serializer_(serializer) {
  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
    pending_chunk_[i] = 0;
  }
}

SerializerReference DefaultSerializerAllocator::Allocate(AllocationSpace space,
                                                         uint32_t size) {
  DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
  DCHECK(size > 0 && size <= MaxChunkSizeInSpace(space));

  // Maps are allocated through AllocateMap.
  DCHECK_NE(MAP_SPACE, space);

  uint32_t new_chunk_size = pending_chunk_[space] + size;
  if (new_chunk_size > MaxChunkSizeInSpace(space)) {
    // The new chunk size would not fit onto a single page. Complete the
    // current chunk and start a new one.
    serializer_->PutNextChunk(space);
    completed_chunks_[space].push_back(pending_chunk_[space]);
    pending_chunk_[space] = 0;
    new_chunk_size = size;
  }
  uint32_t offset = pending_chunk_[space];
  pending_chunk_[space] = new_chunk_size;
  return SerializerReference::BackReference(
      space, static_cast<uint32_t>(completed_chunks_[space].size()), offset);
}

SerializerReference DefaultSerializerAllocator::AllocateMap() {
  // Maps are allocated one-by-one when deserializing.
  return SerializerReference::MapReference(num_maps_++);
}

SerializerReference DefaultSerializerAllocator::AllocateLargeObject(
    uint32_t size) {
  // Large objects are allocated one-by-one when deserializing. We do not
  // have to keep track of multiple chunks.
  large_objects_total_size_ += size;
  return SerializerReference::LargeObjectReference(seen_large_objects_index_++);
}

SerializerReference DefaultSerializerAllocator::AllocateOffHeapBackingStore() {
  DCHECK_NE(0, seen_backing_stores_index_);
  return SerializerReference::OffHeapBackingStoreReference(
      seen_backing_stores_index_++);
}

#ifdef DEBUG
bool DefaultSerializerAllocator::BackReferenceIsAlreadyAllocated(
    SerializerReference reference) const {
  DCHECK(reference.is_back_reference());
  AllocationSpace space = reference.space();
  if (space == LO_SPACE) {
    return reference.large_object_index() < seen_large_objects_index_;
  } else if (space == MAP_SPACE) {
    return reference.map_index() < num_maps_;
  } else {
    size_t chunk_index = reference.chunk_index();
    if (chunk_index == completed_chunks_[space].size()) {
      return reference.chunk_offset() < pending_chunk_[space];
    } else {
      return chunk_index < completed_chunks_[space].size() &&
             reference.chunk_offset() < completed_chunks_[space][chunk_index];
    }
  }
}

bool DefaultSerializerAllocator::HasNotExceededFirstPageOfEachSpace() const {
  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
    if (!completed_chunks_[i].empty()) return false;
  }
  return true;
}
#endif

std::vector<SerializedData::Reservation>
DefaultSerializerAllocator::EncodeReservations() const {
  std::vector<SerializedData::Reservation> out;

  STATIC_ASSERT(NEW_SPACE == 0);
  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
    for (size_t j = 0; j < completed_chunks_[i].size(); j++) {
      out.emplace_back(completed_chunks_[i][j]);
    }

    if (pending_chunk_[i] > 0 || completed_chunks_[i].size() == 0) {
      out.emplace_back(pending_chunk_[i]);
    }
    out.back().mark_as_last();
  }

  STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
  out.emplace_back(num_maps_ * Map::kSize);
  out.back().mark_as_last();

  STATIC_ASSERT(LO_SPACE == MAP_SPACE + 1);
  out.emplace_back(large_objects_total_size_);
  out.back().mark_as_last();

  return out;
}

void DefaultSerializerAllocator::OutputStatistics() {
  DCHECK(FLAG_serialization_statistics);

  PrintF("  Spaces (bytes):\n");

  STATIC_ASSERT(NEW_SPACE == 0);
  for (int space = 0; space < kNumberOfSpaces; space++) {
    PrintF("%16s", AllocationSpaceName(static_cast<AllocationSpace>(space)));
  }
  PrintF("\n");

  STATIC_ASSERT(NEW_SPACE == 0);
  for (int space = 0; space < kNumberOfPreallocatedSpaces; space++) {
    size_t s = pending_chunk_[space];
    for (uint32_t chunk_size : completed_chunks_[space]) s += chunk_size;
    PrintF("%16" PRIuS, s);
  }

  STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
  PrintF("%16d", num_maps_ * Map::kSize);

  STATIC_ASSERT(LO_SPACE == MAP_SPACE + 1);
  PrintF("%16d\n", large_objects_total_size_);
}

// static
uint32_t DefaultSerializerAllocator::MaxChunkSizeInSpace(int space) {
  DCHECK(0 <= space && space < kNumberOfPreallocatedSpaces);

  return static_cast<uint32_t>(
      MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(space)));
}

}  // namespace internal
}  // namespace v8
