< prev index next >

src/hotspot/share/code/dependencyContext.cpp


17  *                                                                                                                                   
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA                                                           
19  * or visit www.oracle.com if you need additional information or have any                                                            
20  * questions.                                                                                                                        
21  *                                                                                                                                   
22  */                                                                                                                                  
23 
24 #include "precompiled.hpp"                                                                                                           
25 #include "code/nmethod.hpp"                                                                                                          
26 #include "code/dependencies.hpp"                                                                                                     
27 #include "code/dependencyContext.hpp"                                                                                                
28 #include "memory/resourceArea.hpp"                                                                                                   
29 #include "runtime/atomic.hpp"                                                                                                        
30 #include "runtime/perfData.hpp"                                                                                                      
31 #include "utilities/exceptions.hpp"                                                                                                  
32 
33 PerfCounter* DependencyContext::_perf_total_buckets_allocated_count   = NULL;                                                        
34 PerfCounter* DependencyContext::_perf_total_buckets_deallocated_count = NULL;                                                        
35 PerfCounter* DependencyContext::_perf_total_buckets_stale_count       = NULL;                                                        
36 PerfCounter* DependencyContext::_perf_total_buckets_stale_acc_count   = NULL;                                                        
37 nmethodBucket* volatile DependencyContext::_purge_list = NULL;                                                                       
38 volatile uint64_t DependencyContext::_cleaning_epoch = 0;                                                                            
                                                                                                                                     
39 
40 void dependencyContext_init() {                                                                                                      
41   DependencyContext::init();                                                                                                         
42 }                                                                                                                                    
43 
44 void DependencyContext::init() {                                                                                                     
45   if (UsePerfData) {                                                                                                                 
46     EXCEPTION_MARK;                                                                                                                  
47     _perf_total_buckets_allocated_count =                                                                                            
48         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsAllocated", PerfData::U_Events, CHECK);                               
49     _perf_total_buckets_deallocated_count =                                                                                          
50         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsDeallocated", PerfData::U_Events, CHECK);                             
51     _perf_total_buckets_stale_count =                                                                                                
52         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsStale", PerfData::U_Events, CHECK);                                   
53     _perf_total_buckets_stale_acc_count =                                                                                            
54         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsStaleAccumulated", PerfData::U_Events, CHECK);                        
55   }                                                                                                                                  
56 }                                                                                                                                    
57 

17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  *
22  */
23 
24 #include "precompiled.hpp"
25 #include "code/nmethod.hpp"
26 #include "code/dependencies.hpp"
27 #include "code/dependencyContext.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "runtime/atomic.hpp"
30 #include "runtime/perfData.hpp"
31 #include "utilities/exceptions.hpp"
32 
33 PerfCounter* DependencyContext::_perf_total_buckets_allocated_count   = NULL;
34 PerfCounter* DependencyContext::_perf_total_buckets_deallocated_count = NULL;
35 PerfCounter* DependencyContext::_perf_total_buckets_stale_count       = NULL;
36 PerfCounter* DependencyContext::_perf_total_buckets_stale_acc_count   = NULL;
37 nmethodBucket* volatile DependencyContext::_purge_list                = NULL;
38 volatile uint64_t DependencyContext::_cleaning_epoch                  = 0;
39 uint64_t  DependencyContext::_cleaning_epoch_monotonic                = 0;
40 
41 void dependencyContext_init() {
42   DependencyContext::init();
43 }
44 
45 void DependencyContext::init() {
46   if (UsePerfData) {
47     EXCEPTION_MARK;
48     _perf_total_buckets_allocated_count =
49         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsAllocated", PerfData::U_Events, CHECK);
50     _perf_total_buckets_deallocated_count =
51         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsDeallocated", PerfData::U_Events, CHECK);
52     _perf_total_buckets_stale_count =
53         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsStale", PerfData::U_Events, CHECK);
54     _perf_total_buckets_stale_acc_count =
55         PerfDataManager::create_counter(SUN_CI, "nmethodBucketsStaleAccumulated", PerfData::U_Events, CHECK);
56   }
57 }
58 

293       // Release is_unloading entries if unlinking was claimed                                                                       
294       DependencyContext::release(head);                                                                                              
295     }                                                                                                                                
296   }                                                                                                                                  
297 }                                                                                                                                    
298 
299 // Relaxed accessors                                                                                                                 
300 void DependencyContext::set_dependencies(nmethodBucket* b) {                                                                         
301   Atomic::store(b, _dependency_context_addr);                                                                                        
302 }                                                                                                                                    
303 
304 nmethodBucket* DependencyContext::dependencies() {                                                                                   
305   return Atomic::load(_dependency_context_addr);                                                                                     
306 }                                                                                                                                    
307 
308 // After the gc_prologue, the dependency contexts may be claimed by the GC                                                           
309 // and releasing of nmethodBucket entries will be deferred and placed on                                                             
310 // a purge list to be deleted later.                                                                                                 
311 void DependencyContext::cleaning_start() {                                                                                           
312   assert(SafepointSynchronize::is_at_safepoint(), "must be");                                                                        
313   uint64_t epoch = SafepointSynchronize::safepoint_counter();                                                                        
314   Atomic::store(epoch, &_cleaning_epoch);                                                                                            
315 }                                                                                                                                    
316 
317 // The epilogue marks the end of dependency context cleanup by the GC,                                                               
318 // and also makes subsequent releases of nmethodBuckets case immediate                                                               
319 // deletion. It is admitted to end the cleanup in a concurrent phase.                                                                
320 void DependencyContext::cleaning_end() {                                                                                             
321   uint64_t epoch = 0;                                                                                                                
322   Atomic::store(epoch, &_cleaning_epoch);                                                                                            
323 }                                                                                                                                    
324 
325 // This function skips over nmethodBuckets in the list corresponding to                                                              
326 // nmethods that are is_unloading. This allows exposing a view of the                                                                
327 // dependents as-if they were already cleaned, despite being cleaned                                                                 
328 // concurrently. Any entry observed that is_unloading() will be unlinked                                                             
329 // and placed on the purge list.                                                                                                     
330 nmethodBucket* nmethodBucket::next_not_unloading() {                                                                                 
331   for (;;) {                                                                                                                         
332     // Do not need acquire because the loaded entry can never be                                                                     

294       // Release is_unloading entries if unlinking was claimed
295       DependencyContext::release(head);
296     }
297   }
298 }
299 
300 // Relaxed accessors
301 void DependencyContext::set_dependencies(nmethodBucket* b) {
302   Atomic::store(b, _dependency_context_addr);
303 }
304 
305 nmethodBucket* DependencyContext::dependencies() {
306   return Atomic::load(_dependency_context_addr);
307 }
308 
309 // After the gc_prologue, the dependency contexts may be claimed by the GC
310 // and releasing of nmethodBucket entries will be deferred and placed on
311 // a purge list to be deleted later.
312 void DependencyContext::cleaning_start() {
313   assert(SafepointSynchronize::is_at_safepoint(), "must be");
314   uint64_t epoch = ++_cleaning_epoch_monotonic;
315   Atomic::store(epoch, &_cleaning_epoch);
316 }
317 
318 // The epilogue marks the end of dependency context cleanup by the GC,
319 // and also makes subsequent releases of nmethodBuckets case immediate
320 // deletion. It is admitted to end the cleanup in a concurrent phase.
321 void DependencyContext::cleaning_end() {
322   uint64_t epoch = 0;
323   Atomic::store(epoch, &_cleaning_epoch);
324 }
325 
326 // This function skips over nmethodBuckets in the list corresponding to
327 // nmethods that are is_unloading. This allows exposing a view of the
328 // dependents as-if they were already cleaned, despite being cleaned
329 // concurrently. Any entry observed that is_unloading() will be unlinked
330 // and placed on the purge list.
331 nmethodBucket* nmethodBucket::next_not_unloading() {
332   for (;;) {
333     // Do not need acquire because the loaded entry can never be
< prev index next >