ART: Correctly exclude super-init times in classlinker
Subtract the times for initializing superclass and interfaces to
not double-count.
Test: m
Test: manual
Change-Id: Ibf4409f8390107c20a1c1b812aa6ea6567ca0a4b
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b0d2da6..fca40c5 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -5284,6 +5284,8 @@
t0 = NanoTime();
}
+ uint64_t t_sub = 0;
+
// Initialize super classes, must be done while initializing for the JLS.
if (!klass->IsInterface() && klass->HasSuperClass()) {
ObjPtr<mirror::Class> super_class = klass->GetSuperClass();
@@ -5292,7 +5294,9 @@
CHECK(can_init_parents);
StackHandleScope<1> hs(self);
Handle<mirror::Class> handle_scope_super(hs.NewHandle(super_class));
+ uint64_t super_t0 = NanoTime();
bool super_initialized = InitializeClass(self, handle_scope_super, can_init_statics, true);
+ uint64_t super_t1 = NanoTime();
if (!super_initialized) {
// The super class was verified ahead of entering initializing, we should only be here if
// the super class became erroneous due to initialization.
@@ -5309,6 +5313,7 @@
mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
return false;
}
+ t_sub = super_t1 - super_t0;
}
}
@@ -5330,16 +5335,19 @@
// We cannot just call initialize class directly because we need to ensure that ALL
// interfaces with default methods are initialized. Non-default interface initialization
// will not affect other non-default super-interfaces.
+ uint64_t inf_t0 = NanoTime(); // This is not very precise, misses all walking.
bool iface_initialized = InitializeDefaultInterfaceRecursive(self,
handle_scope_iface,
can_init_statics,
can_init_parents);
+ uint64_t inf_t1 = NanoTime();
if (!iface_initialized) {
ObjectLock<mirror::Class> lock(self, klass);
// Initialization failed because one of our interfaces with default methods is erroneous.
mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
return false;
}
+ t_sub += inf_t1 - inf_t0;
}
}
}
@@ -5435,8 +5443,8 @@
RuntimeStats* thread_stats = self->GetStats();
++global_stats->class_init_count;
++thread_stats->class_init_count;
- global_stats->class_init_time_ns += (t1 - t0);
- thread_stats->class_init_time_ns += (t1 - t0);
+ global_stats->class_init_time_ns += (t1 - t0 - t_sub);
+ thread_stats->class_init_time_ns += (t1 - t0 - t_sub);
// Set the class as initialized except if failed to initialize static fields.
mirror::Class::SetStatus(klass, ClassStatus::kInitialized, self);
if (VLOG_IS_ON(class_linker)) {