// Copyright 2016 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_ZONE_ZONE_SEGMENT_H_
#define V8_ZONE_ZONE_SEGMENT_H_

#include "src/init/v8.h"

// Segments represent chunks of memory: They have starting address
// (encoded in the this pointer) and a size in bytes. Segments are
// chained together forming a LIFO structure with the newest segment
// available as segment_head_. Segments are allocated using malloc()
// and de-allocated using free().
namespace v8 {
namespace internal {

// Forward declarations.
class AccountingAllocator;
class Zone;

class Segment {
 public:
  Zone* zone() const { return zone_; }
  void set_zone(Zone* const zone) { zone_ = zone; }

  Segment* next() const { return next_; }
  void set_next(Segment* const next) { next_ = next; }

  // {total_size} returns the allocated size including the bookkeeping bytes of
  // the {Segment}.
  size_t total_size() const { return size_; }

  // {capacity} returns the number of storage bytes in this {Segment}, i.e.
  // {end() - start()}.
  size_t capacity() const { return size_ - sizeof(Segment); }

  Address start() const { return address(sizeof(Segment)); }
  Address end() const { return address(size_); }

  // Zap the contents of the segment (but not the header).
  void ZapContents();
  // Zaps the header and makes the segment unusable this way.
  void ZapHeader();

 private:
  // Segments are only created by the AccountingAllocator.
  friend class AccountingAllocator;

  explicit Segment(size_t size) : size_(size) {}

#ifdef DEBUG
  // Constant byte value used for zapping dead memory in debug mode.
  static const unsigned char kZapDeadByte = 0xcd;
#endif

  // Computes the address of the nth byte in this segment.
  Address address(size_t n) const {
    return reinterpret_cast<Address>(this) + n;
  }

  Zone* zone_ = nullptr;
  Segment* next_ = nullptr;
  const size_t size_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_ZONE_ZONE_SEGMENT_H_
