--- old/src/share/vm/compiler/compileBroker.cpp 2014-09-17 17:19:51.000000000 -0700 +++ new/src/share/vm/compiler/compileBroker.cpp 2014-09-17 17:19:51.000000000 -0700 @@ -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; --- old/src/share/vm/oops/method.cpp 2014-09-17 17:19:51.000000000 -0700 +++ new/src/share/vm/oops/method.cpp 2014-09-17 17:19:51.000000000 -0700 @@ -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(); --- old/src/share/vm/oops/method.hpp 2014-09-17 17:19:51.000000000 -0700 +++ new/src/share/vm/oops/method.hpp 2014-09-17 17:19:51.000000000 -0700 @@ -334,10 +334,12 @@ } 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); + _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 --- old/src/share/vm/runtime/sweeper.cpp 2014-09-17 17:19:52.000000000 -0700 +++ new/src/share/vm/runtime/sweeper.cpp 2014-09-17 17:19:52.000000000 -0700 @@ -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();