< prev index next >

src/hotspot/share/code/dependencyContext.hpp


30 #include "runtime/perfData.hpp"                                                                                                      
31 #include "runtime/safepoint.hpp"                                                                                                     
32 
33 class nmethod;                                                                                                                       
34 class DepChange;                                                                                                                     
35 
36 //                                                                                                                                   
37 // nmethodBucket is used to record dependent nmethods for                                                                            
38 // deoptimization.  nmethod dependencies are actually <klass, method>                                                                
39 // pairs but we really only care about the klass part for purposes of                                                                
40 // finding nmethods which might need to be deoptimized.  Instead of                                                                  
41 // recording the method, a count of how many times a particular nmethod                                                              
42 // was recorded is kept.  This ensures that any recording errors are                                                                 
43 // noticed since an nmethod should be removed as many times are it's                                                                 
44 // added.                                                                                                                            
45 //                                                                                                                                   
46 class nmethodBucket: public CHeapObj<mtClass> {                                                                                      
47   friend class VMStructs;                                                                                                            
48  private:                                                                                                                            
49   nmethod*       _nmethod;                                                                                                           
50   int            _count;                                                                                                             
51   nmethodBucket* _next;                                                                                                              
                                                                                                                                     
52 
53  public:                                                                                                                             
54   nmethodBucket(nmethod* nmethod, nmethodBucket* next) :                                                                             
55    _nmethod(nmethod), _count(1), _next(next) {}                                                                                      
56 
57   int count()                             { return _count; }                                                                         
58   int increment()                         { _count += 1; return _count; }                                                            
59   int decrement();                                                                                                                   
60   nmethodBucket* next()                   { return _next; }                                                                          
61   void set_next(nmethodBucket* b)         { _next = b; }                                                                             
62   nmethod* get_nmethod()                  { return _nmethod; }                                                                       
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
63 };                                                                                                                                   
64 
65 //                                                                                                                                   
66 // Utility class to manipulate nmethod dependency context.                                                                           
67 // The context consists of nmethodBucket* (a head of a linked list)                                                                  
68 // and a boolean flag (does the list contains stale entries). The structure is                                                       
69 // encoded as an intptr_t: lower bit is used for the flag. It is possible since                                                      
70 // nmethodBucket* is aligned - the structure is malloc'ed in C heap.                                                                 
71 // Dependency context can be attached either to an InstanceKlass (_dep_context field)                                                
72 // or CallSiteContext oop for call_site_target dependencies (see javaClasses.hpp).                                                   
73 // DependencyContext class operates on some location which holds a intptr_t value.                                                   
                                                                                                                                     
74 //                                                                                                                                   
75 class DependencyContext : public StackObj {                                                                                          
76   friend class VMStructs;                                                                                                            
77   friend class TestDependencyContext;                                                                                                
78  private:                                                                                                                            
79   enum TagBits { _has_stale_entries_bit = 1, _has_stale_entries_mask = 1 };                                                          
                                                                                                                                     
80 
81   intptr_t* _dependency_context_addr;                                                                                                
82                                                                                                                                      
83   void set_dependencies(nmethodBucket* b) {                                                                                          
84     assert((intptr_t(b) & _has_stale_entries_mask) == 0, "should be aligned");                                                       
85     if (has_stale_entries()) {                                                                                                       
86       *_dependency_context_addr = intptr_t(b) | _has_stale_entries_mask;                                                             
87     } else {                                                                                                                         
88       *_dependency_context_addr = intptr_t(b);                                                                                       
89     }                                                                                                                                
90   }                                                                                                                                  
91                                                                                                                                      
92   void set_has_stale_entries(bool x) {                                                                                               
93     if (x) {                                                                                                                         
94       *_dependency_context_addr |= _has_stale_entries_mask;                                                                          
95     } else {                                                                                                                         
96       *_dependency_context_addr &= ~_has_stale_entries_mask;                                                                         
97     }                                                                                                                                
98   }                                                                                                                                  
99                                                                                                                                      
100   nmethodBucket* dependencies() {                                                                                                    
101     intptr_t value = *_dependency_context_addr;                                                                                      
102     return (nmethodBucket*) (value & ~_has_stale_entries_mask);                                                                      
103   }                                                                                                                                  
104                                                                                                                                      
105   bool has_stale_entries() const {                                                                                                   
106     intptr_t value = *_dependency_context_addr;                                                                                      
107     return (value & _has_stale_entries_mask) != 0;                                                                                   
108   }                                                                                                                                  
109 
110   static PerfCounter* _perf_total_buckets_allocated_count;                                                                           
111   static PerfCounter* _perf_total_buckets_deallocated_count;                                                                         
112   static PerfCounter* _perf_total_buckets_stale_count;                                                                               
113   static PerfCounter* _perf_total_buckets_stale_acc_count;                                                                           
                                                                                                                                     
                                                                                                                                     
114 
115  public:                                                                                                                             
116 #ifdef ASSERT                                                                                                                        
117   // Safepoints are forbidden during DC lifetime. GC can invalidate                                                                  
118   // _dependency_context_addr if it relocates the holder                                                                             
119   // (e.g. CallSiteContext Java object).                                                                                             
120   uint64_t _safepoint_counter;                                                                                                       
121 
122   DependencyContext(intptr_t* addr) : _dependency_context_addr(addr),                                                                
123     _safepoint_counter(SafepointSynchronize::safepoint_counter()) {}                                                                 
                                                                                                                                     
                                                                                                                                     
124 
125   ~DependencyContext() {                                                                                                             
126     assert(_safepoint_counter == SafepointSynchronize::safepoint_counter(), "safepoint happened");                                   
127   }                                                                                                                                  
128 #else                                                                                                                                
129   DependencyContext(intptr_t* addr) : _dependency_context_addr(addr) {}                                                              
                                                                                                                                     
                                                                                                                                     
130 #endif // ASSERT                                                                                                                     
131 
132   static const intptr_t EMPTY = 0; // dependencies = NULL, has_stale_entries = false                                                 
133                                                                                                                                      
134   static void init();                                                                                                                
135 
136   int  mark_dependent_nmethods(DepChange& changes);                                                                                  
137   void add_dependent_nmethod(nmethod* nm, bool expunge_stale_entries = false);                                                       
138   void remove_dependent_nmethod(nmethod* nm, bool expunge_stale_entries = false);                                                    
139   int  remove_all_dependents();                                                                                                      
140                                                                                                                                      
141   void expunge_stale_entries();                                                                                                      
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
142 
143 #ifndef PRODUCT                                                                                                                      
144   void print_dependent_nmethods(bool verbose);                                                                                       
145   bool is_dependent_nmethod(nmethod* nm);                                                                                            
146   bool find_stale_entries();                                                                                                         
147 #endif //PRODUCT                                                                                                                     
148 };                                                                                                                                   
149 #endif // SHARE_VM_CODE_DEPENDENCYCONTEXT_HPP                                                                                        

30 #include "runtime/perfData.hpp"
31 #include "runtime/safepoint.hpp"
32 
33 class nmethod;
34 class DepChange;
35 
36 //
37 // nmethodBucket is used to record dependent nmethods for
38 // deoptimization.  nmethod dependencies are actually <klass, method>
39 // pairs but we really only care about the klass part for purposes of
40 // finding nmethods which might need to be deoptimized.  Instead of
41 // recording the method, a count of how many times a particular nmethod
42 // was recorded is kept.  This ensures that any recording errors are
43 // noticed since an nmethod should be removed as many times are it's
44 // added.
45 //
46 class nmethodBucket: public CHeapObj<mtClass> {
47   friend class VMStructs;
48  private:
49   nmethod*       _nmethod;
50   volatile int   _count;
51   nmethodBucket* volatile _next;
52   nmethodBucket* volatile _purge_list_next;
53 
54  public:
55   nmethodBucket(nmethod* nmethod, nmethodBucket* next) :
56     _nmethod(nmethod), _count(1), _next(next), _purge_list_next(NULL) {}
57 
58   int count()                                { return _count; }
59   int increment()                            { _count += 1; return _count; }
60   int decrement();
61   nmethodBucket* next();
62   nmethodBucket* next_not_unloading();
63   void set_next(nmethodBucket* b);
64   nmethodBucket* purge_list_next();
65   void set_purge_list_next(nmethodBucket* b);
66   nmethod* get_nmethod()                     { return _nmethod; }
67 };
68 
69 //
70 // Utility class to manipulate nmethod dependency context.




71 // Dependency context can be attached either to an InstanceKlass (_dep_context field)
72 // or CallSiteContext oop for call_site_target dependencies (see javaClasses.hpp).
73 // DependencyContext class operates on some location which holds a nmethodBucket* value
74 // and uint64_t integer recording the safepoint counter at the last cleanup.
75 //
76 class DependencyContext : public StackObj {
77   friend class VMStructs;
78   friend class TestDependencyContext;
79  private:
80   nmethodBucket* volatile* _dependency_context_addr;
81   volatile uint64_t*       _last_cleanup_addr;
82 
83   bool claim_cleanup();
84   void set_dependencies(nmethodBucket* b);
85   nmethodBucket* dependencies();
86   nmethodBucket* dependencies_not_unloading();
























87 
88   static PerfCounter* _perf_total_buckets_allocated_count;
89   static PerfCounter* _perf_total_buckets_deallocated_count;
90   static PerfCounter* _perf_total_buckets_stale_count;
91   static PerfCounter* _perf_total_buckets_stale_acc_count;
92   static nmethodBucket* volatile _purge_list;
93   static volatile uint64_t       _cleaning_epoch;
94 
95  public:
96 #ifdef ASSERT
97   // Safepoints are forbidden during DC lifetime. GC can invalidate
98   // _dependency_context_addr if it relocates the holder
99   // (e.g. CallSiteContext Java object).
100   uint64_t _safepoint_counter;
101 
102   DependencyContext(nmethodBucket* volatile* bucket_addr, volatile uint64_t* last_cleanup_addr)
103     : _dependency_context_addr(bucket_addr),
104       _last_cleanup_addr(last_cleanup_addr),
105       _safepoint_counter(SafepointSynchronize::safepoint_counter()) {}
106 
107   ~DependencyContext() {
108     assert(_safepoint_counter == SafepointSynchronize::safepoint_counter(), "safepoint happened");
109   }
110 #else
111   DependencyContext(nmethodBucket* volatile* bucket_addr, volatile uint64_t* last_cleanup_addr)
112     : _dependency_context_addr(bucket_addr),
113       _last_cleanup_addr(last_cleanup_addr) {}
114 #endif // ASSERT
115 


116   static void init();
117 
118   int  mark_dependent_nmethods(DepChange& changes);
119   void add_dependent_nmethod(nmethod* nm);
120   void remove_dependent_nmethod(nmethod* nm);
121   int  remove_all_dependents();
122   void clean_unloading_dependents();
123   static void purge_dependency_contexts();
124   static void release(nmethodBucket* b);
125   static void cleaning_start();
126   static void cleaning_end();
127 
128 #ifndef PRODUCT
129   void print_dependent_nmethods(bool verbose);
130   bool is_dependent_nmethod(nmethod* nm);

131 #endif //PRODUCT
132 };
133 #endif // SHARE_VM_CODE_DEPENDENCYCONTEXT_HPP
< prev index next >