// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
#define RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/object.h"

namespace dart {

class ClassTable;
class Precompiler;
class PrecompilerTracer;

namespace compiler {

class SelectorRow;

struct TableSelector {
  TableSelector(int32_t _id,
                int32_t _call_count,
                int32_t _offset,
                bool _called_on_null,
                bool _torn_off)
      : id(_id),
        call_count(_call_count),
        offset(_offset),
        called_on_null(_called_on_null),
        torn_off(_torn_off) {}

  bool IsUsed() const { return call_count > 0; }

  // ID assigned to the selector.
  int32_t id;
  // Number of dispatch table call sites with this selector (conservative:
  // number may be bigger, but not smaller, than actual number of call sites).
  int32_t call_count;
  // Table offset assigned to the selector by the dispatch table generator.
  int32_t offset;
  // Are there any call sites with this selector where the receiver may be null?
  bool called_on_null;
  // Is this method ever torn off, i.e. is its method extractor accessed?
  bool torn_off;
  // Is the selector part of the interface on Null (same as Object)?
  bool on_null_interface = false;
  // Do any targets of this selector assume that an args descriptor is passed?
  bool requires_args_descriptor = false;
};

class SelectorMap {
 public:
  explicit SelectorMap(Zone* zone) : zone_(zone) {}

  // Get the selector for this interface target, or null if the function does
  // not have a selector assigned.
  const TableSelector* GetSelector(const Function& interface_target) const;

  const TableSelector* GetSelector(int32_t sid) const;

 private:
  static constexpr int32_t kInvalidSelectorId =
      kernel::ProcedureAttributesMetadata::kInvalidSelectorId;
  static constexpr int32_t kInvalidSelectorOffset = -1;

  int32_t SelectorId(const Function& interface_target) const;

  void AddSelector(int32_t call_count, bool called_on_null, bool torn_off);
  void SetSelectorProperties(int32_t sid,
                             bool on_null_interface,
                             bool requires_args_descriptor);

  int32_t NumIds() const { return selectors_.length(); }

  friend class dart::Precompiler;
  friend class dart::PrecompilerTracer;
  friend class DispatchTableGenerator;
  friend class SelectorRow;

  Zone* zone_;
  GrowableArray<TableSelector> selectors_;
};

class DispatchTableGenerator {
 public:
  explicit DispatchTableGenerator(Zone* zone);

  SelectorMap* selector_map() { return &selector_map_; }

  // Find suitable selectors and compute offsets for them.
  void Initialize(ClassTable* table);

  // Build up an array of Code objects, used to serialize the information
  // deserialized as a DispatchTable at runtime.
  ArrayPtr BuildCodeArray();

 private:
  void ReadTableSelectorInfo();
  void NumberSelectors();
  void SetupSelectorRows();
  void ComputeSelectorOffsets();

  Zone* const zone_;
  ClassTable* classes_;
  int32_t num_selectors_;
  int32_t num_classes_;
  int32_t table_size_;

  GrowableArray<SelectorRow*> table_rows_;

  SelectorMap selector_map_;
};

}  // namespace compiler
}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
