OSDN Git Service

Fix accidental IMT and root marking regression
authorMathieu Chartier <mathieuc@google.com>
Mon, 1 Jun 2015 17:47:36 +0000 (10:47 -0700)
committerMathieu Chartier <mathieuc@google.com>
Mon, 1 Jun 2015 17:51:42 +0000 (10:51 -0700)
Was always using the conflict trampoline. Also included fix for
regression in GC time caused by extra roots. Most of the regression
was IMT.

Fixed bug in DumpGcPerformanceInfo where we would get SIGABRT due to
detached thread.

EvaluateAndApplyChanges:
From ~2500 -> ~1980
GC time: 8.2s -> 7.2s due to 1s less of MarkConcurrentRoots

Bug: 19264997
Change-Id: I4333e80a8268c2ed1284f87f25b9f113d4f2c7e0

runtime/class_linker.cc
runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
runtime/gc/collector/mark_sweep.cc
runtime/gc/heap.cc
runtime/mirror/class.cc
runtime/runtime.h

index 84da475..3ce646f 100644 (file)
@@ -1264,12 +1264,18 @@ void ClassLinker::VisitClassRoots(RootVisitor* visitor, VisitRootFlags flags) {
     // marked concurrently and we don't hold the classlinker_classes_lock_ when we do the copy.
     for (GcRoot<mirror::Class>& root : class_table_) {
       buffered_visitor.VisitRoot(root);
-      root.Read()->VisitNativeRoots(buffered_visitor, image_pointer_size_);
+      if ((flags & kVisitRootFlagNonMoving) == 0) {
+        // Don't bother visiting ArtField and ArtMethod if kVisitRootFlagNonMoving is set since
+        // these roots are all reachable from the class or dex cache.
+        root.Read()->VisitNativeRoots(buffered_visitor, image_pointer_size_);
+      }
     }
     // PreZygote classes can't move so we won't need to update fields' declaring classes.
     for (GcRoot<mirror::Class>& root : pre_zygote_class_table_) {
       buffered_visitor.VisitRoot(root);
-      root.Read()->VisitNativeRoots(buffered_visitor, image_pointer_size_);
+      if ((flags & kVisitRootFlagNonMoving) == 0) {
+        root.Read()->VisitNativeRoots(buffered_visitor, image_pointer_size_);
+      }
     }
   } else if ((flags & kVisitRootFlagNewRoots) != 0) {
     for (auto& root : new_class_roots_) {
index 7c92b18..042c33f 100644 (file)
@@ -2083,7 +2083,7 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t dex_method_idx,
       return GetTwoWordFailureValue();  // Failure.
     }
   } else {
-    DCHECK(interface_method == Runtime::Current()->GetResolutionMethod());
+    DCHECK_EQ(interface_method, Runtime::Current()->GetResolutionMethod());
     if (kIsDebugBuild) {
       uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
       const DexFile::CodeItem* code = caller_method->GetCodeItem();
index 91a0e8a..1c9c412 100644 (file)
@@ -590,7 +590,8 @@ void MarkSweep::MarkNonThreadRoots() {
 void MarkSweep::MarkConcurrentRoots(VisitRootFlags flags) {
   TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings());
   // Visit all runtime roots and clear dirty flags.
-  Runtime::Current()->VisitConcurrentRoots(this, flags);
+  Runtime::Current()->VisitConcurrentRoots(
+      this, static_cast<VisitRootFlags>(flags | kVisitRootFlagNonMoving));
 }
 
 class ScanObjectVisitor {
index fbde494..59d0259 100644 (file)
@@ -1630,7 +1630,12 @@ size_t Heap::GetObjectsAllocated() const {
 }
 
 uint64_t Heap::GetObjectsAllocatedEver() const {
-  return GetObjectsFreedEver() + GetObjectsAllocated();
+  uint64_t total = GetObjectsFreedEver();
+  // If we are detached, we can't use GetObjectsAllocated since we can't change thread states.
+  if (Thread::Current() != nullptr) {
+    total += GetObjectsAllocated();
+  }
+  return total;
 }
 
 uint64_t Heap::GetBytesAllocatedEver() const {
index 482640b..f0b7bfd 100644 (file)
@@ -806,7 +806,7 @@ void Class::PopulateEmbeddedImtAndVTable(ArtMethod* const (&methods)[kImtSize],
   for (size_t i = 0; i < kImtSize; i++) {
     auto method = methods[i];
     DCHECK(method != nullptr);
-    SetEmbeddedImTableEntry(i, Runtime::Current()->GetImtConflictMethod(), pointer_size);
+    SetEmbeddedImTableEntry(i, method, pointer_size);
   }
   PointerArray* table = GetVTableDuringLinking();
   CHECK(table != nullptr) << PrettyClass(this);
index f6f9725..e569333 100644 (file)
@@ -98,6 +98,9 @@ enum VisitRootFlags : uint8_t {
   kVisitRootFlagStartLoggingNewRoots = 0x4,
   kVisitRootFlagStopLoggingNewRoots = 0x8,
   kVisitRootFlagClearRootLog = 0x10,
+  // Non moving means we can have optimizations where we don't visit some roots if they are
+  // definitely reachable from another location. E.g. ArtMethod and ArtField roots.
+  kVisitRootFlagNonMoving = 0x20,
 };
 
 class Runtime {