/*
 * 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_RUNTIME_H_
#define ART_RUNTIME_RUNTIME_H_

#include <jni.h>
#include <stdio.h>

#include <forward_list>
#include <iosfwd>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "app_info.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/mem_map.h"
#include "base/metrics/metrics.h"
#include "base/string_view_cpp20.h"
#include "compat_framework.h"
#include "deoptimization_kind.h"
#include "dex/dex_file_types.h"
#include "experimental_flags.h"
#include "gc_root.h"
#include "instrumentation.h"
#include "jdwp_provider.h"
#include "jni/jni_id_manager.h"
#include "jni_id_type.h"
#include "metrics/reporter.h"
#include "obj_ptr.h"
#include "offsets.h"
#include "process_state.h"
#include "quick/quick_method_frame_info.h"
#include "reflective_value_visitor.h"
#include "runtime_stats.h"

namespace art {

namespace gc {
class AbstractSystemWeakHolder;
class Heap;
}  // namespace gc

namespace hiddenapi {
enum class EnforcementPolicy;
}  // namespace hiddenapi

namespace jit {
class Jit;
class JitCodeCache;
class JitOptions;
}  // namespace jit

namespace mirror {
class Array;
class ClassLoader;
class DexCache;
template<class T> class ObjectArray;
template<class T> class PrimitiveArray;
using ByteArray = PrimitiveArray<int8_t>;
class String;
class Throwable;
}  // namespace mirror
namespace ti {
class Agent;
class AgentSpec;
}  // namespace ti
namespace verifier {
class MethodVerifier;
enum class VerifyMode : int8_t;
}  // namespace verifier
class ArenaPool;
class ArtMethod;
enum class CalleeSaveType: uint32_t;
class ClassLinker;
class CompilerCallbacks;
class Dex2oatImageTest;
class DexFile;
enum class InstructionSet;
class InternTable;
class IsMarkedVisitor;
class JavaVMExt;
class LinearAlloc;
class MonitorList;
class MonitorPool;
class NullPointerHandler;
class OatFileAssistantTest;
class OatFileManager;
class Plugin;
struct RuntimeArgumentMap;
class RuntimeCallbacks;
class SignalCatcher;
class SmallIrtAllocator;
class StackOverflowHandler;
class SuspensionHandler;
class ThreadList;
class ThreadPool;
class Trace;
struct TraceConfig;
class Transaction;

using RuntimeOptions = std::vector<std::pair<std::string, const void*>>;

class Runtime {
 public:
  // Parse raw runtime options.
  static bool ParseOptions(const RuntimeOptions& raw_options,
                           bool ignore_unrecognized,
                           RuntimeArgumentMap* runtime_options);

  // Creates and initializes a new runtime.
  static bool Create(RuntimeArgumentMap&& runtime_options)
      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);

  // Creates and initializes a new runtime.
  static bool Create(const RuntimeOptions& raw_options, bool ignore_unrecognized)
      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);

  bool EnsurePluginLoaded(const char* plugin_name, std::string* error_msg);
  bool EnsurePerfettoPlugin(std::string* error_msg);

  // IsAotCompiler for compilers that don't have a running runtime. Only dex2oat currently.
  bool IsAotCompiler() const {
    return !UseJitCompilation() && IsCompiler();
  }

  // IsCompiler is any runtime which has a running compiler, either dex2oat or JIT.
  bool IsCompiler() const {
    return compiler_callbacks_ != nullptr;
  }

  // If a compiler, are we compiling a boot image?
  bool IsCompilingBootImage() const;

  bool CanRelocate() const;

  bool ShouldRelocate() const {
    return must_relocate_ && CanRelocate();
  }

  bool MustRelocateIfPossible() const {
    return must_relocate_;
  }

  bool IsImageDex2OatEnabled() const {
    return image_dex2oat_enabled_;
  }

  CompilerCallbacks* GetCompilerCallbacks() {
    return compiler_callbacks_;
  }

  void SetCompilerCallbacks(CompilerCallbacks* callbacks) {
    CHECK(callbacks != nullptr);
    compiler_callbacks_ = callbacks;
  }

  bool IsZygote() const {
    return is_zygote_;
  }

  bool IsPrimaryZygote() const {
    return is_primary_zygote_;
  }

  bool IsSystemServer() const {
    return is_system_server_;
  }

  void SetAsSystemServer() {
    is_system_server_ = true;
    is_zygote_ = false;
    is_primary_zygote_ = false;
  }

  void SetAsZygoteChild(bool is_system_server, bool is_zygote) {
    // System server should have been set earlier in SetAsSystemServer.
    CHECK_EQ(is_system_server_, is_system_server);
    is_zygote_ = is_zygote;
    is_primary_zygote_ = false;
  }

  bool IsExplicitGcDisabled() const {
    return is_explicit_gc_disabled_;
  }

  std::string GetCompilerExecutable() const;

  const std::vector<std::string>& GetCompilerOptions() const {
    return compiler_options_;
  }

  void AddCompilerOption(const std::string& option) {
    compiler_options_.push_back(option);
  }

  const std::vector<std::string>& GetImageCompilerOptions() const {
    return image_compiler_options_;
  }

  const std::vector<std::string>& GetImageLocations() const {
    return image_locations_;
  }

  // Starts a runtime, which may cause threads to be started and code to run.
  bool Start() UNLOCK_FUNCTION(Locks::mutator_lock_);

  bool IsShuttingDown(Thread* self);
  bool IsShuttingDownLocked() const REQUIRES(Locks::runtime_shutdown_lock_) {
    return shutting_down_.load(std::memory_order_relaxed);
  }
  bool IsShuttingDownUnsafe() const {
    return shutting_down_.load(std::memory_order_relaxed);
  }
  void SetShuttingDown() REQUIRES(Locks::runtime_shutdown_lock_) {
    shutting_down_.store(true, std::memory_order_relaxed);
  }

  size_t NumberOfThreadsBeingBorn() const REQUIRES(Locks::runtime_shutdown_lock_) {
    return threads_being_born_;
  }

  void StartThreadBirth() REQUIRES(Locks::runtime_shutdown_lock_) {
    threads_being_born_++;
  }

  void EndThreadBirth() REQUIRES(Locks::runtime_shutdown_lock_);

  bool IsStarted() const {
    return started_;
  }

  bool IsFinishedStarting() const {
    return finished_starting_;
  }

  void RunRootClinits(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);

  static Runtime* Current() {
    return instance_;
  }

  // Set the current runtime to be the given instance.
  // Note that this function is not responsible for cleaning up the old instance or taking the
  // ownership of the new instance.
  //
  // For test use only.
  static void TestOnlySetCurrent(Runtime* instance) { instance_ = instance; }

  // Aborts semi-cleanly. Used in the implementation of LOG(FATAL), which most
  // callers should prefer.
  NO_RETURN static void Abort(const char* msg) REQUIRES(!Locks::abort_lock_);

  // Returns the "main" ThreadGroup, used when attaching user threads.
  jobject GetMainThreadGroup() const;

  // Returns the "system" ThreadGroup, used when attaching our internal threads.
  jobject GetSystemThreadGroup() const;

  // Returns the system ClassLoader which represents the CLASSPATH.
  jobject GetSystemClassLoader() const;

  // Attaches the calling native thread to the runtime.
  bool AttachCurrentThread(const char* thread_name, bool as_daemon, jobject thread_group,
                           bool create_peer);

  void CallExitHook(jint status);

  // Detaches the current native thread from the runtime.
  void DetachCurrentThread() REQUIRES(!Locks::mutator_lock_);

  void DumpDeoptimizations(std::ostream& os);
  void DumpForSigQuit(std::ostream& os);
  void DumpLockHolders(std::ostream& os);

  ~Runtime();

  const std::vector<std::string>& GetBootClassPath() const {
    return boot_class_path_;
  }

  const std::vector<std::string>& GetBootClassPathLocations() const {
    DCHECK(boot_class_path_locations_.empty() ||
           boot_class_path_locations_.size() == boot_class_path_.size());
    return boot_class_path_locations_.empty() ? boot_class_path_ : boot_class_path_locations_;
  }

  const std::vector<int>& GetBootClassPathFds() const {
    return boot_class_path_fds_;
  }

  const std::vector<int>& GetBootClassPathImageFds() const {
    return boot_class_path_image_fds_;
  }

  const std::vector<int>& GetBootClassPathVdexFds() const {
    return boot_class_path_vdex_fds_;
  }

  const std::vector<int>& GetBootClassPathOatFds() const {
    return boot_class_path_oat_fds_;
  }

  // Returns the checksums for the boot image, extensions and extra boot class path dex files,
  // based on the image spaces and boot class path dex files loaded in memory.
  const std::string& GetBootClassPathChecksums() const {
    return boot_class_path_checksums_;
  }

  const std::string& GetClassPathString() const {
    return class_path_string_;
  }

  ClassLinker* GetClassLinker() const {
    return class_linker_;
  }

  SmallIrtAllocator* GetSmallIrtAllocator() const {
    return small_irt_allocator_;
  }

  jni::JniIdManager* GetJniIdManager() const {
    return jni_id_manager_.get();
  }

  size_t GetDefaultStackSize() const {
    return default_stack_size_;
  }

  unsigned int GetFinalizerTimeoutMs() const {
    return finalizer_timeout_ms_;
  }

  gc::Heap* GetHeap() const {
    return heap_;
  }

  InternTable* GetInternTable() const {
    DCHECK(intern_table_ != nullptr);
    return intern_table_;
  }

  JavaVMExt* GetJavaVM() const {
    return java_vm_.get();
  }

  size_t GetMaxSpinsBeforeThinLockInflation() const {
    return max_spins_before_thin_lock_inflation_;
  }

  MonitorList* GetMonitorList() const {
    return monitor_list_;
  }

  MonitorPool* GetMonitorPool() const {
    return monitor_pool_;
  }

  // Is the given object the special object used to mark a cleared JNI weak global?
  bool IsClearedJniWeakGlobal(ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_);

  // Get the special object used to mark a cleared JNI weak global.
  mirror::Object* GetClearedJniWeakGlobal() REQUIRES_SHARED(Locks::mutator_lock_);

  mirror::Throwable* GetPreAllocatedOutOfMemoryErrorWhenThrowingException()
      REQUIRES_SHARED(Locks::mutator_lock_);
  mirror::Throwable* GetPreAllocatedOutOfMemoryErrorWhenThrowingOOME()
      REQUIRES_SHARED(Locks::mutator_lock_);
  mirror::Throwable* GetPreAllocatedOutOfMemoryErrorWhenHandlingStackOverflow()
      REQUIRES_SHARED(Locks::mutator_lock_);

  mirror::Throwable* GetPreAllocatedNoClassDefFoundError()
      REQUIRES_SHARED(Locks::mutator_lock_);

  const std::vector<std::string>& GetProperties() const {
    return properties_;
  }

  ThreadList* GetThreadList() const {
    return thread_list_;
  }

  static const char* GetVersion() {
    return "2.1.0";
  }

  bool IsMethodHandlesEnabled() const {
    return true;
  }

  void DisallowNewSystemWeaks() REQUIRES_SHARED(Locks::mutator_lock_);
  void AllowNewSystemWeaks() REQUIRES_SHARED(Locks::mutator_lock_);
  // broadcast_for_checkpoint is true when we broadcast for making blocking threads to respond to
  // checkpoint requests. It's false when we broadcast to unblock blocking threads after system weak
  // access is reenabled.
  void BroadcastForNewSystemWeaks(bool broadcast_for_checkpoint = false);

  // Visit all the roots. If only_dirty is true then non-dirty roots won't be visited. If
  // clean_dirty is true then dirty roots will be marked as non-dirty after visiting.
  void VisitRoots(RootVisitor* visitor, VisitRootFlags flags = kVisitRootFlagAllRoots)
      REQUIRES(!Locks::classlinker_classes_lock_, !Locks::trace_lock_)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Visit image roots, only used for hprof since the GC uses the image space mod union table
  // instead.
  void VisitImageRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);

  // Visit all of the roots we can safely visit concurrently.
  void VisitConcurrentRoots(RootVisitor* visitor,
                            VisitRootFlags flags = kVisitRootFlagAllRoots)
      REQUIRES(!Locks::classlinker_classes_lock_, !Locks::trace_lock_)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Visit all of the non thread roots, we can do this with mutators unpaused.
  void VisitNonThreadRoots(RootVisitor* visitor)
      REQUIRES_SHARED(Locks::mutator_lock_);

  void VisitTransactionRoots(RootVisitor* visitor)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Sweep system weaks, the system weak is deleted if the visitor return null. Otherwise, the
  // system weak is updated to be the visitor's returned value.
  void SweepSystemWeaks(IsMarkedVisitor* visitor)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Walk all reflective objects and visit their targets as well as any method/fields held by the
  // runtime threads that are marked as being reflective.
  void VisitReflectiveTargets(ReflectiveValueVisitor* visitor) REQUIRES(Locks::mutator_lock_);
  // Helper for visiting reflective targets with lambdas for both field and method reflective
  // targets.
  template <typename FieldVis, typename MethodVis>
  void VisitReflectiveTargets(FieldVis&& fv, MethodVis&& mv) REQUIRES(Locks::mutator_lock_) {
    FunctionReflectiveValueVisitor frvv(fv, mv);
    VisitReflectiveTargets(&frvv);
  }

  // Returns a special method that calls into a trampoline for runtime method resolution
  ArtMethod* GetResolutionMethod();

  bool HasResolutionMethod() const {
    return resolution_method_ != nullptr;
  }

  void SetResolutionMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
  void ClearResolutionMethod() {
    resolution_method_ = nullptr;
  }

  ArtMethod* CreateResolutionMethod() REQUIRES_SHARED(Locks::mutator_lock_);

  // Returns a special method that calls into a trampoline for runtime imt conflicts.
  ArtMethod* GetImtConflictMethod();
  ArtMethod* GetImtUnimplementedMethod();

  bool HasImtConflictMethod() const {
    return imt_conflict_method_ != nullptr;
  }

  void ClearImtConflictMethod() {
    imt_conflict_method_ = nullptr;
  }

  void FixupConflictTables() REQUIRES_SHARED(Locks::mutator_lock_);
  void SetImtConflictMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
  void SetImtUnimplementedMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);

  ArtMethod* CreateImtConflictMethod(LinearAlloc* linear_alloc)
      REQUIRES_SHARED(Locks::mutator_lock_);

  void ClearImtUnimplementedMethod() {
    imt_unimplemented_method_ = nullptr;
  }

  bool HasCalleeSaveMethod(CalleeSaveType type) const {
    return callee_save_methods_[static_cast<size_t>(type)] != 0u;
  }

  ArtMethod* GetCalleeSaveMethod(CalleeSaveType type)
      REQUIRES_SHARED(Locks::mutator_lock_);

  ArtMethod* GetCalleeSaveMethodUnchecked(CalleeSaveType type)
      REQUIRES_SHARED(Locks::mutator_lock_);

  QuickMethodFrameInfo GetRuntimeMethodFrameInfo(ArtMethod* method)
      REQUIRES_SHARED(Locks::mutator_lock_);

  static constexpr size_t GetCalleeSaveMethodOffset(CalleeSaveType type) {
    return OFFSETOF_MEMBER(Runtime, callee_save_methods_[static_cast<size_t>(type)]);
  }

  InstructionSet GetInstructionSet() const {
    return instruction_set_;
  }

  void SetInstructionSet(InstructionSet instruction_set);
  void ClearInstructionSet();

  void SetCalleeSaveMethod(ArtMethod* method, CalleeSaveType type);
  void ClearCalleeSaveMethods();

  ArtMethod* CreateCalleeSaveMethod() REQUIRES_SHARED(Locks::mutator_lock_);

  uint64_t GetStat(int kind);

  RuntimeStats* GetStats() {
    return &stats_;
  }

  bool HasStatsEnabled() const {
    return stats_enabled_;
  }

  void ResetStats(int kinds);

  void SetStatsEnabled(bool new_state)
      REQUIRES(!Locks::instrument_entrypoints_lock_, !Locks::mutator_lock_);

  enum class NativeBridgeAction {  // private
    kUnload,
    kInitialize
  };

  jit::Jit* GetJit() const {
    return jit_.get();
  }

  jit::JitCodeCache* GetJitCodeCache() const {
    return jit_code_cache_.get();
  }

  // Returns true if JIT compilations are enabled. GetJit() will be not null in this case.
  bool UseJitCompilation() const;

  void PreZygoteFork();
  void PostZygoteFork();
  void InitNonZygoteOrPostFork(
      JNIEnv* env,
      bool is_system_server,
      bool is_child_zygote,
      NativeBridgeAction action,
      const char* isa,
      bool profile_system_server = false);

  const instrumentation::Instrumentation* GetInstrumentation() const {
    return &instrumentation_;
  }

  instrumentation::Instrumentation* GetInstrumentation() {
    return &instrumentation_;
  }

  void RegisterAppInfo(const std::string& package_name,
                       const std::vector<std::string>& code_paths,
                       const std::string& profile_output_filename,
                       const std::string& ref_profile_filename,
                       int32_t code_type);

  // Transaction support.
  bool IsActiveTransaction() const;
  void EnterTransactionMode(bool strict, mirror::Class* root);
  void ExitTransactionMode();
  void RollbackAllTransactions() REQUIRES_SHARED(Locks::mutator_lock_);
  // Transaction rollback and exit transaction are always done together, it's convenience to
  // do them in one function.
  void RollbackAndExitTransactionMode() REQUIRES_SHARED(Locks::mutator_lock_);
  bool IsTransactionAborted() const;
  const Transaction* GetTransaction() const;
  Transaction* GetTransaction();
  bool IsActiveStrictTransactionMode() const;

  void AbortTransactionAndThrowAbortError(Thread* self, const std::string& abort_message)
      REQUIRES_SHARED(Locks::mutator_lock_);
  void ThrowTransactionAbortError(Thread* self)
      REQUIRES_SHARED(Locks::mutator_lock_);

  void RecordWriteFieldBoolean(mirror::Object* obj,
                               MemberOffset field_offset,
                               uint8_t value,
                               bool is_volatile);
  void RecordWriteFieldByte(mirror::Object* obj,
                            MemberOffset field_offset,
                            int8_t value,
                            bool is_volatile);
  void RecordWriteFieldChar(mirror::Object* obj,
                            MemberOffset field_offset,
                            uint16_t value,
                            bool is_volatile);
  void RecordWriteFieldShort(mirror::Object* obj,
                             MemberOffset field_offset,
                             int16_t value,
                             bool is_volatile);
  void RecordWriteField32(mirror::Object* obj,
                          MemberOffset field_offset,
                          uint32_t value,
                          bool is_volatile);
  void RecordWriteField64(mirror::Object* obj,
                          MemberOffset field_offset,
                          uint64_t value,
                          bool is_volatile);
  void RecordWriteFieldReference(mirror::Object* obj,
                                 MemberOffset field_offset,
                                 ObjPtr<mirror::Object> value,
                                 bool is_volatile)
      REQUIRES_SHARED(Locks::mutator_lock_);
  void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
      REQUIRES_SHARED(Locks::mutator_lock_);
  void RecordStrongStringInsertion(ObjPtr<mirror::String> s)
      REQUIRES(Locks::intern_table_lock_);
  void RecordWeakStringInsertion(ObjPtr<mirror::String> s)
      REQUIRES(Locks::intern_table_lock_);
  void RecordStrongStringRemoval(ObjPtr<mirror::String> s)
      REQUIRES(Locks::intern_table_lock_);
  void RecordWeakStringRemoval(ObjPtr<mirror::String> s)
      REQUIRES(Locks::intern_table_lock_);
  void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx)
      REQUIRES_SHARED(Locks::mutator_lock_);
  void RecordResolveMethodType(ObjPtr<mirror::DexCache> dex_cache, dex::ProtoIndex proto_idx)
      REQUIRES_SHARED(Locks::mutator_lock_);

  void SetFaultMessage(const std::string& message);

  void AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* arg_vector) const;

  bool GetImplicitStackOverflowChecks() const {
    return implicit_so_checks_;
  }

  bool GetImplicitSuspendChecks() const {
    return implicit_suspend_checks_;
  }

  bool GetImplicitNullChecks() const {
    return implicit_null_checks_;
  }

  void DisableVerifier();
  bool IsVerificationEnabled() const;
  bool IsVerificationSoftFail() const;

  void SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy policy) {
    hidden_api_policy_ = policy;
  }

  hiddenapi::EnforcementPolicy GetHiddenApiEnforcementPolicy() const {
    return hidden_api_policy_;
  }

  void SetCorePlatformApiEnforcementPolicy(hiddenapi::EnforcementPolicy policy) {
    core_platform_api_policy_ = policy;
  }

  hiddenapi::EnforcementPolicy GetCorePlatformApiEnforcementPolicy() const {
    return core_platform_api_policy_;
  }

  void SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy policy) {
    test_api_policy_ = policy;
  }

  hiddenapi::EnforcementPolicy GetTestApiEnforcementPolicy() const {
    return test_api_policy_;
  }

  void SetHiddenApiExemptions(const std::vector<std::string>& exemptions) {
    hidden_api_exemptions_ = exemptions;
  }

  const std::vector<std::string>& GetHiddenApiExemptions() {
    return hidden_api_exemptions_;
  }

  void SetDedupeHiddenApiWarnings(bool value) {
    dedupe_hidden_api_warnings_ = value;
  }

  bool ShouldDedupeHiddenApiWarnings() {
    return dedupe_hidden_api_warnings_;
  }

  void SetHiddenApiEventLogSampleRate(uint32_t rate) {
    hidden_api_access_event_log_rate_ = rate;
  }

  uint32_t GetHiddenApiEventLogSampleRate() const {
    return hidden_api_access_event_log_rate_;
  }

  const std::string& GetProcessPackageName() const {
    return process_package_name_;
  }

  void SetProcessPackageName(const char* package_name) {
    if (package_name == nullptr) {
      process_package_name_.clear();
    } else {
      process_package_name_ = package_name;
    }
  }

  const std::string& GetProcessDataDirectory() const {
    return process_data_directory_;
  }

  void SetProcessDataDirectory(const char* data_dir) {
    if (data_dir == nullptr) {
      process_data_directory_.clear();
    } else {
      process_data_directory_ = data_dir;
    }
  }

  const std::vector<std::string>& GetCpuAbilist() const {
    return cpu_abilist_;
  }

  bool IsRunningOnMemoryTool() const {
    return is_running_on_memory_tool_;
  }

  void SetTargetSdkVersion(uint32_t version) {
    target_sdk_version_ = version;
  }

  uint32_t GetTargetSdkVersion() const {
    return target_sdk_version_;
  }

  CompatFramework& GetCompatFramework() {
    return compat_framework_;
  }

  uint32_t GetZygoteMaxFailedBoots() const {
    return zygote_max_failed_boots_;
  }

  bool AreExperimentalFlagsEnabled(ExperimentalFlags flags) {
    return (experimental_flags_ & flags) != ExperimentalFlags::kNone;
  }

  void CreateJitCodeCache(bool rwx_memory_allowed);

  // Create the JIT and instrumentation and code cache.
  void CreateJit();

  ArenaPool* GetArenaPool() {
    return arena_pool_.get();
  }
  const ArenaPool* GetArenaPool() const {
    return arena_pool_.get();
  }
  ArenaPool* GetJitArenaPool() {
    return jit_arena_pool_.get();
  }

  void ReclaimArenaPoolMemory();

  LinearAlloc* GetLinearAlloc() {
    return linear_alloc_.get();
  }

  jit::JitOptions* GetJITOptions() {
    return jit_options_.get();
  }

  bool IsJavaDebuggable() const {
    return is_java_debuggable_;
  }

  void SetProfileableFromShell(bool value) {
    is_profileable_from_shell_ = value;
  }

  bool IsProfileableFromShell() const {
    return is_profileable_from_shell_;
  }

  void SetProfileable(bool value) {
    is_profileable_ = value;
  }

  bool IsProfileable() const {
    return is_profileable_;
  }

  void SetJavaDebuggable(bool value);

  // Deoptimize the boot image, called for Java debuggable apps.
  void DeoptimizeBootImage() REQUIRES(Locks::mutator_lock_);

  bool IsNativeDebuggable() const {
    return is_native_debuggable_;
  }

  void SetNativeDebuggable(bool value) {
    is_native_debuggable_ = value;
  }

  void SetSignalHookDebuggable(bool value);

  bool AreNonStandardExitsEnabled() const {
    return non_standard_exits_enabled_;
  }

  void SetNonStandardExitsEnabled() {
    non_standard_exits_enabled_ = true;
  }

  bool AreAsyncExceptionsThrown() const {
    return async_exceptions_thrown_;
  }

  void SetAsyncExceptionsThrown() {
    async_exceptions_thrown_ = true;
  }

  // Returns the build fingerprint, if set. Otherwise an empty string is returned.
  std::string GetFingerprint() {
    return fingerprint_;
  }

  // Called from class linker.
  void SetSentinel(ObjPtr<mirror::Object> sentinel) REQUIRES_SHARED(Locks::mutator_lock_);
  // For testing purpose only.
  // TODO: Remove this when this is no longer needed (b/116087961).
  GcRoot<mirror::Object> GetSentinel() REQUIRES_SHARED(Locks::mutator_lock_);


  // Use a sentinel for marking entries in a table that have been cleared.
  // This helps diagnosing in case code tries to wrongly access such
  // entries.
  static mirror::Class* GetWeakClassSentinel() {
    return reinterpret_cast<mirror::Class*>(0xebadbeef);
  }

  // Helper for the GC to process a weak class in a table.
  static void ProcessWeakClass(GcRoot<mirror::Class>* root_ptr,
                               IsMarkedVisitor* visitor,
                               mirror::Class* update)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Create a normal LinearAlloc or low 4gb version if we are 64 bit AOT compiler.
  LinearAlloc* CreateLinearAlloc();

  OatFileManager& GetOatFileManager() const {
    DCHECK(oat_file_manager_ != nullptr);
    return *oat_file_manager_;
  }

  double GetHashTableMinLoadFactor() const;
  double GetHashTableMaxLoadFactor() const;

  bool IsSafeMode() const {
    return safe_mode_;
  }

  void SetSafeMode(bool mode) {
    safe_mode_ = mode;
  }

  bool GetDumpNativeStackOnSigQuit() const {
    return dump_native_stack_on_sig_quit_;
  }

  void UpdateProcessState(ProcessState process_state);

  // Returns true if we currently care about long mutator pause.
  bool InJankPerceptibleProcessState() const {
    return process_state_ == kProcessStateJankPerceptible;
  }

  void RegisterSensitiveThread() const;

  void SetZygoteNoThreadSection(bool val) {
    zygote_no_threads_ = val;
  }

  bool IsZygoteNoThreadSection() const {
    return zygote_no_threads_;
  }

  // Returns if the code can be deoptimized asynchronously. Code may be compiled with some
  // optimization that makes it impossible to deoptimize.
  bool IsAsyncDeoptimizeable(uintptr_t code) const REQUIRES_SHARED(Locks::mutator_lock_);

  // Returns a saved copy of the environment (getenv/setenv values).
  // Used by Fork to protect against overwriting LD_LIBRARY_PATH, etc.
  char** GetEnvSnapshot() const {
    return env_snapshot_.GetSnapshot();
  }

  void AddSystemWeakHolder(gc::AbstractSystemWeakHolder* holder);
  void RemoveSystemWeakHolder(gc::AbstractSystemWeakHolder* holder);

  void AttachAgent(JNIEnv* env, const std::string& agent_arg, jobject class_loader);

  const std::list<std::unique_ptr<ti::Agent>>& GetAgents() const {
    return agents_;
  }

  RuntimeCallbacks* GetRuntimeCallbacks();

  bool HasLoadedPlugins() const {
    return !plugins_.empty();
  }

  void InitThreadGroups(Thread* self);

  void SetDumpGCPerformanceOnShutdown(bool value) {
    dump_gc_performance_on_shutdown_ = value;
  }

  bool GetDumpGCPerformanceOnShutdown() const {
    return dump_gc_performance_on_shutdown_;
  }

  void IncrementDeoptimizationCount(DeoptimizationKind kind) {
    DCHECK_LE(kind, DeoptimizationKind::kLast);
    deoptimization_counts_[static_cast<size_t>(kind)]++;
  }

  uint32_t GetNumberOfDeoptimizations() const {
    uint32_t result = 0;
    for (size_t i = 0; i <= static_cast<size_t>(DeoptimizationKind::kLast); ++i) {
      result += deoptimization_counts_[i];
    }
    return result;
  }

  bool DenyArtApexDataFiles() const {
    return deny_art_apex_data_files_;
  }

  // Whether or not we use MADV_RANDOM on files that are thought to have random access patterns.
  // This is beneficial for low RAM devices since it reduces page cache thrashing.
  bool MAdviseRandomAccess() const {
    return madvise_random_access_;
  }

  size_t GetMadviseWillNeedSizeVdex() const {
    return madvise_willneed_vdex_filesize_;
  }

  size_t GetMadviseWillNeedSizeOdex() const {
    return madvise_willneed_odex_filesize_;
  }

  size_t GetMadviseWillNeedSizeArt() const {
    return madvise_willneed_art_filesize_;
  }

  const std::string& GetJdwpOptions() {
    return jdwp_options_;
  }

  JdwpProvider GetJdwpProvider() const {
    return jdwp_provider_;
  }

  JniIdType GetJniIdType() const {
    return jni_ids_indirection_;
  }

  bool CanSetJniIdType() const {
    return GetJniIdType() == JniIdType::kSwapablePointer;
  }

  // Changes the JniIdType to the given type. Only allowed if CanSetJniIdType(). All threads must be
  // suspended to call this function.
  void SetJniIdType(JniIdType t);

  uint32_t GetVerifierLoggingThresholdMs() const {
    return verifier_logging_threshold_ms_;
  }

  // Atomically delete the thread pool if the reference count is 0.
  bool DeleteThreadPool() REQUIRES(!Locks::runtime_thread_pool_lock_);

  // Wait for all the thread workers to be attached.
  void WaitForThreadPoolWorkersToStart() REQUIRES(!Locks::runtime_thread_pool_lock_);

  // Scoped usage of the runtime thread pool. Prevents the pool from being
  // deleted. Note that the thread pool is only for startup and gets deleted after.
  class ScopedThreadPoolUsage {
   public:
    ScopedThreadPoolUsage();
    ~ScopedThreadPoolUsage();

    // Return the thread pool.
    ThreadPool* GetThreadPool() const {
      return thread_pool_;
    }

   private:
    ThreadPool* const thread_pool_;
  };

  bool LoadAppImageStartupCache() const {
    return load_app_image_startup_cache_;
  }

  void SetLoadAppImageStartupCacheEnabled(bool enabled) {
    load_app_image_startup_cache_ = enabled;
  }

  // Reset the startup completed status so that we can call NotifyStartupCompleted again. Should
  // only be used for testing.
  void ResetStartupCompleted();

  // Notify the runtime that application startup is considered completed. Only has effect for the
  // first call.
  void NotifyStartupCompleted();

  // Notify the runtime that the application finished loading some dex/odex files. This is
  // called everytime we load a set of dex files in a class loader.
  void NotifyDexFileLoaded();

  // Return true if startup is already completed.
  bool GetStartupCompleted() const;

  bool IsVerifierMissingKThrowFatal() const {
    return verifier_missing_kthrow_fatal_;
  }

  bool IsJavaZygoteForkLoopRequired() const {
    return force_java_zygote_fork_loop_;
  }

  bool IsPerfettoHprofEnabled() const {
    return perfetto_hprof_enabled_;
  }

  bool IsPerfettoJavaHeapStackProfEnabled() const {
    return perfetto_javaheapprof_enabled_;
  }

  bool IsMonitorTimeoutEnabled() const {
    return monitor_timeout_enable_;
  }

  uint64_t GetMonitorTimeoutNs() const {
    return monitor_timeout_ns_;
  }
  // Return true if we should load oat files as executable or not.
  bool GetOatFilesExecutable() const;

  metrics::ArtMetrics* GetMetrics() { return &metrics_; }

  AppInfo* GetAppInfo() { return &app_info_; }

  void RequestMetricsReport(bool synchronous = true);

  static void MadviseFileForRange(size_t madvise_size_limit_bytes,
                                  size_t map_size_bytes,
                                  const uint8_t* map_begin,
                                  const uint8_t* map_end,
                                  const std::string& file_name);

  const std::string& GetApexVersions() const {
    return apex_versions_;
  }

  // Return whether a boot image has a profile. This means it's an in-memory
  // image rather that an image loaded from disk.
  bool HasImageWithProfile() const;

  // Trigger a flag reload from system properties or device congfigs.
  //
  // Should only be called from runtime init and zygote post fork as
  // we don't want to change the runtime config midway during execution.
  //
  // The caller argument should be the name of the function making this call
  // and will be used to enforce the appropriate names.
  //
  // See Flags::ReloadAllFlags as well.
  static void ReloadAllFlags(const std::string& caller);

  // Parses /apex/apex-info-list.xml to build a string containing apex versions of boot classpath
  // jars, which is encoded into .oat files.
  static std::string GetApexVersions(ArrayRef<const std::string> boot_class_path_locations);

 private:
  static void InitPlatformSignalHandlers();

  Runtime();

  void BlockSignals();

  bool Init(RuntimeArgumentMap&& runtime_options)
      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
  void InitNativeMethods() REQUIRES(!Locks::mutator_lock_);
  void RegisterRuntimeNativeMethods(JNIEnv* env);
  void InitMetrics();

  void StartDaemonThreads();
  void StartSignalCatcher();

  void MaybeSaveJitProfilingInfo();

  // Visit all of the thread roots.
  void VisitThreadRoots(RootVisitor* visitor, VisitRootFlags flags)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Visit all other roots which must be done with mutators suspended.
  void VisitNonConcurrentRoots(RootVisitor* visitor, VisitRootFlags flags)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Constant roots are the roots which never change after the runtime is initialized, they only
  // need to be visited once per GC cycle.
  void VisitConstantRoots(RootVisitor* visitor)
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Note: To be lock-free, GetFaultMessage temporarily replaces the lock message with null.
  //       As such, there is a window where a call will return an empty string. In general,
  //       only aborting code should retrieve this data (via GetFaultMessageForAbortLogging
  //       friend).
  std::string GetFaultMessage();

  ThreadPool* AcquireThreadPool() REQUIRES(!Locks::runtime_thread_pool_lock_);
  void ReleaseThreadPool() REQUIRES(!Locks::runtime_thread_pool_lock_);

  // Caches the apex versions produced by `GetApexVersions`.
  void InitializeApexVersions();

  // A pointer to the active runtime or null.
  static Runtime* instance_;

  // NOTE: these must match the gc::ProcessState values as they come directly from the framework.
  static constexpr int kProfileForground = 0;
  static constexpr int kProfileBackground = 1;

  static constexpr uint32_t kCalleeSaveSize = 6u;

  // 64 bit so that we can share the same asm offsets for both 32 and 64 bits.
  uint64_t callee_save_methods_[kCalleeSaveSize];
  // Pre-allocated exceptions (see Runtime::Init).
  GcRoot<mirror::Throwable> pre_allocated_OutOfMemoryError_when_throwing_exception_;
  GcRoot<mirror::Throwable> pre_allocated_OutOfMemoryError_when_throwing_oome_;
  GcRoot<mirror::Throwable> pre_allocated_OutOfMemoryError_when_handling_stack_overflow_;
  GcRoot<mirror::Throwable> pre_allocated_NoClassDefFoundError_;
  ArtMethod* resolution_method_;
  ArtMethod* imt_conflict_method_;
  // Unresolved method has the same behavior as the conflict method, it is used by the class linker
  // for differentiating between unfilled imt slots vs conflict slots in superclasses.
  ArtMethod* imt_unimplemented_method_;

  // Special sentinel object used to invalid conditions in JNI (cleared weak references) and
  // JDWP (invalid references).
  GcRoot<mirror::Object> sentinel_;

  InstructionSet instruction_set_;

  CompilerCallbacks* compiler_callbacks_;
  bool is_zygote_;
  bool is_primary_zygote_;
  bool is_system_server_;
  bool must_relocate_;
  bool is_concurrent_gc_enabled_;
  bool is_explicit_gc_disabled_;
  bool image_dex2oat_enabled_;

  std::string compiler_executable_;
  std::vector<std::string> compiler_options_;
  std::vector<std::string> image_compiler_options_;
  std::vector<std::string> image_locations_;

  std::vector<std::string> boot_class_path_;
  std::vector<std::string> boot_class_path_locations_;
  std::string boot_class_path_checksums_;
  std::vector<int> boot_class_path_fds_;
  std::vector<int> boot_class_path_image_fds_;
  std::vector<int> boot_class_path_vdex_fds_;
  std::vector<int> boot_class_path_oat_fds_;
  std::string class_path_string_;
  std::vector<std::string> properties_;

  std::list<ti::AgentSpec> agent_specs_;
  std::list<std::unique_ptr<ti::Agent>> agents_;
  std::vector<Plugin> plugins_;

  // The default stack size for managed threads created by the runtime.
  size_t default_stack_size_;

  // Finalizers running for longer than this many milliseconds abort the runtime.
  unsigned int finalizer_timeout_ms_;

  gc::Heap* heap_;

  std::unique_ptr<ArenaPool> jit_arena_pool_;
  std::unique_ptr<ArenaPool> arena_pool_;
  // Special low 4gb pool for compiler linear alloc. We need ArtFields to be in low 4gb if we are
  // compiling using a 32 bit image on a 64 bit compiler in case we resolve things in the image
  // since the field arrays are int arrays in this case.
  std::unique_ptr<ArenaPool> low_4gb_arena_pool_;

  // Shared linear alloc for now.
  std::unique_ptr<LinearAlloc> linear_alloc_;

  // The number of spins that are done before thread suspension is used to forcibly inflate.
  size_t max_spins_before_thin_lock_inflation_;
  MonitorList* monitor_list_;
  MonitorPool* monitor_pool_;

  ThreadList* thread_list_;

  InternTable* intern_table_;

  ClassLinker* class_linker_;

  SignalCatcher* signal_catcher_;

  SmallIrtAllocator* small_irt_allocator_;

  std::unique_ptr<jni::JniIdManager> jni_id_manager_;

  std::unique_ptr<JavaVMExt> java_vm_;

  std::unique_ptr<jit::Jit> jit_;
  std::unique_ptr<jit::JitCodeCache> jit_code_cache_;
  std::unique_ptr<jit::JitOptions> jit_options_;

  // Runtime thread pool. The pool is only for startup and gets deleted after.
  std::unique_ptr<ThreadPool> thread_pool_ GUARDED_BY(Locks::runtime_thread_pool_lock_);
  size_t thread_pool_ref_count_ GUARDED_BY(Locks::runtime_thread_pool_lock_);

  // Fault message, printed when we get a SIGSEGV. Stored as a native-heap object and accessed
  // lock-free, so needs to be atomic.
  std::atomic<std::string*> fault_message_;

  // A non-zero value indicates that a thread has been created but not yet initialized. Guarded by
  // the shutdown lock so that threads aren't born while we're shutting down.
  size_t threads_being_born_ GUARDED_BY(Locks::runtime_shutdown_lock_);

  // Waited upon until no threads are being born.
  std::unique_ptr<ConditionVariable> shutdown_cond_ GUARDED_BY(Locks::runtime_shutdown_lock_);

  // Set when runtime shutdown is past the point that new threads may attach.  Usually
  // GUARDED_BY(Locks::runtime_shutdown_lock_). But we need to check it in Abort without the
  // lock, because we may already own it.
  std::atomic<bool> shutting_down_;

  // The runtime is starting to shutdown but is blocked waiting on shutdown_cond_.
  bool shutting_down_started_ GUARDED_BY(Locks::runtime_shutdown_lock_);

  bool started_;

  // New flag added which tells us if the runtime has finished starting. If
  // this flag is set then the Daemon threads are created and the class loader
  // is created. This flag is needed for knowing if its safe to request CMS.
  bool finished_starting_;

  // Hooks supported by JNI_CreateJavaVM
  jint (*vfprintf_)(FILE* stream, const char* format, va_list ap);
  void (*exit_)(jint status);
  void (*abort_)();

  bool stats_enabled_;
  RuntimeStats stats_;

  const bool is_running_on_memory_tool_;

  std::unique_ptr<TraceConfig> trace_config_;

  instrumentation::Instrumentation instrumentation_;

  jobject main_thread_group_;
  jobject system_thread_group_;

  // As returned by ClassLoader.getSystemClassLoader().
  jobject system_class_loader_;

  // If true, then we dump the GC cumulative timings on shutdown.
  bool dump_gc_performance_on_shutdown_;

  // Transactions used for pre-initializing classes at compilation time.
  // Support nested transactions, maintain a list containing all transactions. Transactions are
  // handled under a stack discipline. Because GC needs to go over all transactions, we choose list
  // as substantial data structure instead of stack.
  std::forward_list<Transaction> preinitialization_transactions_;

  // If kNone, verification is disabled. kEnable by default.
  verifier::VerifyMode verify_;

  // List of supported cpu abis.
  std::vector<std::string> cpu_abilist_;

  // Specifies target SDK version to allow workarounds for certain API levels.
  uint32_t target_sdk_version_;

  // ART counterpart for the compat framework (go/compat-framework).
  CompatFramework compat_framework_;

  // Implicit checks flags.
  bool implicit_null_checks_;       // NullPointer checks are implicit.
  bool implicit_so_checks_;         // StackOverflow checks are implicit.
  bool implicit_suspend_checks_;    // Thread suspension checks are implicit.

  // Whether or not the sig chain (and implicitly the fault handler) should be
  // disabled. Tools like dex2oat don't need them. This enables
  // building a statically link version of dex2oat.
  bool no_sig_chain_;

  // Force the use of native bridge even if the app ISA matches the runtime ISA.
  bool force_native_bridge_;

  // Whether or not a native bridge has been loaded.
  //
  // The native bridge allows running native code compiled for a foreign ISA. The way it works is,
  // if standard dlopen fails to load native library associated with native activity, it calls to
  // the native bridge to load it and then gets the trampoline for the entry to native activity.
  //
  // The option 'native_bridge_library_filename' specifies the name of the native bridge.
  // When non-empty the native bridge will be loaded from the given file. An empty value means
  // that there's no native bridge.
  bool is_native_bridge_loaded_;

  // Whether we are running under native debugger.
  bool is_native_debuggable_;

  // whether or not any async exceptions have ever been thrown. This is used to speed up the
  // MterpShouldSwitchInterpreters function.
  bool async_exceptions_thrown_;

  // Whether anything is going to be using the shadow-frame APIs to force a function to return
  // early. Doing this requires that (1) we be debuggable and (2) that mterp is exited.
  bool non_standard_exits_enabled_;

  // Whether Java code needs to be debuggable.
  bool is_java_debuggable_;

  bool monitor_timeout_enable_;
  uint64_t monitor_timeout_ns_;

  // Whether or not this application can be profiled by the shell user,
  // even when running on a device that is running in user mode.
  bool is_profileable_from_shell_ = false;

  // Whether or not this application can be profiled by system services on a
  // device running in user mode, but not necessarily by the shell user.
  bool is_profileable_ = false;

  // The maximum number of failed boots we allow before pruning the dalvik cache
  // and trying again. This option is only inspected when we're running as a
  // zygote.
  uint32_t zygote_max_failed_boots_;

  // Enable experimental opcodes that aren't fully specified yet. The intent is to
  // eventually publish them as public-usable opcodes, but they aren't ready yet.
  //
  // Experimental opcodes should not be used by other production code.
  ExperimentalFlags experimental_flags_;

  // Contains the build fingerprint, if given as a parameter.
  std::string fingerprint_;

  // Oat file manager, keeps track of what oat files are open.
  OatFileManager* oat_file_manager_;

  // Whether or not we are on a low RAM device.
  bool is_low_memory_mode_;

  // Whether or not we use MADV_RANDOM on files that are thought to have random access patterns.
  // This is beneficial for low RAM devices since it reduces page cache thrashing.
  bool madvise_random_access_;

  // Limiting size (in bytes) for applying MADV_WILLNEED on vdex files
  // A 0 for this will turn off madvising to MADV_WILLNEED
  size_t madvise_willneed_vdex_filesize_;

  // Limiting size (in bytes) for applying MADV_WILLNEED on odex files
  // A 0 for this will turn off madvising to MADV_WILLNEED
  size_t madvise_willneed_odex_filesize_;

  // Limiting size (in bytes) for applying MADV_WILLNEED on art files
  // A 0 for this will turn off madvising to MADV_WILLNEED
  size_t madvise_willneed_art_filesize_;

  // Whether the application should run in safe mode, that is, interpreter only.
  bool safe_mode_;

  // Whether access checks on hidden API should be performed.
  hiddenapi::EnforcementPolicy hidden_api_policy_;

  // Whether access checks on core platform API should be performed.
  hiddenapi::EnforcementPolicy core_platform_api_policy_;

  // Whether access checks on test API should be performed.
  hiddenapi::EnforcementPolicy test_api_policy_;

  // List of signature prefixes of methods that have been removed from the blocklist, and treated
  // as if SDK.
  std::vector<std::string> hidden_api_exemptions_;

  // Do not warn about the same hidden API access violation twice.
  // This is only used for testing.
  bool dedupe_hidden_api_warnings_;

  // How often to log hidden API access to the event log. An integer between 0
  // (never) and 0x10000 (always).
  uint32_t hidden_api_access_event_log_rate_;

  // The package of the app running in this process.
  std::string process_package_name_;

  // The data directory of the app running in this process.
  std::string process_data_directory_;

  // Whether threads should dump their native stack on SIGQUIT.
  bool dump_native_stack_on_sig_quit_;

  // Whether or not we currently care about pause times.
  ProcessState process_state_;

  // Whether zygote code is in a section that should not start threads.
  bool zygote_no_threads_;

  // The string containing requested jdwp options
  std::string jdwp_options_;

  // The jdwp provider we were configured with.
  JdwpProvider jdwp_provider_;

  // True if jmethodID and jfieldID are opaque Indices. When false (the default) these are simply
  // pointers. This is set by -Xopaque-jni-ids:{true,false}.
  JniIdType jni_ids_indirection_;

  // Set to false in cases where we want to directly control when jni-id
  // indirection is changed. This is intended only for testing JNI id swapping.
  bool automatically_set_jni_ids_indirection_;

  // True if files in /data/misc/apexdata/com.android.art are considered untrustworthy.
  bool deny_art_apex_data_files_;

  // Saved environment.
  class EnvSnapshot {
   public:
    EnvSnapshot() = default;
    void TakeSnapshot();
    char** GetSnapshot() const;

   private:
    std::unique_ptr<char*[]> c_env_vector_;
    std::vector<std::unique_ptr<std::string>> name_value_pairs_;

    DISALLOW_COPY_AND_ASSIGN(EnvSnapshot);
  } env_snapshot_;

  // Generic system-weak holders.
  std::vector<gc::AbstractSystemWeakHolder*> system_weak_holders_;

  std::unique_ptr<RuntimeCallbacks> callbacks_;

  std::atomic<uint32_t> deoptimization_counts_[
      static_cast<uint32_t>(DeoptimizationKind::kLast) + 1];

  MemMap protected_fault_page_;

  uint32_t verifier_logging_threshold_ms_;

  bool load_app_image_startup_cache_ = false;

  // If startup has completed, must happen at most once.
  std::atomic<bool> startup_completed_ = false;

  bool verifier_missing_kthrow_fatal_;
  bool force_java_zygote_fork_loop_;
  bool perfetto_hprof_enabled_;
  bool perfetto_javaheapprof_enabled_;

  metrics::ArtMetrics metrics_;
  std::unique_ptr<metrics::MetricsReporter> metrics_reporter_;

  // Apex versions of boot classpath jars concatenated in a string. The format
  // is of the type:
  // '/apex1_version/apex2_version//'
  //
  // When the apex is the factory version, we don't encode it (for example in
  // the third entry in the example above).
  std::string apex_versions_;

  // The info about the application code paths.
  AppInfo app_info_;

  // Note: See comments on GetFaultMessage.
  friend std::string GetFaultMessageForAbortLogging();
  friend class Dex2oatImageTest;
  friend class ScopedThreadPoolUsage;
  friend class OatFileAssistantTest;
  class NotifyStartupCompletedTask;

  DISALLOW_COPY_AND_ASSIGN(Runtime);
};

inline metrics::ArtMetrics* GetMetrics() { return Runtime::Current()->GetMetrics(); }

}  // namespace art

#endif  // ART_RUNTIME_RUNTIME_H_
