mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 06:14:49 +02:00
8058564: Tiered compilation performance drop in PIT
Ensure MethodCounters are created before method is enqueued for compilation Reviewed-by: kvn, drchase, jiangli
This commit is contained in:
parent
964c442938
commit
ad7e67c98f
4 changed files with 18 additions and 17 deletions
|
@ -1206,6 +1206,12 @@ void CompileBroker::compile_method_base(methodHandle method,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TieredCompilation) {
|
||||||
|
// Tiered policy requires MethodCounters to exist before adding a method to
|
||||||
|
// the queue. Create if we don't have them yet.
|
||||||
|
method->get_method_counters(thread);
|
||||||
|
}
|
||||||
|
|
||||||
// Outputs from the following MutexLocker block:
|
// Outputs from the following MutexLocker block:
|
||||||
CompileTask* task = NULL;
|
CompileTask* task = NULL;
|
||||||
bool blocking = false;
|
bool blocking = false;
|
||||||
|
|
|
@ -93,7 +93,7 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
|
||||||
set_hidden(false);
|
set_hidden(false);
|
||||||
set_dont_inline(false);
|
set_dont_inline(false);
|
||||||
set_method_data(NULL);
|
set_method_data(NULL);
|
||||||
set_method_counters(NULL);
|
clear_method_counters();
|
||||||
set_vtable_index(Method::garbage_vtable_index);
|
set_vtable_index(Method::garbage_vtable_index);
|
||||||
|
|
||||||
// Fix and bury in Method*
|
// Fix and bury in Method*
|
||||||
|
@ -117,7 +117,7 @@ void Method::deallocate_contents(ClassLoaderData* loader_data) {
|
||||||
MetadataFactory::free_metadata(loader_data, method_data());
|
MetadataFactory::free_metadata(loader_data, method_data());
|
||||||
set_method_data(NULL);
|
set_method_data(NULL);
|
||||||
MetadataFactory::free_metadata(loader_data, method_counters());
|
MetadataFactory::free_metadata(loader_data, method_counters());
|
||||||
set_method_counters(NULL);
|
clear_method_counters();
|
||||||
// The nmethod will be gone when we get here.
|
// The nmethod will be gone when we get here.
|
||||||
if (code() != NULL) _code = NULL;
|
if (code() != NULL) _code = NULL;
|
||||||
}
|
}
|
||||||
|
@ -395,9 +395,7 @@ MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
|
||||||
methodHandle mh(m);
|
methodHandle mh(m);
|
||||||
ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
|
ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
|
||||||
MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
|
MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
|
||||||
if (mh->method_counters() == NULL) {
|
if (!mh->init_method_counters(counters)) {
|
||||||
mh->set_method_counters(counters);
|
|
||||||
} else {
|
|
||||||
MetadataFactory::free_metadata(loader_data, counters);
|
MetadataFactory::free_metadata(loader_data, counters);
|
||||||
}
|
}
|
||||||
return mh->method_counters();
|
return mh->method_counters();
|
||||||
|
@ -859,7 +857,7 @@ void Method::unlink_method() {
|
||||||
assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
|
assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
|
||||||
|
|
||||||
set_method_data(NULL);
|
set_method_data(NULL);
|
||||||
set_method_counters(NULL);
|
clear_method_counters();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the method_holder is getting linked. Setup entrypoints so the method
|
// Called when the method_holder is getting linked. Setup entrypoints so the method
|
||||||
|
|
|
@ -333,11 +333,13 @@ class Method : public Metadata {
|
||||||
return _method_counters;
|
return _method_counters;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_method_counters(MethodCounters* counters) {
|
void clear_method_counters() {
|
||||||
// The store into method must be released. On platforms without
|
_method_counters = NULL;
|
||||||
// total store order (TSO) the reference may become visible before
|
}
|
||||||
// the initialization of data otherwise.
|
|
||||||
OrderAccess::release_store_ptr((volatile void *)&_method_counters, counters);
|
bool init_method_counters(MethodCounters* counters) {
|
||||||
|
// Try to install a pointer to MethodCounters, return true on success.
|
||||||
|
return Atomic::cmpxchg_ptr(counters, (volatile void*)&_method_counters, NULL) == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TIERED
|
#ifdef TIERED
|
||||||
|
|
|
@ -616,12 +616,7 @@ void NMethodSweeper::possibly_flush(nmethod* nm) {
|
||||||
// The stack-scanning low-cost detection may not see the method was used (which can happen for
|
// The stack-scanning low-cost detection may not see the method was used (which can happen for
|
||||||
// flat profiles). Check the age counter for possible data.
|
// flat profiles). Check the age counter for possible data.
|
||||||
if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) {
|
if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) {
|
||||||
MethodCounters* mc = nm->method()->method_counters();
|
MethodCounters* mc = nm->method()->get_method_counters(Thread::current());
|
||||||
if (mc == NULL) {
|
|
||||||
// Sometimes we can get here without MethodCounters. For example if we run with -Xcomp.
|
|
||||||
// Try to allocate them.
|
|
||||||
mc = nm->method()->get_method_counters(Thread::current());
|
|
||||||
}
|
|
||||||
if (mc != NULL) {
|
if (mc != NULL) {
|
||||||
// Snapshot the value as it's changed concurrently
|
// Snapshot the value as it's changed concurrently
|
||||||
int age = mc->nmethod_age();
|
int age = mc->nmethod_age();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue