// Copyright 2019 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_CODEGEN_CODE_DESC_H_
#define V8_CODEGEN_CODE_DESC_H_

#include "src/common/globals.h"

namespace v8 {
namespace internal {

// A CodeDesc describes a buffer holding instructions and relocation
// information. The instructions start at the beginning of the buffer
// and grow forward, the relocation information starts at the end of
// the buffer and grows backward. Inlined metadata sections may exist
// at the end of the instructions.
//
//  |<--------------- buffer_size ----------------------------------->|
//  |<---------------- instr_size ------------->|      |<-reloc_size->|
//  |--------------+----------------------------+------+--------------|
//  | instructions |         data               | free |  reloc info  |
//  +--------------+----------------------------+------+--------------+

// TODO(jgruber): Add a single chokepoint for specifying the instruction area
// layout (i.e. the order of inlined metadata fields).
// TODO(jgruber): Systematically maintain inlined metadata offsets and sizes
// to simplify CodeDesc initialization.

class CodeDesc {
 public:
  static void Initialize(CodeDesc* desc, Assembler* assembler,
                         int safepoint_table_offset, int handler_table_offset,
                         int constant_pool_offset, int code_comments_offset,
                         int reloc_info_offset);

#ifdef DEBUG
  static void Verify(const CodeDesc* desc);
#else
  inline static void Verify(const CodeDesc* desc) {}
#endif

 public:
  byte* buffer = nullptr;
  int buffer_size = 0;

  // The instruction area contains executable code plus inlined metadata.

  int instr_size = 0;

  // Metadata packed into the instructions area.

  int safepoint_table_offset = 0;
  int safepoint_table_size = 0;

  int handler_table_offset = 0;
  int handler_table_size = 0;

  int constant_pool_offset = 0;
  int constant_pool_size = 0;

  int code_comments_offset = 0;
  int code_comments_size = 0;

  // TODO(jgruber,v8:11036): Remove these functions once CodeDesc fields have
  // been made consistent with Code layout.
  int body_size() const { return instr_size + unwinding_info_size; }
  int instruction_size() const { return safepoint_table_offset; }
  int metadata_size() const { return body_size() - instruction_size(); }
  int safepoint_table_offset_relative() const {
    return safepoint_table_offset - instruction_size();
  }
  int handler_table_offset_relative() const {
    return handler_table_offset - instruction_size();
  }
  int constant_pool_offset_relative() const {
    return constant_pool_offset - instruction_size();
  }
  int code_comments_offset_relative() const {
    return code_comments_offset - instruction_size();
  }

  // Relocation info is located at the end of the buffer and not part of the
  // instructions area.

  int reloc_offset = 0;
  int reloc_size = 0;

  // Unwinding information.

  byte* unwinding_info = nullptr;
  int unwinding_info_size = 0;
  int unwinding_info_offset_relative() const {
    // TODO(jgruber,v8:11036): Remove this function once unwinding_info setup
    // is more consistent with other metadata tables.
    return code_comments_offset_relative() + code_comments_size;
  }

  Assembler* origin = nullptr;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_CODEGEN_CODE_DESC_H_
