Merge "Remove some stray stringpiece.h includes"
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 7cbeb29..5339b5e 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -756,21 +756,25 @@
   RememberForGcArgumentVisitor visitor(sp, invoke_type == kStatic, shorty, shorty_len, &soa);
   visitor.VisitArguments();
   thread->EndAssertNoThreadSuspension(old_cause);
+  bool virtual_or_interface = invoke_type == kVirtual || invoke_type == kInterface;
   // Resolve method filling in dex cache.
   if (called->IsRuntimeMethod()) {
+    SirtRef<mirror::Object> sirt_receiver(soa.Self(), virtual_or_interface ? receiver : nullptr);
     called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
+    receiver = sirt_receiver.get();
   }
   const void* code = NULL;
   if (LIKELY(!thread->IsExceptionPending())) {
     // Incompatible class change should have been handled in resolve method.
     CHECK(!called->CheckIncompatibleClassChange(invoke_type));
-    // Refine called method based on receiver.
-    if (invoke_type == kVirtual) {
-      called = receiver->GetClass()->FindVirtualMethodForVirtual(called);
-    } else if (invoke_type == kInterface) {
-      called = receiver->GetClass()->FindVirtualMethodForInterface(called);
-    }
-    if ((invoke_type == kVirtual) || (invoke_type == kInterface)) {
+    if (virtual_or_interface) {
+      // Refine called method based on receiver.
+      CHECK(receiver != nullptr) << invoke_type;
+      if (invoke_type == kVirtual) {
+        called = receiver->GetClass()->FindVirtualMethodForVirtual(called);
+      } else {
+        called = receiver->GetClass()->FindVirtualMethodForInterface(called);
+      }
       // We came here because of sharpening. Ensure the dex cache is up-to-date on the method index
       // of the sharpened method.
       if (called->GetDexCacheResolvedMethods() == caller->GetDexCacheResolvedMethods()) {
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h
index e089ef2..89ded0b 100644
--- a/runtime/gc/heap-inl.h
+++ b/runtime/gc/heap-inl.h
@@ -256,7 +256,7 @@
   // Zygote resulting in it being prematurely freed.
   // We can only do this for primitive objects since large objects will not be within the card table
   // range. This also means that we rely on SetClass not dirtying the object's card.
-  return byte_count >= kLargeObjectThreshold && have_zygote_space_ && c->IsPrimitiveArray();
+  return byte_count >= large_object_threshold_ && c->IsPrimitiveArray();
 }
 
 template <bool kGrow>
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 8d8cdd6..2e6d2c2 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -98,6 +98,7 @@
       long_gc_log_threshold_(long_gc_log_threshold),
       ignore_max_footprint_(ignore_max_footprint),
       have_zygote_space_(false),
+      large_object_threshold_(std::numeric_limits<size_t>::max()),  // Starts out disabled.
       soft_reference_queue_(this),
       weak_reference_queue_(this),
       finalizer_reference_queue_(this),
@@ -159,11 +160,16 @@
   }
   // If we aren't the zygote, switch to the default non zygote allocator. This may update the
   // entrypoints.
-  if (!Runtime::Current()->IsZygote() || !kMovingCollector) {
+  if (!Runtime::Current()->IsZygote()) {
     ChangeCollector(post_zygote_collector_type_);
+    large_object_threshold_ = kDefaultLargeObjectThreshold;
   } else {
-    // We are the zygote, use bump pointer allocation + semi space collector.
-    ChangeCollector(kCollectorTypeSS);
+    if (kMovingCollector) {
+      // We are the zygote, use bump pointer allocation + semi space collector.
+      ChangeCollector(kCollectorTypeSS);
+    } else {
+      ChangeCollector(post_zygote_collector_type_);
+    }
   }
 
   live_bitmap_.reset(new accounting::HeapBitmap(this));
@@ -1485,15 +1491,13 @@
   main_space_->SetFootprintLimit(main_space_->Capacity());
   AddSpace(main_space_);
   have_zygote_space_ = true;
+  // Enable large object space allocations.
+  large_object_threshold_ = kDefaultLargeObjectThreshold;
   // Create the zygote space mod union table.
   accounting::ModUnionTable* mod_union_table =
       new accounting::ModUnionTableCardCache("zygote space mod-union table", this, zygote_space);
   CHECK(mod_union_table != nullptr) << "Failed to create zygote space mod-union table";
   AddModUnionTable(mod_union_table);
-  // Reset the cumulative loggers since we now have a few additional timing phases.
-  for (const auto& collector : garbage_collectors_) {
-    collector->ResetCumulativeStatistics();
-  }
   // Can't use RosAlloc for non moving space due to thread local buffers.
   // TODO: Non limited space for non-movable objects?
   MemMap* mem_map = post_zygote_non_moving_space_mem_map_.release();
@@ -2049,7 +2053,8 @@
       TimingLogger::ScopedSplit split("AllocSpaceClearCards", &timings);
       // No mod union table for the AllocSpace. Age the cards so that the GC knows that these cards
       // were dirty before the GC started.
-      // TODO: Don't need to use atomic.
+      // TODO: Need to use atomic for the case where aged(cleaning thread) -> dirty(other thread)
+      // -> clean(cleaning thread).
       // The races are we either end up with: Aged card, unaged card. Since we have the checkpoint
       // roots and then we scan / update mod union tables after. We will always scan either card.
       // If we end up with the non aged card, we scan it it in the pause.
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 5d3232f..2f227d0 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -119,7 +119,7 @@
   // If true, measure the total allocation time.
   static constexpr bool kMeasureAllocationTime = false;
   // Primitive arrays larger than this size are put in the large object space.
-  static constexpr size_t kLargeObjectThreshold = 3 * kPageSize;
+  static constexpr size_t kDefaultLargeObjectThreshold = 3 * kPageSize;
 
   static constexpr size_t kDefaultInitialSize = 2 * MB;
   static constexpr size_t kDefaultMaximumSize = 32 * MB;
@@ -743,6 +743,9 @@
   // If we have a zygote space.
   bool have_zygote_space_;
 
+  // Minimum allocation size of large object.
+  size_t large_object_threshold_;
+
   // Guards access to the state of GC, associated conditional variable is used to signal when a GC
   // completes.
   Mutex* gc_complete_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;