/*
 * Copyright (C) 2011 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_JNI_JAVA_VM_EXT_H_
#define ART_RUNTIME_JNI_JAVA_VM_EXT_H_

#include "jni.h"

#include "base/macros.h"
#include "base/mutex.h"
#include "indirect_reference_table.h"
#include "obj_ptr.h"
#include "reference_table.h"

namespace art {

namespace mirror {
class Array;
}  // namespace mirror

class ArtMethod;
class IsMarkedVisitor;
class Libraries;
class ParsedOptions;
class Runtime;
struct RuntimeArgumentMap;
class ScopedObjectAccess;

class JavaVMExt;
// Hook definition for runtime plugins.
using GetEnvHook = jint (*)(JavaVMExt* vm, /*out*/void** new_env, jint version);

class JavaVMExt : public JavaVM {
 public:
  // Creates a new JavaVMExt object.
  // Returns nullptr on error, in which case error_msg is set to a message
  // describing the error.
  static std::unique_ptr<JavaVMExt> Create(Runtime* runtime,
                                           const RuntimeArgumentMap& runtime_options,
                                           std::string* error_msg);


  ~JavaVMExt();

  bool ForceCopy() const {
    return force_copy_;
  }

  bool IsCheckJniEnabled() const {
    return check_jni_;
  }

  bool IsTracingEnabled() const {
    return tracing_enabled_;
  }

  Runtime* GetRuntime() const {
    return runtime_;
  }

  void SetCheckJniAbortHook(void (*hook)(void*, const std::string&), void* data) {
    check_jni_abort_hook_ = hook;
    check_jni_abort_hook_data_ = data;
  }

  // Aborts execution unless there is an abort handler installed in which case it will return. Its
  // therefore important that callers return after aborting as otherwise code following the abort
  // will be executed in the abort handler case.
  void JniAbort(const char* jni_function_name, const char* msg);

  void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap);

  void JniAbortF(const char* jni_function_name, const char* fmt, ...)
      __attribute__((__format__(__printf__, 3, 4)));

  // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
  // when a native method that matches the -Xjnitrace argument calls a JNI function
  // such as NewByteArray.
  // If -verbose:third-party-jni is on, we want to log any JNI function calls
  // made by a third-party native method.
  bool ShouldTrace(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);

  /**
   * Loads the given shared library. 'path' is an absolute pathname.
   *
   * Returns 'true' on success. On failure, sets 'error_msg' to a
   * human-readable description of the error.
   */
  bool LoadNativeLibrary(JNIEnv* env,
                         const std::string& path,
                         jobject class_loader,
                         jclass caller_class,
                         std::string* error_msg);

  // Unload native libraries with cleared class loaders.
  void UnloadNativeLibraries()
      REQUIRES(!Locks::jni_libraries_lock_)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Unload all boot classpath native libraries.
  void UnloadBootNativeLibraries()
      REQUIRES(!Locks::jni_libraries_lock_)
      REQUIRES_SHARED(Locks::mutator_lock_);

  /**
   * Returns a pointer to the code for the native method 'm', found
   * using dlsym(3) on every native library that's been loaded so far.
   */
  void* FindCodeForNativeMethod(ArtMethod* m)
      REQUIRES_SHARED(Locks::mutator_lock_);

  void DumpForSigQuit(std::ostream& os)
      REQUIRES(!Locks::jni_libraries_lock_,
               !Locks::jni_globals_lock_,
               !Locks::jni_weak_globals_lock_);

  void DumpReferenceTables(std::ostream& os)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_globals_lock_,
               !Locks::jni_weak_globals_lock_,
               !Locks::alloc_tracker_lock_);

  bool SetCheckJniEnabled(bool enabled);

  void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_globals_lock_);

  void DisallowNewWeakGlobals()
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);
  void AllowNewWeakGlobals()
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);
  void BroadcastForNewWeakGlobals()
      REQUIRES(!Locks::jni_weak_globals_lock_);

  jobject AddGlobalRef(Thread* self, ObjPtr<mirror::Object> obj)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_globals_lock_);

  jweak AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);

  void DeleteGlobalRef(Thread* self, jobject obj) REQUIRES(!Locks::jni_globals_lock_);

  void DeleteWeakGlobalRef(Thread* self, jweak obj) REQUIRES(!Locks::jni_weak_globals_lock_);

  void SweepJniWeakGlobals(IsMarkedVisitor* visitor)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);

  ObjPtr<mirror::Object> DecodeGlobal(IndirectRef ref)
      REQUIRES_SHARED(Locks::mutator_lock_);

  void UpdateGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_globals_lock_);

  ObjPtr<mirror::Object> DecodeWeakGlobal(Thread* self, IndirectRef ref)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);

  ObjPtr<mirror::Object> DecodeWeakGlobalLocked(Thread* self, IndirectRef ref)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(Locks::jni_weak_globals_lock_);

  // Like DecodeWeakGlobal() but to be used only during a runtime shutdown where self may be
  // null.
  ObjPtr<mirror::Object> DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);

  // Checks if the weak global ref has been cleared by the GC without decode (read barrier.)
  bool IsWeakGlobalCleared(Thread* self, IndirectRef ref)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);

  void UpdateWeakGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_weak_globals_lock_);

  const JNIInvokeInterface* GetUncheckedFunctions() const {
    return unchecked_functions_;
  }

  void TrimGlobals() REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(!Locks::jni_globals_lock_);

  jint HandleGetEnv(/*out*/void** env, jint version);

  void AddEnvironmentHook(GetEnvHook hook);

  static bool IsBadJniVersion(int version);

  // Return the library search path for the given classloader, if the classloader is of a
  // well-known type. The jobject will be a local reference and is expected to be managed by the
  // caller.
  static jstring GetLibrarySearchPath(JNIEnv* env, jobject class_loader);

 private:
  // The constructor should not be called directly. It may leave the object in
  // an erroneous state, and the result needs to be checked.
  JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options, std::string* error_msg);

  // Return true if self can currently access weak globals.
  bool MayAccessWeakGlobalsUnlocked(Thread* self) const REQUIRES_SHARED(Locks::mutator_lock_);
  bool MayAccessWeakGlobals(Thread* self) const
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(Locks::jni_weak_globals_lock_);

  void WaitForWeakGlobalsAccess(Thread* self)
      REQUIRES_SHARED(Locks::mutator_lock_)
      REQUIRES(Locks::jni_weak_globals_lock_);

  void CheckGlobalRefAllocationTracking();

  inline void MaybeTraceGlobals() REQUIRES(Locks::jni_globals_lock_);
  inline void MaybeTraceWeakGlobals() REQUIRES(Locks::jni_weak_globals_lock_);

  Runtime* const runtime_;

  // Used for testing. By default, we'll LOG(FATAL) the reason.
  void (*check_jni_abort_hook_)(void* data, const std::string& reason);
  void* check_jni_abort_hook_data_;

  // Extra checking.
  bool check_jni_;
  const bool force_copy_;
  const bool tracing_enabled_;

  // Extra diagnostics.
  const std::string trace_;

  // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
  IndirectReferenceTable globals_;

  // No lock annotation since UnloadNativeLibraries is called on libraries_ but locks the
  // jni_libraries_lock_ internally.
  std::unique_ptr<Libraries> libraries_;

  // Used by -Xcheck:jni.
  const JNIInvokeInterface* const unchecked_functions_;

  // Since weak_globals_ contain weak roots, be careful not to
  // directly access the object references in it. Use Get() with the
  // read barrier enabled.
  // Not guarded by weak_globals_lock since we may use SynchronizedGet in DecodeWeakGlobal.
  IndirectReferenceTable weak_globals_;
  // Not guarded by weak_globals_lock since we may use SynchronizedGet in DecodeWeakGlobal.
  Atomic<bool> allow_accessing_weak_globals_;
  ConditionVariable weak_globals_add_condition_ GUARDED_BY(Locks::jni_weak_globals_lock_);

  // TODO Maybe move this to Runtime.
  std::vector<GetEnvHook> env_hooks_;

  size_t enable_allocation_tracking_delta_;
  std::atomic<bool> allocation_tracking_enabled_;
  std::atomic<bool> old_allocation_tracking_state_;

  // We report the number of global references after every kGlobalRefReportInterval changes.
  static constexpr uint32_t kGlobalRefReportInterval = 17;
  uint32_t weak_global_ref_report_counter_ GUARDED_BY(Locks::jni_weak_globals_lock_)
      = kGlobalRefReportInterval;
  uint32_t global_ref_report_counter_ GUARDED_BY(Locks::jni_globals_lock_)
      = kGlobalRefReportInterval;


  friend IndirectReferenceTable* GetIndirectReferenceTable(ScopedObjectAccess& soa,
                                                           IndirectRefKind kind);

  DISALLOW_COPY_AND_ASSIGN(JavaVMExt);
};

}  // namespace art

#endif  // ART_RUNTIME_JNI_JAVA_VM_EXT_H_
