Fri, 19 Sep 2014 11:53:58 -0700
8058564: Tiered compilation performance drop in PIT
Summary: Ensure MethodCounters are created before method is enqueued for compilation
Reviewed-by: kvn, drchase, jiangli, roland
1.1 --- a/src/share/vm/compiler/compileBroker.cpp Fri Sep 19 11:12:39 2014 -0400 1.2 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Sep 19 11:53:58 2014 -0700 1.3 @@ -1175,6 +1175,12 @@ 1.4 return; 1.5 } 1.6 1.7 + if (TieredCompilation) { 1.8 + // Tiered policy requires MethodCounters to exist before adding a method to 1.9 + // the queue. Create if we don't have them yet. 1.10 + method->get_method_counters(thread); 1.11 + } 1.12 + 1.13 // Outputs from the following MutexLocker block: 1.14 CompileTask* task = NULL; 1.15 bool blocking = false;
2.1 --- a/src/share/vm/oops/method.cpp Fri Sep 19 11:12:39 2014 -0400 2.2 +++ b/src/share/vm/oops/method.cpp Fri Sep 19 11:53:58 2014 -0700 2.3 @@ -93,7 +93,7 @@ 2.4 set_hidden(false); 2.5 set_dont_inline(false); 2.6 set_method_data(NULL); 2.7 - set_method_counters(NULL); 2.8 + clear_method_counters(); 2.9 set_vtable_index(Method::garbage_vtable_index); 2.10 2.11 // Fix and bury in Method* 2.12 @@ -117,7 +117,7 @@ 2.13 MetadataFactory::free_metadata(loader_data, method_data()); 2.14 set_method_data(NULL); 2.15 MetadataFactory::free_metadata(loader_data, method_counters()); 2.16 - set_method_counters(NULL); 2.17 + clear_method_counters(); 2.18 // The nmethod will be gone when we get here. 2.19 if (code() != NULL) _code = NULL; 2.20 } 2.21 @@ -388,9 +388,7 @@ 2.22 methodHandle mh(m); 2.23 ClassLoaderData* loader_data = mh->method_holder()->class_loader_data(); 2.24 MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL); 2.25 - if (mh->method_counters() == NULL) { 2.26 - mh->set_method_counters(counters); 2.27 - } else { 2.28 + if (!mh->init_method_counters(counters)) { 2.29 MetadataFactory::free_metadata(loader_data, counters); 2.30 } 2.31 return mh->method_counters(); 2.32 @@ -852,7 +850,7 @@ 2.33 assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?"); 2.34 2.35 set_method_data(NULL); 2.36 - set_method_counters(NULL); 2.37 + clear_method_counters(); 2.38 } 2.39 2.40 // Called when the method_holder is getting linked. Setup entrypoints so the method
3.1 --- a/src/share/vm/oops/method.hpp Fri Sep 19 11:12:39 2014 -0400 3.2 +++ b/src/share/vm/oops/method.hpp Fri Sep 19 11:53:58 2014 -0700 3.3 @@ -365,11 +365,13 @@ 3.4 return _method_counters; 3.5 } 3.6 3.7 - void set_method_counters(MethodCounters* counters) { 3.8 - // The store into method must be released. On platforms without 3.9 - // total store order (TSO) the reference may become visible before 3.10 - // the initialization of data otherwise. 3.11 - OrderAccess::release_store_ptr((volatile void *)&_method_counters, counters); 3.12 + void clear_method_counters() { 3.13 + _method_counters = NULL; 3.14 + } 3.15 + 3.16 + bool init_method_counters(MethodCounters* counters) { 3.17 + // Try to install a pointer to MethodCounters, return true on success. 3.18 + return Atomic::cmpxchg_ptr(counters, (volatile void*)&_method_counters, NULL) == NULL; 3.19 } 3.20 3.21 #ifdef TIERED