From 590fee9e8972f872301c2d16a575d579ee564bee Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Fri, 13 Sep 2013 13:46:47 -0700 Subject: Compacting collector. The compacting collector is currently similar to semispace. It works by copying objects back and forth between two bump pointer spaces. There are types of objects which are "non-movable" due to current runtime limitations. These are Classes, Methods, and Fields. Bump pointer spaces are a new type of continuous alloc space which have no lock in the allocation code path. When you allocate from these it uses atomic operations to increase an index. Traversing the objects in the bump pointer space relies on Object::SizeOf matching the allocated size exactly. Runtime changes: JNI::GetArrayElements returns copies objects if you attempt to get the backing data of a movable array. For GetArrayElementsCritical, we return direct backing storage for any types of arrays, but temporarily disable the GC until the critical region is completed. Added a new runtime call called VisitObjects, this is used in place of the old pattern which was flushing the allocation stack and walking the bitmaps. Changed image writer to be compaction safe and use object monitor word for forwarding addresses. Added a bunch of added SIRTs to ClassLinker, MethodLinker, etc.. TODO: Enable switching allocators, compacting on background, etc.. Bug: 8981901 Change-Id: I3c886fd322a6eef2b99388d19a765042ec26ab99 --- runtime/base/mutex-inl.h | 2 +- runtime/base/mutex.cc | 6 ++---- runtime/base/mutex.h | 5 +++++ runtime/base/timing_logger.cc | 5 +++++ runtime/base/timing_logger.h | 1 + 5 files changed, 14 insertions(+), 5 deletions(-) (limited to 'runtime/base') diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h index c0cfee2..29b3981 100644 --- a/runtime/base/mutex-inl.h +++ b/runtime/base/mutex-inl.h @@ -130,7 +130,7 @@ static inline void CheckUnattachedThread(LockLevel level) NO_THREAD_SAFETY_ANALY // TODO: tighten this check. if (kDebugLocking) { Runtime* runtime = Runtime::Current(); - CHECK(runtime == NULL || !runtime->IsStarted() || runtime->IsShuttingDown() || + CHECK(runtime == NULL || !runtime->IsStarted() || runtime->IsShuttingDownLocked() || level == kDefaultMutexLevel || level == kRuntimeShutdownLock || level == kThreadListLock || level == kLoggingLock || level == kAbortLock); } diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index 249f031..1c7d744 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -266,9 +266,8 @@ Mutex::Mutex(const char* name, LockLevel level, bool recursive) Mutex::~Mutex() { #if ART_USE_FUTEXES if (state_ != 0) { - MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_); Runtime* runtime = Runtime::Current(); - bool shutting_down = (runtime == NULL) || runtime->IsShuttingDown(); + bool shutting_down = runtime == nullptr || runtime->IsShuttingDown(Thread::Current()); LOG(shutting_down ? WARNING : FATAL) << "destroying mutex with owner: " << exclusive_owner_; } else { CHECK_EQ(exclusive_owner_, 0U) << "unexpectedly found an owner on unlocked mutex " << name_; @@ -641,9 +640,8 @@ ConditionVariable::ConditionVariable(const char* name, Mutex& guard) ConditionVariable::~ConditionVariable() { #if ART_USE_FUTEXES if (num_waiters_!= 0) { - MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_); Runtime* runtime = Runtime::Current(); - bool shutting_down = (runtime == NULL) || runtime->IsShuttingDown(); + bool shutting_down = runtime == nullptr || runtime->IsShuttingDown(Thread::Current()); LOG(shutting_down ? WARNING : FATAL) << "ConditionVariable::~ConditionVariable for " << name_ << " called with " << num_waiters_ << " waiters."; } diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h index feb8a6c..a875017 100644 --- a/runtime/base/mutex.h +++ b/runtime/base/mutex.h @@ -329,6 +329,11 @@ class ConditionVariable { // TODO: remove this. void WaitHoldingLocks(Thread* self) NO_THREAD_SAFETY_ANALYSIS; + // Return the number of people that are waiting on this condition. + int32_t GetNumWaiters() const NO_THREAD_SAFETY_ANALYSIS { + return num_waiters_; + } + private: const char* const name_; // The Mutex being used by waiters. It is an error to mix condition variables between different diff --git a/runtime/base/timing_logger.cc b/runtime/base/timing_logger.cc index 6df1126..45a546f 100644 --- a/runtime/base/timing_logger.cc +++ b/runtime/base/timing_logger.cc @@ -86,6 +86,11 @@ void CumulativeLogger::AddLogger(const base::TimingLogger &logger) { } } +size_t CumulativeLogger::GetIterations() const { + MutexLock mu(Thread::Current(), lock_); + return iterations_; +} + void CumulativeLogger::Dump(std::ostream &os) { MutexLock mu(Thread::Current(), lock_); DumpHistogram(os); diff --git a/runtime/base/timing_logger.h b/runtime/base/timing_logger.h index 07d1ee0..501d2d7 100644 --- a/runtime/base/timing_logger.h +++ b/runtime/base/timing_logger.h @@ -45,6 +45,7 @@ class CumulativeLogger { // parent class that is unable to determine the "name" of a sub-class. void SetName(const std::string& name); void AddLogger(const base::TimingLogger& logger) LOCKS_EXCLUDED(lock_); + size_t GetIterations() const; private: typedef std::map *> Histograms; -- cgit v1.1