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

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

#if !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

class ClassTable;
class Precompiler;

namespace compiler {

class SelectorRow;

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

  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 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;

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

  int32_t SelectorId(const Function& interface_target) const;

  void AddSelector(int32_t call_count, bool called_on_null);
  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 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.
  RawArray* 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  // !defined(DART_PRECOMPILED_RUNTIME)

#endif  // RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
