< prev index next >

src/hotspot/share/code/compiledMethod.cpp


71   case not_installed:                                                                                                                
72     return "not installed";                                                                                                          
73   case in_use:                                                                                                                       
74     return "in use";                                                                                                                 
75   case not_used:                                                                                                                     
76     return "not_used";                                                                                                               
77   case not_entrant:                                                                                                                  
78     return "not_entrant";                                                                                                            
79   case zombie:                                                                                                                       
80     return "zombie";                                                                                                                 
81   case unloaded:                                                                                                                     
82     return "unloaded";                                                                                                               
83   default:                                                                                                                           
84     fatal("unexpected method state: %d", state);                                                                                     
85     return NULL;                                                                                                                     
86   }                                                                                                                                  
87 }                                                                                                                                    
88 
89 //-----------------------------------------------------------------------------                                                      
90 
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
91 void CompiledMethod::add_exception_cache_entry(ExceptionCache* new_entry) {                                                          
92   assert(ExceptionCache_lock->owned_by_self(),"Must hold the ExceptionCache_lock");                                                  
93   assert(new_entry != NULL,"Must be non null");                                                                                      
94   assert(new_entry->next() == NULL, "Must be null");                                                                                 
95 
96   ExceptionCache *ec = exception_cache();                                                                                            
97   if (ec != NULL) {                                                                                                                  
98     new_entry->set_next(ec);                                                                                                         
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
99   }                                                                                                                                  
100   release_set_exception_cache(new_entry);                                                                                            
101 }                                                                                                                                    
102 
103 void CompiledMethod::clean_exception_cache() {                                                                                       
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
104   ExceptionCache* prev = NULL;                                                                                                       
105   ExceptionCache* curr = exception_cache();                                                                                          
106 
107   while (curr != NULL) {                                                                                                             
108     ExceptionCache* next = curr->next();                                                                                             
109 
110     Klass* ex_klass = curr->exception_type();                                                                                        
111     if (ex_klass != NULL && !ex_klass->is_loader_alive()) {                                                                          
112       if (prev == NULL) {                                                                                                            
113         set_exception_cache(next);                                                                                                   
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
114       } else {                                                                                                                       
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
115         prev->set_next(next);                                                                                                        
116       }                                                                                                                              
117       delete curr;                                                                                                                   
118       // prev stays the same.                                                                                                        
                                                                                                                                     
                                                                                                                                     
119     } else {                                                                                                                         
120       prev = curr;                                                                                                                   
121     }                                                                                                                                
122 
123     curr = next;                                                                                                                     
124   }                                                                                                                                  
125 }                                                                                                                                    
126 
127 // public method for accessing the exception cache                                                                                   
128 // These are the public access methods.                                                                                              
129 address CompiledMethod::handler_for_exception_and_pc(Handle exception, address pc) {                                                 
130   // We never grab a lock to read the exception cache, so we may                                                                     
131   // have false negatives. This is okay, as it can only happen during                                                                
132   // the first few exception lookups for a given nmethod.                                                                            
133   ExceptionCache* ec = exception_cache();                                                                                            
134   while (ec != NULL) {                                                                                                               
135     address ret_val;                                                                                                                 
136     if ((ret_val = ec->match(exception,pc)) != NULL) {                                                                               
137       return ret_val;                                                                                                                
138     }                                                                                                                                
139     ec = ec->next();                                                                                                                 
140   }                                                                                                                                  
141   return NULL;                                                                                                                       
142 }                                                                                                                                    
143 
144 void CompiledMethod::add_handler_for_exception_and_pc(Handle exception, address pc, address handler) {                               
145   // There are potential race conditions during exception cache updates, so we                                                       
146   // must own the ExceptionCache_lock before doing ANY modifications. Because                                                        
147   // we don't lock during reads, it is possible to have several threads attempt                                                      
148   // to update the cache with the same data. We need to check for already inserted                                                   
149   // copies of the current data before adding it.                                                                                    
150 
151   MutexLocker ml(ExceptionCache_lock);                                                                                               
152   ExceptionCache* target_entry = exception_cache_entry_for_exception(exception);                                                     
153 
154   if (target_entry == NULL || !target_entry->add_address_and_handler(pc,handler)) {                                                  
155     target_entry = new ExceptionCache(exception,pc,handler);                                                                         
156     add_exception_cache_entry(target_entry);                                                                                         
157   }                                                                                                                                  
158 }                                                                                                                                    
159 
160 //-------------end of code for ExceptionCache--------------                                                                          
161                                                                                                                                      
162 // private method for handling exception cache                                                                                       
163 // These methods are private, and used to manipulate the exception cache                                                             
164 // directly.                                                                                                                         
165 ExceptionCache* CompiledMethod::exception_cache_entry_for_exception(Handle exception) {                                              
166   ExceptionCache* ec = exception_cache();                                                                                            
167   while (ec != NULL) {                                                                                                               
168     if (ec->match_exception_with_space(exception)) {                                                                                 
169       return ec;                                                                                                                     
170     }                                                                                                                                
171     ec = ec->next();                                                                                                                 
172   }                                                                                                                                  
173   return NULL;                                                                                                                       
174 }                                                                                                                                    
                                                                                                                                     
                                                                                                                                     
175 
176 bool CompiledMethod::is_at_poll_return(address pc) {                                                                                 
177   RelocIterator iter(this, pc, pc+1);                                                                                                
178   while (iter.next()) {                                                                                                              
179     if (iter.type() == relocInfo::poll_return_type)                                                                                  
180       return true;                                                                                                                   
181   }                                                                                                                                  
182   return false;                                                                                                                      
183 }                                                                                                                                    
184 
185 
186 bool CompiledMethod::is_at_poll_or_poll_return(address pc) {                                                                         
187   RelocIterator iter(this, pc, pc+1);                                                                                                
188   while (iter.next()) {                                                                                                              
189     relocInfo::relocType t = iter.type();                                                                                            
190     if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)                                                               
191       return true;                                                                                                                   
192   }                                                                                                                                  
193   return false;                                                                                                                      

71   case not_installed:
72     return "not installed";
73   case in_use:
74     return "in use";
75   case not_used:
76     return "not_used";
77   case not_entrant:
78     return "not_entrant";
79   case zombie:
80     return "zombie";
81   case unloaded:
82     return "unloaded";
83   default:
84     fatal("unexpected method state: %d", state);
85     return NULL;
86   }
87 }
88 
89 //-----------------------------------------------------------------------------
90 
91 ExceptionCache* CompiledMethod::exception_cache_acquire() const {
92   return OrderAccess::load_acquire(&_exception_cache);
93 }
94 
95 void CompiledMethod::add_exception_cache_entry(ExceptionCache* new_entry) {
96   assert(ExceptionCache_lock->owned_by_self(),"Must hold the ExceptionCache_lock");
97   assert(new_entry != NULL,"Must be non null");
98   assert(new_entry->next() == NULL, "Must be null");
99 
100   for (;;) {
101     ExceptionCache *ec = exception_cache();
102     if (ec != NULL) {
103       Klass* ex_klass = ec->exception_type();
104       if (!ex_klass->is_loader_alive()) {
105         // We must guarantee that entries are not inserted with new next pointer
106         // edges to ExceptionCache entries with dead klasses, due to bad interactions
107         // with concurrent ExceptionCache cleanup. Therefore, the inserts roll
108         // the head pointer forward to the first live ExceptionCache, so that the new
109         // next pointers always point at live ExceptionCaches, that are not removed due
110         // to concurrent ExceptionCache cleanup.
111         ExceptionCache* next = ec->next();
112         if (Atomic::cmpxchg(next, &_exception_cache, ec) == ec) {
113           CodeCache::release_exception_cache(ec);
114         }
115         continue;
116       }
117       ec = exception_cache();
118       if (ec != NULL) {
119         new_entry->set_next(ec);
120       }
121     }
122     if (Atomic::cmpxchg(new_entry, &_exception_cache, ec) == ec) {
123       return;
124     }
125   }

126 }
127 
128 void CompiledMethod::clean_exception_cache() {
129   // For each nmethod, only a single thread may call this cleanup function
130   // at the same time, whether called in STW cleanup or concurrent cleanup.
131   // Note that if the GC is processing exception cache cleaning in a concurrent phase,
132   // then a single writer may contend with cleaning up the head pointer to the
133   // first ExceptionCache node that has a Klass* that is alive. That is fine,
134   // as long as there is no concurrent cleanup of next pointers from concurrent writers.
135   // And the concurrent writers do not clean up next pointers, only the head.
136   // Also note that concurent readers will walk through Klass* pointers that are not
137   // alive. That does not cause ABA problems, because Klass* is deleted after
138   // a handshake with all threads, after all stale ExceptionCaches have been
139   // unlinked. That is also when the CodeCache::exception_cache_purge_list()
140   // is deleted, with all ExceptionCache entries that were cleaned concurrently.
141   // That similarly implies that CAS operations on ExceptionCache entries do not
142   // suffer from ABA problems as unlinking and deletion is separated by a global
143   // handshake operation.
144   ExceptionCache* prev = NULL;
145   ExceptionCache* curr = exception_cache_acquire();
146 
147   while (curr != NULL) {
148     ExceptionCache* next = curr->next();
149 
150     if (!curr->exception_type()->is_loader_alive()) {

151       if (prev == NULL) {
152         // Try to clean head; this is contended by concurrent inserts, that
153         // both lazily clean the head, and insert entries at the head. If
154         // the CAS fails, the operation is restarted.
155         if (Atomic::cmpxchg(next, &_exception_cache, curr) != curr) {
156           prev = NULL;
157           curr = exception_cache_acquire();
158           continue;
159         }
160       } else {
161         // It is impossible to during cleanup connect the next pointer to
162         // an ExceptionCache that has not been published before a safepoint
163         // prior to the cleanup. Therefore, release is not required.
164         prev->set_next(next);
165       }

166       // prev stays the same.
167 
168       CodeCache::release_exception_cache(curr);
169     } else {
170       prev = curr;
171     }
172 
173     curr = next;
174   }
175 }
176 
177 // public method for accessing the exception cache
178 // These are the public access methods.
179 address CompiledMethod::handler_for_exception_and_pc(Handle exception, address pc) {
180   // We never grab a lock to read the exception cache, so we may
181   // have false negatives. This is okay, as it can only happen during
182   // the first few exception lookups for a given nmethod.
183   ExceptionCache* ec = exception_cache_acquire();
184   while (ec != NULL) {
185     address ret_val;
186     if ((ret_val = ec->match(exception,pc)) != NULL) {
187       return ret_val;
188     }
189     ec = ec->next();
190   }
191   return NULL;
192 }
193 
194 void CompiledMethod::add_handler_for_exception_and_pc(Handle exception, address pc, address handler) {
195   // There are potential race conditions during exception cache updates, so we
196   // must own the ExceptionCache_lock before doing ANY modifications. Because
197   // we don't lock during reads, it is possible to have several threads attempt
198   // to update the cache with the same data. We need to check for already inserted
199   // copies of the current data before adding it.
200 
201   MutexLocker ml(ExceptionCache_lock);
202   ExceptionCache* target_entry = exception_cache_entry_for_exception(exception);
203 
204   if (target_entry == NULL || !target_entry->add_address_and_handler(pc,handler)) {
205     target_entry = new ExceptionCache(exception,pc,handler);
206     add_exception_cache_entry(target_entry);
207   }
208 }
209 


210 // private method for handling exception cache
211 // These methods are private, and used to manipulate the exception cache
212 // directly.
213 ExceptionCache* CompiledMethod::exception_cache_entry_for_exception(Handle exception) {
214   ExceptionCache* ec = exception_cache_acquire();
215   while (ec != NULL) {
216     if (ec->match_exception_with_space(exception)) {
217       return ec;
218     }
219     ec = ec->next();
220   }
221   return NULL;
222 }
223 
224 //-------------end of code for ExceptionCache--------------
225 
226 bool CompiledMethod::is_at_poll_return(address pc) {
227   RelocIterator iter(this, pc, pc+1);
228   while (iter.next()) {
229     if (iter.type() == relocInfo::poll_return_type)
230       return true;
231   }
232   return false;
233 }
234 
235 
236 bool CompiledMethod::is_at_poll_or_poll_return(address pc) {
237   RelocIterator iter(this, pc, pc+1);
238   while (iter.next()) {
239     relocInfo::relocType t = iter.type();
240     if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)
241       return true;
242   }
243   return false;
< prev index next >