Mercurial > hg > graal-compiler
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 |