summaryrefslogtreecommitdiff
path: root/runtime/runtime.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/runtime.h')
-rw-r--r--runtime/runtime.h195
1 files changed, 151 insertions, 44 deletions
diff --git a/runtime/runtime.h b/runtime/runtime.h
index e7b71e29f5..fc8c050cf1 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -68,6 +68,10 @@ class JitCodeCache;
class JitOptions;
} // namespace jit
+namespace jni {
+class SmallLrtAllocator;
+} // namespace jni
+
namespace mirror {
class Array;
class ClassLoader;
@@ -107,7 +111,6 @@ class Plugin;
struct RuntimeArgumentMap;
class RuntimeCallbacks;
class SignalCatcher;
-class SmallIrtAllocator;
class StackOverflowHandler;
class SuspensionHandler;
class ThreadList;
@@ -133,6 +136,19 @@ class Runtime {
static bool Create(const RuntimeOptions& raw_options, bool ignore_unrecognized)
SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
+ enum class RuntimeDebugState {
+ // This doesn't support any debug features / method tracing. This is the expected state usually.
+ kNonJavaDebuggable,
+ // This supports method tracing and a restricted set of debug features (for ex: redefinition
+ // isn't supported). We transition to this state when method tracing has started or when the
+ // debugger was attached and transition back to NonDebuggable once the tracing has stopped /
+ // the debugger agent has detached..
+ kJavaDebuggable,
+ // The runtime was started as a debuggable runtime. This allows us to support the extended set
+ // of debug features (for ex: redefinition). We never transition out of this state.
+ kJavaDebuggableAtInit
+ };
+
bool EnsurePluginLoaded(const char* plugin_name, std::string* error_msg);
bool EnsurePerfettoPlugin(std::string* error_msg);
@@ -257,6 +273,13 @@ class Runtime {
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_);
@@ -271,13 +294,16 @@ class Runtime {
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);
+ bool AttachCurrentThread(const char* thread_name,
+ bool as_daemon,
+ jobject thread_group,
+ bool create_peer,
+ bool should_run_callbacks = true);
void CallExitHook(jint status);
// Detaches the current native thread from the runtime.
- void DetachCurrentThread() REQUIRES(!Locks::mutator_lock_);
+ void DetachCurrentThread(bool should_run_callbacks = true) REQUIRES(!Locks::mutator_lock_);
void DumpDeoptimizations(std::ostream& os);
void DumpForSigQuit(std::ostream& os);
@@ -295,6 +321,28 @@ class Runtime {
return boot_class_path_locations_.empty() ? boot_class_path_ : boot_class_path_locations_;
}
+ // Dynamically adds an element to boot class path.
+ void AppendToBootClassPath(const std::string& filename,
+ const std::string& location,
+ const std::vector<std::unique_ptr<const art::DexFile>>& dex_files);
+
+ // Same as above, but takes raw pointers.
+ void AppendToBootClassPath(const std::string& filename,
+ const std::string& location,
+ const std::vector<const art::DexFile*>& dex_files);
+
+ // Same as above, but also takes a dex cache for each dex file.
+ void AppendToBootClassPath(
+ const std::string& filename,
+ const std::string& location,
+ const std::vector<std::pair<const art::DexFile*, ObjPtr<mirror::DexCache>>>&
+ dex_files_and_cache);
+
+ // Dynamically adds an element to boot class path and takes ownership of the dex files.
+ void AddExtraBootDexFiles(const std::string& filename,
+ const std::string& location,
+ std::vector<std::unique_ptr<const art::DexFile>>&& dex_files);
+
const std::vector<int>& GetBootClassPathFds() const {
return boot_class_path_fds_;
}
@@ -325,8 +373,8 @@ class Runtime {
return class_linker_;
}
- SmallIrtAllocator* GetSmallIrtAllocator() const {
- return small_irt_allocator_;
+ jni::SmallLrtAllocator* GetSmallLrtAllocator() const {
+ return small_lrt_allocator_;
}
jni::JniIdManager* GetJniIdManager() const {
@@ -430,8 +478,7 @@ class Runtime {
// 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_);
+ 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.
@@ -498,6 +545,10 @@ class Runtime {
return OFFSETOF_MEMBER(Runtime, callee_save_methods_[static_cast<size_t>(type)]);
}
+ static constexpr MemberOffset GetInstrumentationOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(Runtime, instrumentation_));
+ }
+
InstructionSet GetInstructionSet() const {
return instruction_set_;
}
@@ -567,7 +618,8 @@ class Runtime {
// Transaction support.
bool IsActiveTransaction() const;
- void EnterTransactionMode(bool strict, mirror::Class* root);
+ // EnterTransactionMode may suspend.
+ void EnterTransactionMode(bool strict, mirror::Class* root) REQUIRES_SHARED(Locks::mutator_lock_);
void ExitTransactionMode();
void RollbackAllTransactions() REQUIRES_SHARED(Locks::mutator_lock_);
// Transaction rollback and exit transaction are always done together, it's convenience to
@@ -752,6 +804,9 @@ class Runtime {
// Create the JIT and instrumentation and code cache.
void CreateJit();
+ ArenaPool* GetLinearAllocArenaPool() {
+ return linear_alloc_arena_pool_.get();
+ }
ArenaPool* GetArenaPool() {
return arena_pool_.get();
}
@@ -768,12 +823,21 @@ class Runtime {
return linear_alloc_.get();
}
+ LinearAlloc* GetStartupLinearAlloc() {
+ return startup_linear_alloc_.load(std::memory_order_relaxed);
+ }
+
jit::JitOptions* GetJITOptions() {
return jit_options_.get();
}
bool IsJavaDebuggable() const {
- return is_java_debuggable_;
+ return runtime_debug_state_ == RuntimeDebugState::kJavaDebuggable ||
+ runtime_debug_state_ == RuntimeDebugState::kJavaDebuggableAtInit;
+ }
+
+ bool IsJavaDebuggableAtInit() const {
+ return runtime_debug_state_ == RuntimeDebugState::kJavaDebuggableAtInit;
}
void SetProfileableFromShell(bool value) {
@@ -792,7 +856,7 @@ class Runtime {
return is_profileable_;
}
- void SetJavaDebuggable(bool value);
+ void SetRuntimeDebugState(RuntimeDebugState state);
// Deoptimize the boot image, called for Java debuggable apps.
void DeoptimizeBootImage() REQUIRES(Locks::mutator_lock_);
@@ -842,14 +906,13 @@ class Runtime {
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();
+ // Setup linear-alloc allocators to stop using the current arena so that the
+ // next allocations, which would be after zygote fork, happens in userfaultfd
+ // visited space.
+ void SetupLinearAllocForPostZygoteFork(Thread* self)
+ REQUIRES(!Locks::mutator_lock_, !Locks::classlinker_classes_lock_);
OatFileManager& GetOatFileManager() const {
DCHECK(oat_file_manager_ != nullptr);
@@ -890,7 +953,8 @@ class Runtime {
// 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_);
+ bool IsAsyncDeoptimizeable(ArtMethod* method, 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.
@@ -940,14 +1004,8 @@ class Runtime {
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 GetMadviseWillNeedTotalDexSize() const {
+ return madvise_willneed_total_dex_size_;
}
size_t GetMadviseWillNeedSizeOdex() const {
@@ -1004,6 +1062,10 @@ class Runtime {
ThreadPool* const thread_pool_;
};
+ LinearAlloc* ReleaseStartupLinearAlloc() {
+ return startup_linear_alloc_.exchange(nullptr, std::memory_order_relaxed);
+ }
+
bool LoadAppImageStartupCache() const {
return load_app_image_startup_cache_;
}
@@ -1017,8 +1079,8 @@ class Runtime {
void ResetStartupCompleted();
// Notify the runtime that application startup is considered completed. Only has effect for the
- // first call.
- void NotifyStartupCompleted();
+ // first call. Returns whether this was the first call.
+ bool 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.
@@ -1050,7 +1112,11 @@ class Runtime {
uint64_t GetMonitorTimeoutNs() const {
return monitor_timeout_ns_;
}
- // Return true if we should load oat files as executable or not.
+
+ // Return whether this is system server and it is being profiled.
+ bool IsSystemServerProfiled() const;
+
+ // Return whether we should load oat files as executable or not.
bool GetOatFilesExecutable() const;
metrics::ArtMetrics* GetMetrics() { return &metrics_; }
@@ -1073,6 +1139,14 @@ class Runtime {
// image rather that an image loaded from disk.
bool HasImageWithProfile() const;
+ bool GetNoSigChain() const {
+ return no_sig_chain_;
+ }
+
+ void AddGeneratedCodeRange(const void* start, size_t size);
+ void RemoveGeneratedCodeRange(const void* start, size_t size)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Trigger a flag reload from system properties or device congfigs.
//
// Should only be called from runtime init and zygote post fork as
@@ -1084,11 +1158,33 @@ class Runtime {
// 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);
+
+ bool AllowInMemoryCompilation() const { return allow_in_memory_compilation_; }
+
+ // Used by plugin code to attach a hook for OOME.
+ void SetOutOfMemoryErrorHook(void (*hook)()) {
+ out_of_memory_error_hook_ = hook;
+ }
+
+ void OutOfMemoryErrorHook() {
+ if (out_of_memory_error_hook_ != nullptr) {
+ out_of_memory_error_hook_();
+ }
+ }
+
private:
static void InitPlatformSignalHandlers();
Runtime();
+ bool HandlesSignalsInCompiledCode() const {
+ return !no_sig_chain_ &&
+ (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_);
+ }
+
void BlockSignals();
bool Init(RuntimeArgumentMap&& runtime_options)
@@ -1097,7 +1193,7 @@ class Runtime {
void RegisterRuntimeNativeMethods(JNIEnv* env);
void InitMetrics();
- void StartDaemonThreads();
+ void StartDaemonThreads() REQUIRES_SHARED(Locks::mutator_lock_);
void StartSignalCatcher();
void MaybeSaveJitProfilingInfo();
@@ -1124,10 +1220,11 @@ class Runtime {
ThreadPool* AcquireThreadPool() REQUIRES(!Locks::runtime_thread_pool_lock_);
void ReleaseThreadPool() REQUIRES(!Locks::runtime_thread_pool_lock_);
- // Parses /apex/apex-info-list.xml to initialize a string containing versions
- // of boot classpath jars and encoded into .oat files.
+ // Caches the apex versions produced by `GetApexVersions`.
void InitializeApexVersions();
+ void AppendToBootClassPath(const std::string& filename, const std::string& location);
+
// A pointer to the active runtime or null.
static Runtime* instance_;
@@ -1194,14 +1291,21 @@ class Runtime {
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_;
+ // This pool is used for linear alloc if we are using userfaultfd GC, or if
+ // low 4gb pool is required for compiler linear alloc. Otherwise, use
+ // arena_pool_.
+ // 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> linear_alloc_arena_pool_;
// Shared linear alloc for now.
std::unique_ptr<LinearAlloc> linear_alloc_;
+ // Linear alloc used for allocations during startup. Will be deleted after
+ // startup. Atomic because the pointer can be concurrently updated to null.
+ std::atomic<LinearAlloc*> startup_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_;
@@ -1215,7 +1319,7 @@ class Runtime {
SignalCatcher* signal_catcher_;
- SmallIrtAllocator* small_irt_allocator_;
+ jni::SmallLrtAllocator* small_lrt_allocator_;
std::unique_ptr<jni::JniIdManager> jni_id_manager_;
@@ -1332,7 +1436,7 @@ class Runtime {
bool non_standard_exits_enabled_;
// Whether Java code needs to be debuggable.
- bool is_java_debuggable_;
+ RuntimeDebugState runtime_debug_state_;
bool monitor_timeout_enable_;
uint64_t monitor_timeout_ns_;
@@ -1365,13 +1469,10 @@ class Runtime {
// 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
+ // or uncompressed dex files in APKs.
// A 0 for this will turn off madvising to MADV_WILLNEED
- size_t madvise_willneed_vdex_filesize_;
+ size_t madvise_willneed_total_dex_size_;
// Limiting size (in bytes) for applying MADV_WILLNEED on odex files
// A 0 for this will turn off madvising to MADV_WILLNEED
@@ -1437,6 +1538,9 @@ class Runtime {
// True if files in /data/misc/apexdata/com.android.art are considered untrustworthy.
bool deny_art_apex_data_files_;
+ // Whether to allow compiling the boot classpath in memory when the given boot image is unusable.
+ bool allow_in_memory_compilation_ = false;
+
// Saved environment.
class EnvSnapshot {
public:
@@ -1473,6 +1577,9 @@ class Runtime {
bool perfetto_hprof_enabled_;
bool perfetto_javaheapprof_enabled_;
+ // Called on out of memory error
+ void (*out_of_memory_error_hook_)();
+
metrics::ArtMetrics metrics_;
std::unique_ptr<metrics::MetricsReporter> metrics_reporter_;
@@ -1492,7 +1599,7 @@ class Runtime {
friend class Dex2oatImageTest;
friend class ScopedThreadPoolUsage;
friend class OatFileAssistantTest;
- class NotifyStartupCompletedTask;
+ class SetupLinearAllocForZygoteFork;
DISALLOW_COPY_AND_ASSIGN(Runtime);
};