Merge "Make entrypoints Thumb2." into dalvik-dev
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index f7801f5..8111c9f 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -66,7 +66,7 @@
             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 2951444..8ec13bf 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -232,18 +232,18 @@
                                       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 @@
       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 @@
   }
   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 @@
     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 @@
   //
   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 cedea61..2f68f8e 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -144,7 +144,7 @@
       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::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 @@
 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 @@
   // 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::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 dbec3e9..fdd0c86 100644
--- a/runtime/gc/collector/mark_sweep.h
+++ b/runtime/gc/collector/mark_sweep.h
@@ -305,8 +305,9 @@
   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 @@
 
   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 88d05db..f63e2b1 100644
--- a/runtime/locks.h
+++ b/runtime/locks.h
@@ -38,6 +38,7 @@
   kAbortLock,
   kJdwpSocketLock,
   kAllocSpaceLock,
+  kMarkSweepMarkStackLock,
   kDefaultMutexLevel,
   kMarkSweepLargeObjectLock,
   kPinTableLock,
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 3178bf1..a454195 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2209,14 +2209,12 @@
   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);
   }
 }