--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Sep 18 08:47:07 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Sep 18 08:32:12 2014 +0000
@@ -1206,6 +1206,12 @@
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:
CompileTask* task = NULL;
bool blocking = false;
--- a/hotspot/src/share/vm/oops/method.cpp Thu Sep 18 08:47:07 2014 +0200
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Sep 18 08:32:12 2014 +0000
@@ -93,7 +93,7 @@
set_hidden(false);
set_dont_inline(false);
set_method_data(NULL);
- set_method_counters(NULL);
+ clear_method_counters();
set_vtable_index(Method::garbage_vtable_index);
// Fix and bury in Method*
@@ -117,7 +117,7 @@
MetadataFactory::free_metadata(loader_data, method_data());
set_method_data(NULL);
MetadataFactory::free_metadata(loader_data, method_counters());
- set_method_counters(NULL);
+ clear_method_counters();
// The nmethod will be gone when we get here.
if (code() != NULL) _code = NULL;
}
@@ -395,9 +395,7 @@
methodHandle mh(m);
ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
- if (mh->method_counters() == NULL) {
- mh->set_method_counters(counters);
- } else {
+ if (!mh->init_method_counters(counters)) {
MetadataFactory::free_metadata(loader_data, counters);
}
return mh->method_counters();
@@ -859,7 +857,7 @@
assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
set_method_data(NULL);
- set_method_counters(NULL);
+ clear_method_counters();
}
// Called when the method_holder is getting linked. Setup entrypoints so the method
--- a/hotspot/src/share/vm/oops/method.hpp Thu Sep 18 08:47:07 2014 +0200
+++ b/hotspot/src/share/vm/oops/method.hpp Thu Sep 18 08:32:12 2014 +0000
@@ -333,11 +333,13 @@
return _method_counters;
}
- void set_method_counters(MethodCounters* counters) {
- // The store into method must be released. On platforms without
- // total store order (TSO) the reference may become visible before
- // the initialization of data otherwise.
- OrderAccess::release_store_ptr((volatile void *)&_method_counters, counters);
+ void clear_method_counters() {
+ _method_counters = NULL;
+ }
+
+ 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
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Thu Sep 18 08:47:07 2014 +0200
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Thu Sep 18 08:32:12 2014 +0000
@@ -616,12 +616,7 @@
// 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.
if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) {
- MethodCounters* mc = nm->method()->method_counters();
- 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());
- }
+ MethodCounters* mc = nm->method()->get_method_counters(Thread::current());
if (mc != NULL) {
// Snapshot the value as it's changed concurrently
int age = mc->nmethod_age();