Global lock levels.
Introduce the notion of the mutators/GC being a shared-exclusive (aka
reader-writer) lock. Introduce globally ordered locks, analysable by
annotalysis, statically at compile time. Add locking attributes to
methods.
More subtly, remove the heap_lock_ and split between various locks that
are held for smaller periods (where work doesn't get blocked). Remove
buggy Dalvik style thread transitions. Make GC use CMS in all cases when
concurrent is enabled. Fix bug where suspend counts rather than debug
suspend counts were sent to JDWP. Move the PathClassLoader to
WellKnownClasses. In debugger refactor calls to send request and
possibly suspend. Break apart different VmWait thread states. Move
identity hash code to a shared method.
Change-Id: Icdbfc3ce3fcccd14341860ac7305d8e97b51f5c6
diff --git a/src/runtime.h b/src/runtime.h
index 544dcf4..3b9919c 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -28,6 +28,7 @@
#include "globals.h"
#include "heap.h"
#include "instruction_set.h"
+#include "jobject_comparator.h"
#include "macros.h"
#include "runtime_stats.h"
#include "safe_map.h"
@@ -95,7 +96,8 @@
};
// Creates and initializes a new runtime.
- static Runtime* Create(const Options& options, bool ignore_unrecognized);
+ static bool Create(const Options& options, bool ignore_unrecognized)
+ SHARED_TRYLOCK_FUNCTION(true, GlobalSynchronization::mutator_lock_);
bool IsCompiler() const {
return is_compiler_;
@@ -115,7 +117,7 @@
}
// Starts a runtime, which may cause threads to be started and code to run.
- void Start();
+ void Start() UNLOCK_FUNCTION(GlobalSynchronization::mutator_lock_);
bool IsShuttingDown() const {
return shutting_down_;
@@ -138,7 +140,7 @@
// This isn't marked ((noreturn)) because then gcc will merge multiple calls
// in a single function together. This reduces code size slightly, but means
// that the native stack trace we get may point at the wrong call site.
- static void Abort();
+ static void Abort() LOCKS_EXCLUDED(GlobalSynchronization::abort_lock_);
// Returns the "main" ThreadGroup, used when attaching user threads.
jobject GetMainThreadGroup() const;
@@ -152,9 +154,10 @@
void CallExitHook(jint status);
// Detaches the current native thread from the runtime.
- void DetachCurrentThread();
+ void DetachCurrentThread() LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_);
- void DumpForSigQuit(std::ostream& os);
+ void DumpForSigQuit(std::ostream& os)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
void DumpLockHolders(std::ostream& os);
~Runtime();
@@ -207,7 +210,8 @@
return "2.0.0";
}
- void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
+ void VisitRoots(Heap::RootVisitor* visitor, void* arg) const
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
bool HasJniDlsymLookupStub() const {
return jni_stub_array_ != NULL;
@@ -263,7 +267,7 @@
resolution_method_ = method;
}
- Method* CreateResolutionMethod();
+ Method* CreateResolutionMethod() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
// Returns a special method that describes all callee saves being spilled to the stack.
enum CalleeSaveType {
@@ -284,10 +288,14 @@
void SetCalleeSaveMethod(Method* method, CalleeSaveType type);
- Method* CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type);
+ Method* CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
- Method* CreateRefOnlyCalleeSaveMethod(InstructionSet instruction_set);
- Method* CreateRefAndArgsCalleeSaveMethod(InstructionSet instruction_set);
+ Method* CreateRefOnlyCalleeSaveMethod(InstructionSet instruction_set)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+
+ Method* CreateRefAndArgsCalleeSaveMethod(InstructionSet instruction_set)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
int32_t GetStat(int kind);
@@ -322,8 +330,8 @@
return use_compile_time_class_path_;
}
- const std::vector<const DexFile*>& GetCompileTimeClassPath(const ClassLoader* class_loader);
- void SetCompileTimeClassPath(const ClassLoader* class_loader, std::vector<const DexFile*>& class_path);
+ const std::vector<const DexFile*>& GetCompileTimeClassPath(jobject class_loader);
+ void SetCompileTimeClassPath(jobject class_loader, std::vector<const DexFile*>& class_path);
private:
static void InitPlatformSignalHandlers();
@@ -332,8 +340,9 @@
void BlockSignals();
- bool Init(const Options& options, bool ignore_unrecognized);
- void InitNativeMethods();
+ bool Init(const Options& options, bool ignore_unrecognized)
+ SHARED_TRYLOCK_FUNCTION(true, GlobalSynchronization::mutator_lock_);
+ void InitNativeMethods() LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_);
void InitThreadGroups(Thread* self);
void RegisterRuntimeNativeMethods(JNIEnv* env);
@@ -417,7 +426,7 @@
size_t method_trace_file_size_;
Trace* tracer_;
- typedef SafeMap<const ClassLoader*, std::vector<const DexFile*> > CompileTimeClassPaths;
+ typedef SafeMap<jobject, std::vector<const DexFile*>, JobjectComparator> CompileTimeClassPaths;
CompileTimeClassPaths compile_time_class_paths_;
bool use_compile_time_class_path_;