/* 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 <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_);

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

  static DeoptManager* Get();

 private:
  bool MethodHasBreakpointsLocked(art::ArtMethod* method)
      REQUIRES(deoptimization_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";
  // static constexpr const char* kDeoptManagerThreadName = "JVMTI_DeoptManagerWorkerThread";

  art::Mutex deoptimization_status_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
  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 map from methods to the number of breakpoints in them from all envs.
  std::unordered_map<art::ArtMethod*, uint32_t> breakpoint_status_
      GUARDED_BY(deoptimization_status_lock_);

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

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

}  // namespace openjdkjvmti
#endif  // ART_OPENJDKJVMTI_DEOPT_MANAGER_H_
