comparison src/share/vm/classfile/classLoaderData.cpp @ 10181:1cb4795305b9

8011802: NPG: init_dependencies in class loader data graph can cause invalid CLD Summary: Restructure initialization of ClassLoaderData to not add a new instance if init_dependencies fail Reviewed-by: stefank, coleenp
author mgerdin
date Tue, 23 Apr 2013 08:39:55 +0200
parents c23dbf0e8ab7
children 868d87ed63c8
comparison
equal deleted inserted replaced
10180:ebded0261dfc 10181:1cb4795305b9
51 #include "classfile/classLoaderData.inline.hpp" 51 #include "classfile/classLoaderData.inline.hpp"
52 #include "classfile/javaClasses.hpp" 52 #include "classfile/javaClasses.hpp"
53 #include "classfile/metadataOnStackMark.hpp" 53 #include "classfile/metadataOnStackMark.hpp"
54 #include "classfile/systemDictionary.hpp" 54 #include "classfile/systemDictionary.hpp"
55 #include "code/codeCache.hpp" 55 #include "code/codeCache.hpp"
56 #include "memory/gcLocker.hpp"
56 #include "memory/metadataFactory.hpp" 57 #include "memory/metadataFactory.hpp"
57 #include "memory/metaspaceShared.hpp" 58 #include "memory/metaspaceShared.hpp"
58 #include "memory/oopFactory.hpp" 59 #include "memory/oopFactory.hpp"
59 #include "runtime/jniHandles.hpp" 60 #include "runtime/jniHandles.hpp"
60 #include "runtime/mutex.hpp" 61 #include "runtime/mutex.hpp"
421 } 422 }
422 423
423 // These anonymous class loaders are to contain classes used for JSR292 424 // These anonymous class loaders are to contain classes used for JSR292
424 ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) { 425 ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
425 // Add a new class loader data to the graph. 426 // Add a new class loader data to the graph.
426 return ClassLoaderDataGraph::add(NULL, loader, CHECK_NULL); 427 return ClassLoaderDataGraph::add(loader, true, CHECK_NULL);
427 } 428 }
428 429
429 const char* ClassLoaderData::loader_name() { 430 const char* ClassLoaderData::loader_name() {
430 // Handles null class loader 431 // Handles null class loader
431 return SystemDictionary::loader_name(class_loader()); 432 return SystemDictionary::loader_name(class_loader());
493 // GC root of class loader data created. 494 // GC root of class loader data created.
494 ClassLoaderData* ClassLoaderDataGraph::_head = NULL; 495 ClassLoaderData* ClassLoaderDataGraph::_head = NULL;
495 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; 496 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL;
496 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; 497 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
497 498
498
499 // Add a new class loader data node to the list. Assign the newly created 499 // Add a new class loader data node to the list. Assign the newly created
500 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field 500 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
501 ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader, TRAPS) { 501 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
502 // Not assigned a class loader data yet. 502 // Not assigned a class loader data yet.
503 // Create one. 503 // Create one.
504 ClassLoaderData* *list_head = &_head;
505 ClassLoaderData* next = _head;
506
507 bool is_anonymous = (cld_addr == NULL);
508 ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); 504 ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
509 505 cld->init_dependencies(THREAD);
510 if (cld_addr != NULL) { 506 if (HAS_PENDING_EXCEPTION) {
511 // First, Atomically set it 507 delete cld;
512 ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); 508 return NULL;
513 if (old != NULL) { 509 }
514 delete cld; 510
515 // Returns the data. 511 No_Safepoint_Verifier no_safepoints; // nothing is keeping the dependencies array in cld alive
516 return old; 512 // make sure we don't encounter a GC until we've inserted
513 // cld into the CLDG
514
515 if (!is_anonymous) {
516 ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
517 if (cld_addr != NULL) {
518 // First, Atomically set it
519 ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
520 if (old != NULL) {
521 delete cld;
522 // Returns the data.
523 return old;
524 }
517 } 525 }
518 } 526 }
519 527
520 // We won the race, and therefore the task of adding the data to the list of 528 // We won the race, and therefore the task of adding the data to the list of
521 // class loader data 529 // class loader data
530 ClassLoaderData** list_head = &_head;
531 ClassLoaderData* next = _head;
532
522 do { 533 do {
523 cld->set_next(next); 534 cld->set_next(next);
524 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next); 535 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
525 if (exchanged == next) { 536 if (exchanged == next) {
526 if (TraceClassLoaderData) { 537 if (TraceClassLoaderData) {
529 tty->print("create class loader data "PTR_FORMAT, cld); 540 tty->print("create class loader data "PTR_FORMAT, cld);
530 tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(), 541 tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(),
531 cld->loader_name()); 542 cld->loader_name());
532 tty->print_cr("]"); 543 tty->print_cr("]");
533 } 544 }
534 // Create dependencies after the CLD is added to the list. Otherwise,
535 // the GC GC will not find the CLD and the _class_loader field will
536 // not be updated.
537 cld->init_dependencies(CHECK_NULL);
538 return cld; 545 return cld;
539 } 546 }
540 next = exchanged; 547 next = exchanged;
541 } while (true); 548 } while (true);
542 549