8264872: Dependencies: Migrate to PerfData counters
Reviewed-by: kvn, neliasso
This commit is contained in:
parent
07c8ff47d2
commit
76bd313d80
@ -41,6 +41,7 @@
|
||||
#include "runtime/handles.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/jniHandles.inline.hpp"
|
||||
#include "runtime/perfData.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/vmThread.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
@ -951,7 +952,7 @@ bool DependencySignature::equals(DependencySignature const& s1, DependencySignat
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Checking dependencies:
|
||||
/// Checking dependencies
|
||||
|
||||
// This hierarchy walker inspects subtypes of a given type,
|
||||
// trying to find a "bad" class which breaks a dependency.
|
||||
@ -1145,6 +1146,24 @@ class ClassHierarchyWalker {
|
||||
return false; // not in list
|
||||
}
|
||||
|
||||
class CountingClassHierarchyIterator : public ClassHierarchyIterator {
|
||||
private:
|
||||
jlong _nof_steps;
|
||||
public:
|
||||
CountingClassHierarchyIterator(InstanceKlass* root) : ClassHierarchyIterator(root), _nof_steps(0) {}
|
||||
|
||||
void next() {
|
||||
_nof_steps++;
|
||||
ClassHierarchyIterator::next();
|
||||
}
|
||||
|
||||
~CountingClassHierarchyIterator() {
|
||||
if (UsePerfData) {
|
||||
_perf_find_witness_anywhere_steps_count->inc(_nof_steps);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
// the actual search method:
|
||||
Klass* find_witness_anywhere(InstanceKlass* context_type,
|
||||
@ -1179,53 +1198,32 @@ class ClassHierarchyWalker {
|
||||
return find_witness_anywhere(context_type, !participants_hide_witnesses);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static PerfCounter* _perf_find_witness_anywhere_calls_count;
|
||||
static PerfCounter* _perf_find_witness_anywhere_steps_count;
|
||||
static PerfCounter* _perf_find_witness_in_calls_count;
|
||||
|
||||
public:
|
||||
static void init();
|
||||
static void print_statistics();
|
||||
};
|
||||
|
||||
#ifndef PRODUCT
|
||||
static int deps_find_witness_calls = 0;
|
||||
static int deps_find_witness_steps = 0;
|
||||
static int deps_find_witness_recursions = 0;
|
||||
static int deps_find_witness_singles = 0;
|
||||
static int deps_find_witness_print = 0; // set to -1 to force a final print
|
||||
static bool count_find_witness_calls() {
|
||||
if (TraceDependencies || LogCompilation) {
|
||||
int pcount = deps_find_witness_print + 1;
|
||||
bool final_stats = (pcount == 0);
|
||||
bool initial_call = (pcount == 1);
|
||||
bool occasional_print = ((pcount & ((1<<10) - 1)) == 0);
|
||||
if (pcount < 0) pcount = 1; // crude overflow protection
|
||||
deps_find_witness_print = pcount;
|
||||
if (TraceDependencies && VerifyDependencies && initial_call) {
|
||||
warning("TraceDependencies results may be inflated by VerifyDependencies");
|
||||
}
|
||||
if (occasional_print || final_stats) {
|
||||
// Every now and then dump a little info about dependency searching.
|
||||
if (xtty != NULL) {
|
||||
ttyLocker ttyl;
|
||||
xtty->elem("deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'",
|
||||
deps_find_witness_calls,
|
||||
deps_find_witness_steps,
|
||||
deps_find_witness_recursions,
|
||||
deps_find_witness_singles);
|
||||
}
|
||||
if (final_stats || (TraceDependencies && WizardMode)) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("Dependency check (find_witness) "
|
||||
"calls=%d, steps=%d (avg=%.1f), recursions=%d, singles=%d",
|
||||
deps_find_witness_calls,
|
||||
deps_find_witness_steps,
|
||||
(double)deps_find_witness_steps / deps_find_witness_calls,
|
||||
deps_find_witness_recursions,
|
||||
deps_find_witness_singles);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
PerfCounter* ClassHierarchyWalker::_perf_find_witness_anywhere_calls_count = NULL;
|
||||
PerfCounter* ClassHierarchyWalker::_perf_find_witness_anywhere_steps_count = NULL;
|
||||
PerfCounter* ClassHierarchyWalker::_perf_find_witness_in_calls_count = NULL;
|
||||
|
||||
void ClassHierarchyWalker::init() {
|
||||
if (UsePerfData) {
|
||||
EXCEPTION_MARK;
|
||||
_perf_find_witness_anywhere_calls_count =
|
||||
PerfDataManager::create_counter(SUN_CI, "findWitnessAnywhere", PerfData::U_Events, CHECK);
|
||||
_perf_find_witness_anywhere_steps_count =
|
||||
PerfDataManager::create_counter(SUN_CI, "findWitnessAnywhereSteps", PerfData::U_Events, CHECK);
|
||||
_perf_find_witness_in_calls_count =
|
||||
PerfDataManager::create_counter(SUN_CI, "findWitnessIn", PerfData::U_Events, CHECK);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#define count_find_witness_calls() (0)
|
||||
#endif //PRODUCT
|
||||
|
||||
#ifdef ASSERT
|
||||
// Assert that m is inherited into ctxk, without intervening overrides.
|
||||
@ -1291,8 +1289,9 @@ Klass* ClassHierarchyWalker::find_witness_in(KlassDepChange& changes,
|
||||
assert(changes.involves_context(context_type), "irrelevant dependency");
|
||||
Klass* new_type = changes.new_type();
|
||||
|
||||
(void)count_find_witness_calls();
|
||||
NOT_PRODUCT(deps_find_witness_singles++);
|
||||
if (UsePerfData) {
|
||||
_perf_find_witness_in_calls_count->inc();
|
||||
}
|
||||
|
||||
// Current thread must be in VM (not native mode, as in CI):
|
||||
assert(must_be_in_vm(), "raw oops here");
|
||||
@ -1332,12 +1331,11 @@ Klass* ClassHierarchyWalker::find_witness_anywhere(InstanceKlass* context_type,
|
||||
// Must not move the class hierarchy during this check:
|
||||
assert_locked_or_safepoint(Compile_lock);
|
||||
|
||||
bool do_counts = count_find_witness_calls();
|
||||
if (UsePerfData) {
|
||||
_perf_find_witness_anywhere_calls_count->inc();
|
||||
}
|
||||
|
||||
// Check the root of the sub-hierarchy first.
|
||||
if (do_counts) {
|
||||
NOT_PRODUCT(deps_find_witness_calls++);
|
||||
}
|
||||
|
||||
// (Note: Interfaces do not have subclasses.)
|
||||
// If it is an interface, search its direct implementors.
|
||||
@ -1362,11 +1360,9 @@ Klass* ClassHierarchyWalker::find_witness_anywhere(InstanceKlass* context_type,
|
||||
|
||||
assert(!context_type->is_interface(), "not allowed");
|
||||
|
||||
for (ClassHierarchyIterator iter(context_type); !iter.done(); iter.next()) {
|
||||
for (CountingClassHierarchyIterator iter(context_type); !iter.done(); iter.next()) {
|
||||
Klass* sub = iter.klass();
|
||||
|
||||
if (do_counts) { NOT_PRODUCT(deps_find_witness_steps++); }
|
||||
|
||||
// Do not report participant types.
|
||||
if (is_participant(sub)) {
|
||||
// Walk beneath a participant only when it doesn't hide witnesses.
|
||||
@ -1779,15 +1775,31 @@ bool KlassDepChange::involves_context(Klass* k) {
|
||||
return is_contained;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void Dependencies::print_statistics() {
|
||||
if (deps_find_witness_print != 0) {
|
||||
// Call one final time, to flush out the data.
|
||||
deps_find_witness_print = -1;
|
||||
count_find_witness_calls();
|
||||
ClassHierarchyWalker::print_statistics();
|
||||
}
|
||||
|
||||
void ClassHierarchyWalker::print_statistics() {
|
||||
if (UsePerfData) {
|
||||
jlong deps_find_witness_calls = _perf_find_witness_anywhere_calls_count->get_value();
|
||||
jlong deps_find_witness_steps = _perf_find_witness_anywhere_steps_count->get_value();
|
||||
jlong deps_find_witness_singles = _perf_find_witness_in_calls_count->get_value();
|
||||
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("Dependency check (find_witness) "
|
||||
"calls=" JLONG_FORMAT ", steps=" JLONG_FORMAT " (avg=%.1f), singles=" JLONG_FORMAT,
|
||||
deps_find_witness_calls,
|
||||
deps_find_witness_steps,
|
||||
(double)deps_find_witness_steps / deps_find_witness_calls,
|
||||
deps_find_witness_singles);
|
||||
if (xtty != NULL) {
|
||||
xtty->elem("deps_find_witness calls='" JLONG_FORMAT "' steps='" JLONG_FORMAT "' singles='" JLONG_FORMAT "'",
|
||||
deps_find_witness_calls,
|
||||
deps_find_witness_steps,
|
||||
deps_find_witness_singles);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CallSiteDepChange::CallSiteDepChange(Handle call_site, Handle method_handle) :
|
||||
_call_site(call_site),
|
||||
@ -1795,3 +1807,7 @@ CallSiteDepChange::CallSiteDepChange(Handle call_site, Handle method_handle) :
|
||||
assert(_call_site()->is_a(vmClasses::CallSite_klass()), "must be");
|
||||
assert(_method_handle.is_null() || _method_handle()->is_a(vmClasses::MethodHandle_klass()), "must be");
|
||||
}
|
||||
|
||||
void dependencies_init() {
|
||||
ClassHierarchyWalker::init();
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ class Dependencies: public ResourceObj {
|
||||
};
|
||||
friend class Dependencies::DepStream;
|
||||
|
||||
static void print_statistics() PRODUCT_RETURN;
|
||||
static void print_statistics();
|
||||
};
|
||||
|
||||
|
||||
|
@ -3967,6 +3967,12 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
|
||||
no_shared_spaces("CDS Disabled");
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
if (TraceDependencies && VerifyDependencies) {
|
||||
if (!FLAG_IS_DEFAULT(TraceDependencies)) {
|
||||
warning("TraceDependencies results may be inflated by VerifyDependencies");
|
||||
}
|
||||
}
|
||||
|
||||
apply_debugger_ergo();
|
||||
|
||||
return JNI_OK;
|
||||
|
@ -85,6 +85,7 @@ void InlineCacheBuffer_init();
|
||||
void compilerOracle_init();
|
||||
bool compileBroker_init();
|
||||
void dependencyContext_init();
|
||||
void dependencies_init();
|
||||
|
||||
// Initialization after compiler initialization
|
||||
bool universe_post_init(); // must happen after compiler_init
|
||||
@ -143,6 +144,7 @@ jint init_globals() {
|
||||
InlineCacheBuffer_init();
|
||||
compilerOracle_init();
|
||||
dependencyContext_init();
|
||||
dependencies_init();
|
||||
|
||||
if (!compileBroker_init()) {
|
||||
return JNI_EINVAL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user