diff options
| -rw-r--r-- | compiler/oat_writer.h | 2 | ||||
| -rw-r--r-- | dex2oat/dex2oat.cc | 21 | ||||
| -rw-r--r-- | runtime/gc/collector/mark_sweep.cc | 22 | ||||
| -rw-r--r-- | runtime/gc/collector/mark_sweep.h | 7 | ||||
| -rw-r--r-- | runtime/locks.h | 1 | ||||
| -rw-r--r-- | runtime/thread.cc | 8 |
6 files changed, 30 insertions, 31 deletions
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h index f7801f5d7f..8111c9f7a0 100644 --- a/compiler/oat_writer.h +++ b/compiler/oat_writer.h @@ -66,7 +66,7 @@ class OatWriter { uint32_t image_file_location_oat_checksum, uint32_t image_file_location_oat_begin, const std::string& image_file_location, - const CompilerDriver* compiler) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const CompilerDriver* compiler); const OatHeader& GetOatHeader() const { return *oat_header_; diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 29514444c9..8ec13bf4b5 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -232,18 +232,18 @@ class Dex2Oat { bool image, UniquePtr<CompilerDriver::DescriptorSet>& image_classes, bool dump_stats, - base::TimingLogger& timings) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + base::TimingLogger& timings) { // SirtRef and ClassLoader creation needs to come after Runtime::Create jobject class_loader = NULL; + Thread* self = Thread::Current(); if (!boot_image_option.empty()) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); std::vector<const DexFile*> class_path_files(dex_files); OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files); + ScopedObjectAccess soa(self); for (size_t i = 0; i < class_path_files.size(); i++) { class_linker->RegisterDexFile(*class_path_files[i]); } - ScopedObjectAccessUnchecked soa(Thread::Current()); soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader); ScopedLocalRef<jobject> class_loader_local(soa.Env(), soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader)); @@ -262,13 +262,8 @@ class Dex2Oat { driver->SetBitcodeFileName(bitcode_filename); } - - Thread::Current()->TransitionFromRunnableToSuspended(kNative); - driver->CompileAll(class_loader, dex_files, timings); - Thread::Current()->TransitionFromSuspendedToRunnable(); - timings.NewSplit("dex2oat OatWriter"); std::string image_file_location; uint32_t image_file_location_oat_checksum = 0; @@ -864,8 +859,9 @@ static int dex2oat(int argc, char** argv) { } UniquePtr<Dex2Oat> dex2oat(p_dex2oat); // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, - // give it away now and then switch to a more managable ScopedObjectAccess. - Thread::Current()->TransitionFromRunnableToSuspended(kNative); + // give it away now so that we don't starve GC. + Thread* self = Thread::Current(); + self->TransitionFromRunnableToSuspended(kNative); // If we're doing the image, override the compiler filter to force full compilation. Must be // done ahead of WellKnownClasses::Init that causes verification. Note: doesn't force // compilation of class initializers. @@ -873,8 +869,7 @@ static int dex2oat(int argc, char** argv) { Runtime::Current()->SetCompilerFilter(Runtime::kEverything); } // Whilst we're in native take the opportunity to initialize well known classes. - WellKnownClasses::Init(Thread::Current()->GetJniEnv()); - ScopedObjectAccess soa(Thread::Current()); + WellKnownClasses::Init(self->GetJniEnv()); // If --image-classes was specified, calculate the full list of classes to include in the image UniquePtr<CompilerDriver::DescriptorSet> image_classes(NULL); @@ -1004,13 +999,11 @@ static int dex2oat(int argc, char** argv) { // if (image) { timings.NewSplit("dex2oat ImageWriter"); - Thread::Current()->TransitionFromRunnableToSuspended(kNative); bool image_creation_success = dex2oat->CreateImageFile(image_filename, image_base, oat_unstripped, oat_location, *compiler.get()); - Thread::Current()->TransitionFromSuspendedToRunnable(); if (!image_creation_success) { return EXIT_FAILURE; } diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index cedea61bda..2f68f8e1c7 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -144,7 +144,7 @@ MarkSweep::MarkSweep(Heap* heap, bool is_concurrent, const std::string& name_pre cleared_reference_list_(NULL), gc_barrier_(new Barrier(0)), large_object_lock_("mark sweep large object lock", kMarkSweepLargeObjectLock), - mark_stack_expand_lock_("mark sweep mark stack expand lock"), + mark_stack_lock_("mark sweep mark stack lock", kMarkSweepMarkStackLock), is_concurrent_(is_concurrent), clear_soft_references_(false) { } @@ -343,14 +343,18 @@ void MarkSweep::FindDefaultMarkBitmap() { } void MarkSweep::ExpandMarkStack() { + ResizeMarkStack(mark_stack_->Capacity() * 2); +} + +void MarkSweep::ResizeMarkStack(size_t new_size) { // Rare case, no need to have Thread::Current be a parameter. - MutexLock mu(Thread::Current(), mark_stack_expand_lock_); if (UNLIKELY(mark_stack_->Size() < mark_stack_->Capacity())) { // Someone else acquired the lock and expanded the mark stack before us. return; } std::vector<Object*> temp(mark_stack_->Begin(), mark_stack_->End()); - mark_stack_->Resize(mark_stack_->Capacity() * 2); + CHECK_LE(mark_stack_->Size(), new_size); + mark_stack_->Resize(new_size); for (const auto& obj : temp) { mark_stack_->PushBack(obj); } @@ -359,10 +363,12 @@ void MarkSweep::ExpandMarkStack() { inline void MarkSweep::MarkObjectNonNullParallel(const Object* obj) { DCHECK(obj != NULL); if (MarkObjectParallel(obj)) { - while (UNLIKELY(!mark_stack_->AtomicPushBack(const_cast<Object*>(obj)))) { - // Only reason a push can fail is that the mark stack is full. + MutexLock mu(Thread::Current(), mark_stack_lock_); + if (UNLIKELY(mark_stack_->Size() >= mark_stack_->Capacity())) { ExpandMarkStack(); } + // The object must be pushed on to the mark stack. + mark_stack_->PushBack(const_cast<Object*>(obj)); } } @@ -409,7 +415,8 @@ inline void MarkSweep::MarkObjectNonNull(const Object* obj) { // This object was not previously marked. if (!object_bitmap->Test(obj)) { object_bitmap->Set(obj); - // Do we need to expand the mark stack? + // Lock is not needed but is here anyways to please annotalysis. + MutexLock mu(Thread::Current(), mark_stack_lock_); if (UNLIKELY(mark_stack_->Size() >= mark_stack_->Capacity())) { ExpandMarkStack(); } @@ -493,8 +500,7 @@ void MarkSweep::MarkRoot(const Object* obj) { void MarkSweep::MarkRootParallelCallback(const Object* root, void* arg) { DCHECK(root != NULL); DCHECK(arg != NULL); - MarkSweep* mark_sweep = reinterpret_cast<MarkSweep*>(arg); - mark_sweep->MarkObjectNonNullParallel(root); + reinterpret_cast<MarkSweep*>(arg)->MarkObjectNonNullParallel(root); } void MarkSweep::MarkObjectCallback(const Object* root, void* arg) { diff --git a/runtime/gc/collector/mark_sweep.h b/runtime/gc/collector/mark_sweep.h index dbec3e9064..fdd0c86724 100644 --- a/runtime/gc/collector/mark_sweep.h +++ b/runtime/gc/collector/mark_sweep.h @@ -305,8 +305,9 @@ class MarkSweep : public GarbageCollector { void VerifyRoots() NO_THREAD_SAFETY_ANALYSIS; - // Expand mark stack to 2x its current size. Thread safe. - void ExpandMarkStack(); + // Expand mark stack to 2x its current size. + void ExpandMarkStack() EXCLUSIVE_LOCKS_REQUIRED(mark_stack_lock_); + void ResizeMarkStack(size_t new_size) EXCLUSIVE_LOCKS_REQUIRED(mark_stack_lock_); // Returns how many threads we should use for the current GC phase based on if we are paused, // whether or not we care about pauses. @@ -445,7 +446,7 @@ class MarkSweep : public GarbageCollector { UniquePtr<Barrier> gc_barrier_; Mutex large_object_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - Mutex mark_stack_expand_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; + Mutex mark_stack_lock_ ACQUIRED_AFTER(Locks::classlinker_classes_lock_); const bool is_concurrent_; diff --git a/runtime/locks.h b/runtime/locks.h index 88d05db0cb..f63e2b1720 100644 --- a/runtime/locks.h +++ b/runtime/locks.h @@ -38,6 +38,7 @@ enum LockLevel { kAbortLock, kJdwpSocketLock, kAllocSpaceLock, + kMarkSweepMarkStackLock, kDefaultMutexLevel, kMarkSweepLargeObjectLock, kPinTableLock, diff --git a/runtime/thread.cc b/runtime/thread.cc index 3178bf16b8..a454195316 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2209,14 +2209,12 @@ void Thread::VisitRoots(RootVisitor* visitor, void* arg) { mapper.WalkStack(); ReleaseLongJumpContext(context); - std::deque<instrumentation::InstrumentationStackFrame>* instrumentation_stack = GetInstrumentationStack(); - typedef std::deque<instrumentation::InstrumentationStackFrame>::const_iterator It; - for (It it = instrumentation_stack->begin(), end = instrumentation_stack->end(); it != end; ++it) { - mirror::Object* this_object = (*it).this_object_; + for (const instrumentation::InstrumentationStackFrame& frame : *GetInstrumentationStack()) { + mirror::Object* this_object = frame.this_object_; if (this_object != NULL) { visitor(this_object, arg); } - mirror::ArtMethod* method = (*it).method_; + mirror::ArtMethod* method = frame.method_; visitor(method, arg); } } |