/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_JIT_JIT_INSTRUMENTATION_H_
#define ART_RUNTIME_JIT_JIT_INSTRUMENTATION_H_

#include <unordered_map>

#include "instrumentation.h"

#include "atomic.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "gc_root.h"
#include "jni.h"
#include "object_callbacks.h"
#include "thread_pool.h"

namespace art {
namespace mirror {
  class ArtField;
  class ArtMethod;
  class Class;
  class Object;
  class Throwable;
}  // namespace mirror
union JValue;
class Thread;

namespace jit {

// Keeps track of which methods are hot.
class JitInstrumentationCache {
 public:
  explicit JitInstrumentationCache(size_t hot_method_threshold);
  void AddSamples(Thread* self, mirror::ArtMethod* method, size_t samples)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
  void SignalCompiled(Thread* self, mirror::ArtMethod* method)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
  void CreateThreadPool();
  void DeleteThreadPool();

 private:
  Mutex lock_;
  std::unordered_map<jmethodID, size_t> samples_;
  size_t hot_method_threshold_;
  std::unique_ptr<ThreadPool> thread_pool_;
};

class JitInstrumentationListener : public instrumentation::InstrumentationListener {
 public:
  explicit JitInstrumentationListener(JitInstrumentationCache* cache);

  virtual void MethodEntered(Thread* thread, mirror::Object* /*this_object*/,
                             mirror::ArtMethod* method, uint32_t /*dex_pc*/)
      OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    instrumentation_cache_->AddSamples(thread, method, 1);
  }
  virtual void MethodExited(Thread* /*thread*/, mirror::Object* /*this_object*/,
                            mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/,
                            const JValue& /*return_value*/)
      OVERRIDE { }
  virtual void MethodUnwind(Thread* /*thread*/, mirror::Object* /*this_object*/,
                            mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/) OVERRIDE { }
  virtual void FieldRead(Thread* /*thread*/, mirror::Object* /*this_object*/,
                         mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/,
                         mirror::ArtField* /*field*/) OVERRIDE { }
  virtual void FieldWritten(Thread* /*thread*/, mirror::Object* /*this_object*/,
                            mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/,
                            mirror::ArtField* /*field*/, const JValue& /*field_value*/)
      OVERRIDE { }
  virtual void ExceptionCaught(Thread* /*thread*/,
                               mirror::Throwable* /*exception_object*/) OVERRIDE { }

  virtual void DexPcMoved(Thread* /*self*/, mirror::Object* /*this_object*/,
                          mirror::ArtMethod* /*method*/, uint32_t /*new_dex_pc*/) OVERRIDE { }

  // We only care about how many dex instructions were executed in the Jit.
  virtual void BackwardBranch(Thread* thread, mirror::ArtMethod* method, int32_t dex_pc_offset)
      OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    CHECK_LE(dex_pc_offset, 0);
    instrumentation_cache_->AddSamples(thread, method, 1);
  }

 private:
  JitInstrumentationCache* const instrumentation_cache_;
};

}  // namespace jit
}  // namespace art

#endif  // ART_RUNTIME_JIT_JIT_INSTRUMENTATION_H_
