When analyzing a timeout on gc/gctests/LargeObject/large00x I used PrintSafepointStatistics to see if there were any Safepoint issues causing the timeout and saw some pretty bad numbers: > vmop [threads: total initially_running wait_to_block] [time: spin block > sync cleanup vmop] page_trap_count > 5.693: EnableBiasedLocking [ 19 0 1 ] [ 0 230493 230493 0 0 ] 0 > (...) > vmop [threads: total initially_running wait_to_block] [time: spin block > sync cleanup vmop] page_trap_count > 435.543: RevokeBias [ 19 0 1 ] [ 0 126420 126421 0 0 ] 0 This led me to run some measurements with the linux "perf" tool, results attached. As you can see, with the 7168280 changes we spend a lot of time in fieldDescriptor::generic_signature(). The changes to make generic signature index slot optional seems to have caused a performance regression when getting all fields through reflection on large classes. This caused the gc/gctests/LargeObject tests to time out on slower hardware. The issue seems to be that given a class with thousands (65k) of fields a call to JVM_GetClassDeclaredFields will in the worst case (which seems to be triggered here) make the VM go through all the fields of the class for each call to Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); because of the loop in fieldDescriptor::generic_signature() This is basically making the time complexity of JVM_GetClassDeclaredFields O(n^2) where n is the number of fields in the class. This seems to have caused the safepoint stalls seen in the test (and the slow execution of the test).
|