// 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_PRECOMPILER_TRACER_H_
#define RUNTIME_VM_COMPILER_AOT_PRECOMPILER_TRACER_H_

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

#include "vm/allocation.h"
#include "vm/hash_table.h"
#include "vm/symbols.h"

namespace dart {

// Forward declarations.
class Precompiler;

#if defined(DART_PRECOMPILER)
// Tracer which produces machine readable precompiler tracer, which captures
// information about all compiled functions and dependencies between them.
// See pkg/vm_snapshot_analysis/README.md for the definition of the
// format.
class PrecompilerTracer : public ZoneAllocated {
 public:
  static PrecompilerTracer* StartTracingIfRequested(Precompiler* precompiler);

  void Finalize();

  void WriteEntityRef(const Object& field) {
    Write("%" Pd ",", InternEntity(field));
  }

  void WriteFieldRef(const Field& field) { WriteEntityRef(field); }

  void WriteFunctionRef(const Function& function) { WriteEntityRef(function); }

  void WriteSelectorRef(const String& selector) {
    Write("\"S\",%" Pd ",", InternString(selector));
  }

  void WriteTableSelectorRef(intptr_t id) { Write("\"T\",%" Pd ",", id); }

  void WriteClassInstantiationRef(const Class& cls) { WriteEntityRef(cls); }

  void WriteCompileFunctionEvent(const Function& function) {
    Write("\"C\",");
    WriteEntityRef(function);
  }

 private:
  struct CString {
    const char* str;
    const intptr_t length;
    uword hash;
  };

  struct StringTableTraits {
    static bool ReportStats() { return false; }
    static const char* Name() { return "StringTableTraits"; }

    static bool IsMatch(const Object& a, const Object& b) {
      return String::Cast(a).Equals(String::Cast(b));
    }

    static bool IsMatch(const CString& cstr, const Object& other) {
      const String& other_str = String::Cast(other);
      if (other_str.Hash() != cstr.hash) {
        return false;
      }

      if (other_str.Length() != cstr.length) {
        return false;
      }

      return other_str.Equals(cstr.str);
    }

    static uword Hash(const CString& cstr) { return cstr.hash; }

    static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); }

    static ObjectPtr NewKey(const CString& cstr) {
      return Symbols::New(Thread::Current(), cstr.str);
    }
  };

  struct EntityTableTraits {
    static bool ReportStats() { return false; }
    static const char* Name() { return "EntityTableTraits"; }

    static bool IsMatch(const Object& a, const Object& b) {
      return a.ptr() == b.ptr();
    }

    static uword Hash(const Object& obj) {
      if (obj.IsFunction()) {
        return Function::Cast(obj).Hash();
      } else if (obj.IsClass()) {
        return Class::Cast(obj).Hash();
      } else if (obj.IsField()) {
        return Field::Cast(obj).Hash();
      }
      return obj.GetClassId();
    }
  };

  using StringTable = UnorderedHashMap<StringTableTraits>;
  using EntityTable = UnorderedHashMap<EntityTableTraits>;

  PrecompilerTracer(Precompiler* precompiler, void* stream);

  intptr_t InternString(const CString& cstr);
  intptr_t InternString(const String& str);
  intptr_t InternEntity(const Object& obj);

  void Write(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
    va_list va;
    va_start(va, format);
    buffer_.VPrintf(format, va);
    va_end(va);
  }

  CString NameForTrace(const Function& f);

  void WriteEntityTable();
  void WriteStringTable();

  Zone* zone_;
  Precompiler* precompiler_;
  TextBuffer buffer_;
  void* stream_;
  StringTable strings_;
  EntityTable entities_;

  Object& object_;
  Class& cls_;
};
#endif  // defined(DART_PRECOMPILER)

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_AOT_PRECOMPILER_TRACER_H_
