< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

CLD claiming v2

128   // name.  Thus CLD's _name_and_id field should never have a null value.                                                            
129   oop cl_name_and_id = java_lang_ClassLoader::nameAndId(class_loader());                                                             
130   const char* cl_instance_name_and_id =                                                                                              
131                   (cl_name_and_id == NULL) ? _class_loader_klass->external_name() :                                                  
132                                              java_lang_String::as_utf8_string(cl_name_and_id);                                       
133   assert(cl_instance_name_and_id != NULL && cl_instance_name_and_id[0] != '\0', "class loader has no name and id");                  
134   // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.                                                            
135   _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH);                                                            
136 }                                                                                                                                    
137 
138 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) :                                                  
139   _metaspace(NULL),                                                                                                                  
140   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,                                                      
141                             Monitor::_safepoint_check_never)),                                                                       
142   _unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous),                                                                      
143   _modified_oops(true), _accumulated_modified_oops(false),                                                                           
144   // An unsafe anonymous class loader data doesn't have anything to keep                                                             
145   // it from being unloaded during parsing of the unsafe anonymous class.                                                            
146   // The null-class-loader should always be kept alive.                                                                              
147   _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0),                                                            
148   _claim_value(0),                                                                                                                   
149   _handles(),                                                                                                                        
150   _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL),                                         
151   _jmethod_ids(NULL),                                                                                                                
152   _deallocate_list(NULL),                                                                                                            
153   _next(NULL),                                                                                                                       
154   _class_loader_klass(NULL), _name(NULL), _name_and_id(NULL) {                                                                       
155 
156   if (!h_class_loader.is_null()) {                                                                                                   
157     _class_loader = _handles.add(h_class_loader());                                                                                  
158     _class_loader_klass = h_class_loader->klass();                                                                                   
159   }                                                                                                                                  
160 
161   if (!is_unsafe_anonymous) {                                                                                                        
162     // The holder is initialized later for unsafe anonymous classes, and before calling anything                                     
163     // that call class_loader().                                                                                                     
164     initialize_holder(h_class_loader);                                                                                               
165 
166     // A ClassLoaderData created solely for an unsafe anonymous class should never have a                                            
167     // ModuleEntryTable or PackageEntryTable created for it. The defining package                                                    

128   // name.  Thus CLD's _name_and_id field should never have a null value.
129   oop cl_name_and_id = java_lang_ClassLoader::nameAndId(class_loader());
130   const char* cl_instance_name_and_id =
131                   (cl_name_and_id == NULL) ? _class_loader_klass->external_name() :
132                                              java_lang_String::as_utf8_string(cl_name_and_id);
133   assert(cl_instance_name_and_id != NULL && cl_instance_name_and_id[0] != '\0', "class loader has no name and id");
134   // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.
135   _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH);
136 }
137 
138 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) :
139   _metaspace(NULL),
140   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
141                             Monitor::_safepoint_check_never)),
142   _unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous),
143   _modified_oops(true), _accumulated_modified_oops(false),
144   // An unsafe anonymous class loader data doesn't have anything to keep
145   // it from being unloaded during parsing of the unsafe anonymous class.
146   // The null-class-loader should always be kept alive.
147   _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0),
148   _claim(0),
149   _handles(),
150   _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL),
151   _jmethod_ids(NULL),
152   _deallocate_list(NULL),
153   _next(NULL),
154   _class_loader_klass(NULL), _name(NULL), _name_and_id(NULL) {
155 
156   if (!h_class_loader.is_null()) {
157     _class_loader = _handles.add(h_class_loader());
158     _class_loader_klass = h_class_loader->klass();
159   }
160 
161   if (!is_unsafe_anonymous) {
162     // The holder is initialized later for unsafe anonymous classes, and before calling anything
163     // that call class_loader().
164     initialize_holder(h_class_loader);
165 
166     // A ClassLoaderData created solely for an unsafe anonymous class should never have a
167     // ModuleEntryTable or PackageEntryTable created for it. The defining package

256 
257 bool ClassLoaderData::ChunkedHandleList::contains(oop p) {                                                                           
258   VerifyContainsOopClosure cl(p);                                                                                                    
259   oops_do(&cl);                                                                                                                      
260   return cl.found();                                                                                                                 
261 }                                                                                                                                    
262 
263 #ifndef PRODUCT                                                                                                                      
264 bool ClassLoaderData::ChunkedHandleList::owner_of(oop* oop_handle) {                                                                 
265   Chunk* chunk = _head;                                                                                                              
266   while (chunk != NULL) {                                                                                                            
267     if (&(chunk->_data[0]) <= oop_handle && oop_handle < &(chunk->_data[chunk->_size])) {                                            
268       return true;                                                                                                                   
269     }                                                                                                                                
270     chunk = chunk->_next;                                                                                                            
271   }                                                                                                                                  
272   return false;                                                                                                                      
273 }                                                                                                                                    
274 #endif // PRODUCT                                                                                                                    
275 
276 bool ClassLoaderData::claim(int claim_value) {                                                                                       
277   for (;;) {                                                                                                                         
278     int old_claim = Atomic::load(&_claim_value);                                                                                     
279     if ((old_claim & claim_value) == claim_value) {                                                                                  
280       return false;                                                                                                                  
281     }                                                                                                                                
282     int new_claim = old_claim | claim_value;                                                                                         
283     if (Atomic::cmpxchg(new_claim, &_claim_value, old_claim) == old_claim) {                                                         
284       return true;                                                                                                                   
285     }                                                                                                                                
286   }                                                                                                                                  
287 }                                                                                                                                    
288 
289 // Unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive                                              
290 // while the class is being parsed, and if the class appears on the module fixup list.                                               
291 // Due to the uniqueness that no other class shares the unsafe anonymous class' name or                                              
292 // ClassLoaderData, no other non-GC thread has knowledge of the unsafe anonymous class while                                         
293 // it is being defined, therefore _keep_alive is not volatile or atomic.                                                             
294 void ClassLoaderData::inc_keep_alive() {                                                                                             
295   if (is_unsafe_anonymous()) {                                                                                                       
296     assert(_keep_alive >= 0, "Invalid keep alive increment count");                                                                  
297     _keep_alive++;                                                                                                                   
298   }                                                                                                                                  
299 }                                                                                                                                    
300 
301 void ClassLoaderData::dec_keep_alive() {                                                                                             
302   if (is_unsafe_anonymous()) {                                                                                                       
303     assert(_keep_alive > 0, "Invalid keep alive decrement count");                                                                   
304     _keep_alive--;                                                                                                                   
305   }                                                                                                                                  
306 }                                                                                                                                    
307 
308 void ClassLoaderData::oops_do(OopClosure* f, int claim_value, bool clear_mod_oops) {                                                 
309   if (claim_value != ClassLoaderData::_claim_value_none && !claim(claim_value)) {                                                    
310     return;                                                                                                                          
311   }                                                                                                                                  
312 
313   // Only clear modified_oops after the ClassLoaderData is claimed.                                                                  
314   if (clear_mod_oops) {                                                                                                              
315     clear_modified_oops();                                                                                                           
316   }                                                                                                                                  
317 
318   _handles.oops_do(f);                                                                                                               
319 }                                                                                                                                    
320 
321 void ClassLoaderData::classes_do(KlassClosure* klass_closure) {                                                                      
322   // Lock-free access requires load_acquire                                                                                          
323   for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {                                             
324     klass_closure->do_klass(k);                                                                                                      
325     assert(k != k->next_link(), "no loops!");                                                                                        
326   }                                                                                                                                  
327 }                                                                                                                                    
328 

256 
257 bool ClassLoaderData::ChunkedHandleList::contains(oop p) {
258   VerifyContainsOopClosure cl(p);
259   oops_do(&cl);
260   return cl.found();
261 }
262 
263 #ifndef PRODUCT
264 bool ClassLoaderData::ChunkedHandleList::owner_of(oop* oop_handle) {
265   Chunk* chunk = _head;
266   while (chunk != NULL) {
267     if (&(chunk->_data[0]) <= oop_handle && oop_handle < &(chunk->_data[chunk->_size])) {
268       return true;
269     }
270     chunk = chunk->_next;
271   }
272   return false;
273 }
274 #endif // PRODUCT
275 
276 bool ClassLoaderData::try_claim(int claim) {
277   for (;;) {
278     int old_claim = Atomic::load(&_claim);
279     if ((old_claim & claim) == claim) {
280       return false;
281     }
282     int new_claim = old_claim | claim;
283     if (Atomic::cmpxchg(new_claim, &_claim, old_claim) == old_claim) {
284       return true;
285     }
286   }
287 }
288 
289 // Unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive
290 // while the class is being parsed, and if the class appears on the module fixup list.
291 // Due to the uniqueness that no other class shares the unsafe anonymous class' name or
292 // ClassLoaderData, no other non-GC thread has knowledge of the unsafe anonymous class while
293 // it is being defined, therefore _keep_alive is not volatile or atomic.
294 void ClassLoaderData::inc_keep_alive() {
295   if (is_unsafe_anonymous()) {
296     assert(_keep_alive >= 0, "Invalid keep alive increment count");
297     _keep_alive++;
298   }
299 }
300 
301 void ClassLoaderData::dec_keep_alive() {
302   if (is_unsafe_anonymous()) {
303     assert(_keep_alive > 0, "Invalid keep alive decrement count");
304     _keep_alive--;
305   }
306 }
307 
308 void ClassLoaderData::oops_do(OopClosure* f, int claim_value, bool clear_mod_oops) {
309   if (claim_value != ClassLoaderData::_claim_none && !try_claim(claim_value)) {
310     return;
311   }
312 
313   // Only clear modified_oops after the ClassLoaderData is claimed.
314   if (clear_mod_oops) {
315     clear_modified_oops();
316   }
317 
318   _handles.oops_do(f);
319 }
320 
321 void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
322   // Lock-free access requires load_acquire
323   for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
324     klass_closure->do_klass(k);
325     assert(k != k->next_link(), "no loops!");
326   }
327 }
328 

433     LogTarget(Trace, class, loader, data) lt;                                                                                        
434     if (lt.is_enabled()) {                                                                                                           
435       ResourceMark rm;                                                                                                               
436       LogStream ls(lt);                                                                                                              
437       ls.print("adding dependency from ");                                                                                           
438       print_value_on(&ls);                                                                                                           
439       ls.print(" to ");                                                                                                              
440       to_cld->print_value_on(&ls);                                                                                                   
441       ls.cr();                                                                                                                       
442     }                                                                                                                                
443     Handle dependency(Thread::current(), to);                                                                                        
444     add_handle(dependency);                                                                                                          
445     // Added a potentially young gen oop to the ClassLoaderData                                                                      
446     record_modified_oops();                                                                                                          
447   }                                                                                                                                  
448 }                                                                                                                                    
449 
450 
451 void ClassLoaderDataGraph::clear_claimed_marks() {                                                                                   
452   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {                                                               
453     cld->clear_claimed();                                                                                                            
454   }                                                                                                                                  
455 }                                                                                                                                    
456 
457 void ClassLoaderData::add_class(Klass* k, bool publicize /* true */) {                                                               
458   {                                                                                                                                  
459     MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);                                                             
460     Klass* old_value = _klasses;                                                                                                     
461     k->set_next_link(old_value);                                                                                                     
462     // Link the new item into the list, making sure the linked class is stable                                                       
463     // since the list can be walked without a lock                                                                                   
464     OrderAccess::release_store(&_klasses, k);                                                                                        
465     if (k->is_array_klass()) {                                                                                                       
466       ClassLoaderDataGraph::inc_array_classes(1);                                                                                    
467     } else {                                                                                                                         
468       ClassLoaderDataGraph::inc_instance_classes(1);                                                                                 
469     }                                                                                                                                
470   }                                                                                                                                  
471 
472   if (publicize) {                                                                                                                   

433     LogTarget(Trace, class, loader, data) lt;
434     if (lt.is_enabled()) {
435       ResourceMark rm;
436       LogStream ls(lt);
437       ls.print("adding dependency from ");
438       print_value_on(&ls);
439       ls.print(" to ");
440       to_cld->print_value_on(&ls);
441       ls.cr();
442     }
443     Handle dependency(Thread::current(), to);
444     add_handle(dependency);
445     // Added a potentially young gen oop to the ClassLoaderData
446     record_modified_oops();
447   }
448 }
449 
450 
451 void ClassLoaderDataGraph::clear_claimed_marks() {
452   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
453     cld->clear_claim();
454   }
455 }
456 
457 void ClassLoaderData::add_class(Klass* k, bool publicize /* true */) {
458   {
459     MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
460     Klass* old_value = _klasses;
461     k->set_next_link(old_value);
462     // Link the new item into the list, making sure the linked class is stable
463     // since the list can be walked without a lock
464     OrderAccess::release_store(&_klasses, k);
465     if (k->is_array_klass()) {
466       ClassLoaderDataGraph::inc_array_classes(1);
467     } else {
468       ClassLoaderDataGraph::inc_instance_classes(1);
469     }
470   }
471 
472   if (publicize) {
< prev index next >