// Copyright 2014 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_DIAGNOSTICS_BASIC_BLOCK_PROFILER_H_
#define V8_DIAGNOSTICS_BASIC_BLOCK_PROFILER_H_

#include <iosfwd>
#include <list>
#include <string>
#include <vector>

#include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/common/globals.h"

namespace v8 {
namespace internal {

class BasicBlockProfiler {
 public:
  class Data {
   public:
    size_t n_blocks() const { return n_blocks_; }
    const uint32_t* counts() const { return &counts_[0]; }

    void SetCode(std::ostringstream* os);
    void SetFunctionName(std::unique_ptr<char[]> name);
    void SetSchedule(std::ostringstream* os);
    void SetBlockRpoNumber(size_t offset, int32_t block_rpo);
    intptr_t GetCounterAddress(size_t offset);

   private:
    friend class BasicBlockProfiler;
    friend std::ostream& operator<<(std::ostream& os,
                                    const BasicBlockProfiler::Data& s);

    explicit Data(size_t n_blocks);
    ~Data() = default;

    V8_EXPORT_PRIVATE void ResetCounts();

    const size_t n_blocks_;
    std::vector<int32_t> block_rpo_numbers_;
    std::vector<uint32_t> counts_;
    std::string function_name_;
    std::string schedule_;
    std::string code_;
    DISALLOW_COPY_AND_ASSIGN(Data);
  };

  using DataList = std::list<Data*>;

  BasicBlockProfiler() = default;
  ~BasicBlockProfiler();

  V8_EXPORT_PRIVATE static BasicBlockProfiler* Get();
  Data* NewData(size_t n_blocks);
  V8_EXPORT_PRIVATE void ResetCounts();

  const DataList* data_list() { return &data_list_; }

 private:
  friend V8_EXPORT_PRIVATE std::ostream& operator<<(
      std::ostream& os, const BasicBlockProfiler& s);

  DataList data_list_;
  base::Mutex data_list_mutex_;

  DISALLOW_COPY_AND_ASSIGN(BasicBlockProfiler);
};

V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           const BasicBlockProfiler& s);
std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler::Data& s);

}  // namespace internal
}  // namespace v8

#endif  // V8_DIAGNOSTICS_BASIC_BLOCK_PROFILER_H_
