summaryrefslogtreecommitdiffstats
path: root/runtime/runtime.cc
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2013-09-12 21:33:12 -0700
committerHiroshi Yamauchi <yamauchi@google.com>2013-09-25 20:28:49 -0700
commit3b4c18933c24b8a33f38573c2ebcdb9aa16efeb5 (patch)
tree5298ccd9c1f1f6b329c0cb6cefac6a8df43dd633 /runtime/runtime.cc
parentf7e090ebcded6d6693894c018d89c4add79253ff (diff)
downloadart-3b4c18933c24b8a33f38573c2ebcdb9aa16efeb5.zip
art-3b4c18933c24b8a33f38573c2ebcdb9aa16efeb5.tar.gz
art-3b4c18933c24b8a33f38573c2ebcdb9aa16efeb5.tar.bz2
Split the allocation path into 'instrumented' and 'uninstrumented'
ones. The instrumented path is equivalent to the existing allocation path that checks for three instrumentation mechanisms (the debugger allocation tracking, the runtime allocation stats collection, and valgrind) for every allocation. The uinstrumented path does not perform these checks. We use the uninstrumented path by default and enable the instrumented path only when any of the three mechanisms is enabled. The uninstrumented version of Heap::AllocObject() is inlined. This change improves the Ritz MemAllocTest by ~4% on Nexus 4 and ~3% on Host/x86. Bug: 9986565 Change-Id: I3e68dfff6789d77bbdcea98457b694e1b5fcef5f
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r--runtime/runtime.cc48
1 files changed, 47 insertions, 1 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 86a8f1b..b4ce37f 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -99,7 +99,8 @@ Runtime::Runtime()
instrumentation_(),
use_compile_time_class_path_(false),
main_thread_group_(NULL),
- system_thread_group_(NULL) {
+ system_thread_group_(NULL),
+ quick_alloc_entry_points_instrumentation_counter_(0) {
for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
callee_save_methods_[i] = NULL;
}
@@ -1055,6 +1056,9 @@ void Runtime::SetStatsEnabled(bool new_state) {
GetStats()->Clear(~0);
// TODO: wouldn't it make more sense to clear _all_ threads' stats?
Thread::Current()->GetStats()->Clear(~0);
+ InstrumentQuickAllocEntryPoints();
+ } else {
+ UninstrumentQuickAllocEntryPoints();
}
stats_enabled_ = new_state;
}
@@ -1282,4 +1286,46 @@ void Runtime::SetCompileTimeClassPath(jobject class_loader, std::vector<const De
compile_time_class_paths_.Put(class_loader, class_path);
}
+static void ResetQuickAllocEntryPointsForThread(Thread* thread, void* arg) {
+ thread->ResetQuickAllocEntryPointsForThread();
+}
+
+void SetQuickAllocEntryPointsInstrumented(bool instrumented);
+
+void Runtime::InstrumentQuickAllocEntryPoints() {
+ ThreadList* tl = thread_list_;
+ Thread* self = Thread::Current();
+ tl->SuspendAll();
+ {
+ MutexLock mu(self, *Locks::runtime_shutdown_lock_);
+ MutexLock mu2(self, *Locks::thread_list_lock_);
+ DCHECK_LE(quick_alloc_entry_points_instrumentation_counter_, 0);
+ int old_counter = quick_alloc_entry_points_instrumentation_counter_++;
+ if (old_counter == 0) {
+ // If it was disabled, enable it.
+ SetQuickAllocEntryPointsInstrumented(true);
+ tl->ForEach(ResetQuickAllocEntryPointsForThread, NULL);
+ }
+ }
+ tl->ResumeAll();
+}
+
+void Runtime::UninstrumentQuickAllocEntryPoints() {
+ ThreadList* tl = thread_list_;
+ Thread* self = Thread::Current();
+ tl->SuspendAll();
+ {
+ MutexLock mu(self, *Locks::runtime_shutdown_lock_);
+ MutexLock mu2(self, *Locks::thread_list_lock_);
+ DCHECK_LT(quick_alloc_entry_points_instrumentation_counter_, 0);
+ int new_counter = --quick_alloc_entry_points_instrumentation_counter_;
+ if (new_counter == 0) {
+ // Disable it if the counter becomes zero.
+ SetQuickAllocEntryPointsInstrumented(false);
+ tl->ForEach(ResetQuickAllocEntryPointsForThread, NULL);
+ }
+ }
+ tl->ResumeAll();
+}
+
} // namespace art