/* Copyright (C) 2017 The Android Open Source Project
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file implements interfaces from the file jvmti.h. This implementation
 * is licensed under the same terms as the file jvmti.h.  The
 * copyright and license information for the file jvmti.h follows.
 *
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#ifndef ART_OPENJDKJVMTI_DEOPT_MANAGER_H_
#define ART_OPENJDKJVMTI_DEOPT_MANAGER_H_

#include <atomic>
#include <unordered_map>

#include "jni.h"
#include "jvmti.h"

#include "base/mutex.h"
#include "runtime_callbacks.h"
#include "ti_breakpoint.h"

namespace art {
class ArtMethod;
namespace mirror {
class Class;
}  // namespace mirror
}  // namespace art

namespace openjdkjvmti {

class DeoptManager;

struct JvmtiMethodInspectionCallback : public art::MethodInspectionCallback {
 public:
  explicit JvmtiMethodInspectionCallback(DeoptManager* manager) : manager_(manager) {}

  bool IsMethodBeingInspected(art::ArtMethod* method)
      override REQUIRES_SHARED(art::Locks::mutator_lock_);

  bool IsMethodSafeToJit(art::ArtMethod* method)
      override REQUIRES_SHARED(art::Locks::mutator_lock_);

  bool MethodNeedsDebugVersion(art::ArtMethod* method)
      override REQUIRES_SHARED(art::Locks::mutator_lock_);

 private:
  DeoptManager* manager_;
};

class ScopedDeoptimizationContext;

class DeoptManager {
 public:
  DeoptManager();

  void Setup();
  void Shutdown();

  void RemoveDeoptimizationRequester() REQUIRES(!deoptimization_status_lock_,
                                                !art::Roles::uninterruptible_);
  void AddDeoptimizationRequester() REQUIRES(!deoptimization_status_lock_,
                                             !art::Roles::uninterruptible_);
  bool MethodHasBreakpoints(art::ArtMethod* method)
      REQUIRES(!deoptimization_status_lock_);

  void RemoveMethodBreakpoint(art::ArtMethod* method)
      REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
      REQUIRES_SHARED(art::Locks::mutator_lock_);

  void AddMethodBreakpoint(art::ArtMethod* method)
      REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
      REQUIRES_SHARED(art::Locks::mutator_lock_);

  void AddDeoptimizeAllMethods()
      REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
      REQUIRES_SHARED(art::Locks::mutator_lock_);

  void RemoveDeoptimizeAllMethods()
      REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
      REQUIRES_SHARED(art::Locks::mutator_lock_);

  void DeoptimizeThread(art::Thread* target) REQUIRES_SHARED(art::Locks::mutator_lock_);
  void DeoptimizeAllThreads() REQUIRES_SHARED(art::Locks::mutator_lock_);

  void FinishSetup()
      REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
      REQUIRES(art::Locks::mutator_lock_);

  static DeoptManager* Get();

  bool HaveLocalsChanged() const {
    return set_local_variable_called_.load();
  }

  void SetLocalsUpdated() {
    set_local_variable_called_.store(true);
  }

 private:
  bool MethodHasBreakpointsLocked(art::ArtMethod* method)
      REQUIRES(breakpoint_status_lock_);

  // Wait until nothing is currently in the middle of deoptimizing/undeoptimizing something. This is
  // needed to ensure that everything is synchronized since threads need to drop the
  // deoptimization_status_lock_ while deoptimizing methods.
  void WaitForDeoptimizationToFinish(art::Thread* self)
      RELEASE(deoptimization_status_lock_) REQUIRES(!art::Locks::mutator_lock_);

  void WaitForDeoptimizationToFinishLocked(art::Thread* self)
      REQUIRES(deoptimization_status_lock_, !art::Locks::mutator_lock_);

  void AddDeoptimizeAllMethodsLocked(art::Thread* self)
      RELEASE(deoptimization_status_lock_)
      REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);

  void RemoveDeoptimizeAllMethodsLocked(art::Thread* self)
      RELEASE(deoptimization_status_lock_)
      REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);

  void PerformGlobalDeoptimization(art::Thread* self)
      RELEASE(deoptimization_status_lock_)
      REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);

  void PerformGlobalUndeoptimization(art::Thread* self)
      RELEASE(deoptimization_status_lock_)
      REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);

  void PerformLimitedDeoptimization(art::Thread* self, art::ArtMethod* method)
      RELEASE(deoptimization_status_lock_)
      REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);

  void PerformLimitedUndeoptimization(art::Thread* self, art::ArtMethod* method)
      RELEASE(deoptimization_status_lock_)
      REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);

  static constexpr const char* kDeoptManagerInstrumentationKey = "JVMTI_DeoptManager";

  art::Mutex deoptimization_status_lock_ ACQUIRED_BEFORE(art::Locks::classlinker_classes_lock_);
  art::ConditionVariable deoptimization_condition_ GUARDED_BY(deoptimization_status_lock_);
  bool performing_deoptimization_ GUARDED_BY(deoptimization_status_lock_);

  // Number of times we have gotten requests to deopt everything.
  uint32_t global_deopt_count_ GUARDED_BY(deoptimization_status_lock_);

  // Number of users of deoptimization there currently are.
  uint32_t deopter_count_ GUARDED_BY(deoptimization_status_lock_);

  // A mutex that just protects the breakpoint-status map. This mutex should always be at the
  // bottom of the lock hierarchy. Nothing more should be locked if we hold this.
  art::Mutex breakpoint_status_lock_ ACQUIRED_BEFORE(art::Locks::abort_lock_);
  // A map from methods to the number of breakpoints in them from all envs.
  std::unordered_map<art::ArtMethod*, uint32_t> breakpoint_status_
      GUARDED_BY(breakpoint_status_lock_);

  // The MethodInspectionCallback we use to tell the runtime if we care about particular methods.
  JvmtiMethodInspectionCallback inspection_callback_;

  // Set to true if anything calls SetLocalVariables on any thread since we need to be careful about
  // OSR after this.
  std::atomic<bool> set_local_variable_called_;

  // Helper for setting up/tearing-down for deoptimization.
  friend class ScopedDeoptimizationContext;
};

}  // namespace openjdkjvmti
#endif  // ART_OPENJDKJVMTI_DEOPT_MANAGER_H_
