< prev index next >

src/share/vm/oops/instanceKlass.cpp

Print this page

        

*** 86,125 **** #define HOTSPOT_CLASS_INITIALIZATION_erroneous HOTSPOT_CLASS_INITIALIZATION_ERRONEOUS #define HOTSPOT_CLASS_INITIALIZATION_super__failed HOTSPOT_CLASS_INITIALIZATION_SUPER_FAILED #define HOTSPOT_CLASS_INITIALIZATION_clinit HOTSPOT_CLASS_INITIALIZATION_CLINIT #define HOTSPOT_CLASS_INITIALIZATION_error HOTSPOT_CLASS_INITIALIZATION_ERROR #define HOTSPOT_CLASS_INITIALIZATION_end HOTSPOT_CLASS_INITIALIZATION_END ! #define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) \ { \ char* data = NULL; \ int len = 0; \ ! Symbol* name = (clss)->name(); \ ! if (name != NULL) { \ ! data = (char*)name->bytes(); \ ! len = name->utf8_length(); \ } \ HOTSPOT_CLASS_INITIALIZATION_##type( \ ! data, len, (clss)->class_loader(), thread_type); \ } ! #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ { \ char* data = NULL; \ int len = 0; \ ! Symbol* name = (clss)->name(); \ ! if (name != NULL) { \ ! data = (char*)name->bytes(); \ ! len = name->utf8_length(); \ } \ HOTSPOT_CLASS_INITIALIZATION_##type( \ ! data, len, (clss)->class_loader(), thread_type, wait); \ } #else // ndef DTRACE_ENABLED ! #define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) ! #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) #endif // ndef DTRACE_ENABLED volatile int InstanceKlass::_total_instanceKlass_count = 0; --- 86,125 ---- #define HOTSPOT_CLASS_INITIALIZATION_erroneous HOTSPOT_CLASS_INITIALIZATION_ERRONEOUS #define HOTSPOT_CLASS_INITIALIZATION_super__failed HOTSPOT_CLASS_INITIALIZATION_SUPER_FAILED #define HOTSPOT_CLASS_INITIALIZATION_clinit HOTSPOT_CLASS_INITIALIZATION_CLINIT #define HOTSPOT_CLASS_INITIALIZATION_error HOTSPOT_CLASS_INITIALIZATION_ERROR #define HOTSPOT_CLASS_INITIALIZATION_end HOTSPOT_CLASS_INITIALIZATION_END ! #define DTRACE_CLASSINIT_PROBE(type, thread_type) \ { \ char* data = NULL; \ int len = 0; \ ! Symbol* clss_name = name(); \ ! if (clss_name != NULL) { \ ! data = (char*)clss_name->bytes(); \ ! len = clss_name->utf8_length(); \ } \ HOTSPOT_CLASS_INITIALIZATION_##type( \ ! data, len, class_loader(), thread_type); \ } ! #define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait) \ { \ char* data = NULL; \ int len = 0; \ ! Symbol* clss_name = name(); \ ! if (clss_name != NULL) { \ ! data = (char*)clss_name->bytes(); \ ! len = clss_name->utf8_length(); \ } \ HOTSPOT_CLASS_INITIALIZATION_##type( \ ! data, len, class_loader(), thread_type, wait); \ } #else // ndef DTRACE_ENABLED ! #define DTRACE_CLASSINIT_PROBE(type, thread_type) ! #define DTRACE_CLASSINIT_PROBE_WAIT(type, thread_type, wait) #endif // ndef DTRACE_ENABLED volatile int InstanceKlass::_total_instanceKlass_count = 0;
*** 383,400 **** if (this->is_not_initialized()) { // abort if the the class has a class initializer if (this->class_initializer() != NULL) return; // abort if it is java.lang.Object (initialization is handled in genesis) ! Klass* super = this->super(); ! if (super == NULL) return; // abort if the super class should be initialized ! if (!InstanceKlass::cast(super)->is_initialized()) return; // call body to expose the this pointer ! eager_initialize_impl(this); } } // JVMTI spec thinks there are signers and protection domain in the // instanceKlass. These accessors pretend these fields are there. --- 383,400 ---- if (this->is_not_initialized()) { // abort if the the class has a class initializer if (this->class_initializer() != NULL) return; // abort if it is java.lang.Object (initialization is handled in genesis) ! Klass* super_klass = super(); ! if (super_klass == NULL) return; // abort if the super class should be initialized ! if (!InstanceKlass::cast(super_klass)->is_initialized()) return; // call body to expose the this pointer ! eager_initialize_impl(); } } // JVMTI spec thinks there are signers and protection domain in the // instanceKlass. These accessors pretend these fields are there.
*** 429,492 **** OrderAccess::storestore(); java_lang_Class::set_init_lock(java_mirror(), NULL); assert(!is_not_initialized(), "class must be initialized now"); } ! void InstanceKlass::eager_initialize_impl(InstanceKlass* this_k) { EXCEPTION_MARK; HandleMark hm(THREAD); ! Handle init_lock(THREAD, this_k->init_lock()); ! ObjectLocker ol(init_lock, THREAD, init_lock() != NULL); // abort if someone beat us to the initialization ! if (!this_k->is_not_initialized()) return; // note: not equivalent to is_initialized() ! ClassState old_state = this_k->init_state(); ! link_class_impl(this_k, true, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; // Abort if linking the class throws an exception. // Use a test to avoid redundantly resetting the state if there's // no change. Set_init_state() asserts that state changes make // progress, whereas here we might just be spinning in place. ! if( old_state != this_k->_init_state ) ! this_k->set_init_state (old_state); } else { // linking successfull, mark class as initialized ! this_k->set_init_state (fully_initialized); ! this_k->fence_and_clear_init_lock(); // trace if (log_is_enabled(Info, class, init)) { ResourceMark rm(THREAD); ! log_info(class, init)("[Initialized %s without side effects]", this_k->external_name()); } } } // See "The Virtual Machine Specification" section 2.16.5 for a detailed explanation of the class initialization // process. The step comments refers to the procedure described in that section. // Note: implementation moved to static method to expose the this pointer. void InstanceKlass::initialize(TRAPS) { if (this->should_be_initialized()) { ! initialize_impl(this, CHECK); // Note: at this point the class may be initialized // OR it may be in the state of being initialized // in case of recursive initialization! } else { assert(is_initialized(), "sanity check"); } } ! bool InstanceKlass::verify_code( ! InstanceKlass* this_k, bool throw_verifyerror, TRAPS) { // 1) Verify the bytecodes Verifier::Mode mode = throw_verifyerror ? Verifier::ThrowException : Verifier::NoException; ! return Verifier::verify(this_k, mode, this_k->should_verify_class(), THREAD); } // Used exclusively by the shared spaces dump mechanism to prevent // classes mapped into the shared regions in new VMs from appearing linked. --- 429,491 ---- OrderAccess::storestore(); java_lang_Class::set_init_lock(java_mirror(), NULL); assert(!is_not_initialized(), "class must be initialized now"); } ! void InstanceKlass::eager_initialize_impl() { EXCEPTION_MARK; HandleMark hm(THREAD); ! Handle h_init_lock(THREAD, init_lock()); ! ObjectLocker ol(h_init_lock, THREAD, init_lock() != NULL); // abort if someone beat us to the initialization ! if (!is_not_initialized()) return; // note: not equivalent to is_initialized() ! ClassState old_state = init_state(); ! link_class_impl(true, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; // Abort if linking the class throws an exception. // Use a test to avoid redundantly resetting the state if there's // no change. Set_init_state() asserts that state changes make // progress, whereas here we might just be spinning in place. ! if (old_state != _init_state) ! set_init_state(old_state); } else { // linking successfull, mark class as initialized ! set_init_state(fully_initialized); ! fence_and_clear_init_lock(); // trace if (log_is_enabled(Info, class, init)) { ResourceMark rm(THREAD); ! log_info(class, init)("[Initialized %s without side effects]", external_name()); } } } // See "The Virtual Machine Specification" section 2.16.5 for a detailed explanation of the class initialization // process. The step comments refers to the procedure described in that section. // Note: implementation moved to static method to expose the this pointer. void InstanceKlass::initialize(TRAPS) { if (this->should_be_initialized()) { ! initialize_impl(CHECK); // Note: at this point the class may be initialized // OR it may be in the state of being initialized // in case of recursive initialization! } else { assert(is_initialized(), "sanity check"); } } ! bool InstanceKlass::verify_code(bool throw_verifyerror, TRAPS) { // 1) Verify the bytecodes Verifier::Mode mode = throw_verifyerror ? Verifier::ThrowException : Verifier::NoException; ! return Verifier::verify(this, mode, should_verify_class(), THREAD); } // Used exclusively by the shared spaces dump mechanism to prevent // classes mapped into the shared regions in new VMs from appearing linked.
*** 497,573 **** } void InstanceKlass::link_class(TRAPS) { assert(is_loaded(), "must be loaded"); if (!is_linked()) { ! link_class_impl(this, true, CHECK); } } // Called to verify that a class can link during initialization, without // throwing a VerifyError. bool InstanceKlass::link_class_or_fail(TRAPS) { assert(is_loaded(), "must be loaded"); if (!is_linked()) { ! link_class_impl(this, false, CHECK_false); } return is_linked(); } ! bool InstanceKlass::link_class_impl( ! InstanceKlass* this_k, bool throw_verifyerror, TRAPS) { ! if (DumpSharedSpaces && this_k->is_in_error_state()) { // This is for CDS dumping phase only -- we use the in_error_state to indicate that // the class has failed verification. Throwing the NoClassDefFoundError here is just // a convenient way to stop repeat attempts to verify the same (bad) class. // // Note that the NoClassDefFoundError is not part of the JLS, and should not be thrown // if we are executing Java code. This is not a problem for CDS dumping phase since // it doesn't execute any Java code. ResourceMark rm(THREAD); ! THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(), ! this_k->external_name(), false); } // return if already verified ! if (this_k->is_linked()) { return true; } // Timing // timer handles recursion assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl"); JavaThread* jt = (JavaThread*)THREAD; // link super class before linking this class ! Klass* super = this_k->super(); ! if (super != NULL) { ! if (super->is_interface()) { // check if super class is an interface ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), "class %s has interface %s as super class", ! this_k->external_name(), ! super->external_name() ); return false; } ! InstanceKlass* ik_super = InstanceKlass::cast(super); ! link_class_impl(ik_super, throw_verifyerror, CHECK_false); } // link all interfaces implemented by this class before linking this class ! Array<Klass*>* interfaces = this_k->local_interfaces(); int num_interfaces = interfaces->length(); for (int index = 0; index < num_interfaces; index++) { InstanceKlass* interk = InstanceKlass::cast(interfaces->at(index)); ! link_class_impl(interk, throw_verifyerror, CHECK_false); } // in case the class is linked in the process of linking its superclasses ! if (this_k->is_linked()) { return true; } // trace only the link time for this klass that includes // the verification time --- 496,570 ---- } void InstanceKlass::link_class(TRAPS) { assert(is_loaded(), "must be loaded"); if (!is_linked()) { ! link_class_impl(true, CHECK); } } // Called to verify that a class can link during initialization, without // throwing a VerifyError. bool InstanceKlass::link_class_or_fail(TRAPS) { assert(is_loaded(), "must be loaded"); if (!is_linked()) { ! link_class_impl(false, CHECK_false); } return is_linked(); } ! bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) { ! if (DumpSharedSpaces && is_in_error_state()) { // This is for CDS dumping phase only -- we use the in_error_state to indicate that // the class has failed verification. Throwing the NoClassDefFoundError here is just // a convenient way to stop repeat attempts to verify the same (bad) class. // // Note that the NoClassDefFoundError is not part of the JLS, and should not be thrown // if we are executing Java code. This is not a problem for CDS dumping phase since // it doesn't execute any Java code. ResourceMark rm(THREAD); ! THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(), external_name(), false); } // return if already verified ! if (is_linked()) { return true; } // Timing // timer handles recursion assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl"); JavaThread* jt = (JavaThread*)THREAD; // link super class before linking this class ! Klass* super_klass = super(); ! if (super_klass != NULL) { ! if (super_klass->is_interface()) { // check if super class is an interface ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), "class %s has interface %s as super class", ! external_name(), ! super_klass->external_name() ); return false; } ! InstanceKlass* ik_super = InstanceKlass::cast(super_klass); ! ik_super->link_class_impl(throw_verifyerror, CHECK_false); } // link all interfaces implemented by this class before linking this class ! Array<Klass*>* interfaces = local_interfaces(); int num_interfaces = interfaces->length(); for (int index = 0; index < num_interfaces; index++) { InstanceKlass* interk = InstanceKlass::cast(interfaces->at(index)); ! interk->link_class_impl(throw_verifyerror, CHECK_false); } // in case the class is linked in the process of linking its superclasses ! if (is_linked()) { return true; } // trace only the link time for this klass that includes // the verification time
*** 579,647 **** PerfClassTraceTime::CLASS_LINK); // verification & rewriting { HandleMark hm(THREAD); ! Handle init_lock(THREAD, this_k->init_lock()); ! ObjectLocker ol(init_lock, THREAD, init_lock() != NULL); // rewritten will have been set if loader constraint error found // on an earlier link attempt // don't verify or rewrite if already rewritten // ! if (!this_k->is_linked()) { ! if (!this_k->is_rewritten()) { { ! bool verify_ok = verify_code(this_k, throw_verifyerror, THREAD); if (!verify_ok) { return false; } } // Just in case a side-effect of verify linked this class already // (which can sometimes happen since the verifier loads classes // using custom class loaders, which are free to initialize things) ! if (this_k->is_linked()) { return true; } // also sets rewritten ! this_k->rewrite_class(CHECK_false); ! } else if (this_k->is_shared()) { ! SystemDictionaryShared::check_verification_constraints(this_k, CHECK_false); } // relocate jsrs and link methods after they are all rewritten ! this_k->link_methods(CHECK_false); // Initialize the vtable and interface table after // methods have been rewritten since rewrite may // fabricate new Method*s. // also does loader constraint checking // // initialize_vtable and initialize_itable need to be rerun for // a shared class if the class is not loaded by the NULL classloader. ! ClassLoaderData * loader_data = this_k->class_loader_data(); ! if (!(this_k->is_shared() && loader_data->is_the_null_class_loader_data())) { ResourceMark rm(THREAD); ! this_k->vtable()->initialize_vtable(true, CHECK_false); ! this_k->itable()->initialize_itable(true, CHECK_false); } #ifdef ASSERT else { ResourceMark rm(THREAD); ! this_k->vtable()->verify(tty, true); // In case itable verification is ever added. ! // this_k->itable()->verify(tty, true); } #endif ! this_k->set_init_state(linked); if (JvmtiExport::should_post_class_prepare()) { Thread *thread = THREAD; assert(thread->is_Java_thread(), "thread->is_Java_thread()"); ! JvmtiExport::post_class_prepare((JavaThread *) thread, this_k); } } } return true; } --- 576,644 ---- PerfClassTraceTime::CLASS_LINK); // verification & rewriting { HandleMark hm(THREAD); ! Handle h_init_lock(THREAD, init_lock()); ! ObjectLocker ol(h_init_lock, THREAD, init_lock() != NULL); // rewritten will have been set if loader constraint error found // on an earlier link attempt // don't verify or rewrite if already rewritten // ! if (!is_linked()) { ! if (!is_rewritten()) { { ! bool verify_ok = verify_code(throw_verifyerror, THREAD); if (!verify_ok) { return false; } } // Just in case a side-effect of verify linked this class already // (which can sometimes happen since the verifier loads classes // using custom class loaders, which are free to initialize things) ! if (is_linked()) { return true; } // also sets rewritten ! rewrite_class(CHECK_false); ! } else if (is_shared()) { ! SystemDictionaryShared::check_verification_constraints(this, CHECK_false); } // relocate jsrs and link methods after they are all rewritten ! link_methods(CHECK_false); // Initialize the vtable and interface table after // methods have been rewritten since rewrite may // fabricate new Method*s. // also does loader constraint checking // // initialize_vtable and initialize_itable need to be rerun for // a shared class if the class is not loaded by the NULL classloader. ! ClassLoaderData * loader_data = class_loader_data(); ! if (!(is_shared() && loader_data->is_the_null_class_loader_data())) { ResourceMark rm(THREAD); ! vtable()->initialize_vtable(true, CHECK_false); ! itable()->initialize_itable(true, CHECK_false); } #ifdef ASSERT else { ResourceMark rm(THREAD); ! vtable()->verify(tty, true); // In case itable verification is ever added. ! // itable()->verify(tty, true); } #endif ! set_init_state(linked); if (JvmtiExport::should_post_class_prepare()) { Thread *thread = THREAD; assert(thread->is_Java_thread(), "thread->is_Java_thread()"); ! JvmtiExport::post_class_prepare((JavaThread *) thread, this); } } } return true; }
*** 672,747 **** m->link_method(m, CHECK); } } // Eagerly initialize superinterfaces that declare default methods (concrete instance: any access) ! void InstanceKlass::initialize_super_interfaces(InstanceKlass* this_k, TRAPS) { ! assert (this_k->has_nonstatic_concrete_methods(), "caller should have checked this"); ! for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { ! Klass* iface = this_k->local_interfaces()->at(i); InstanceKlass* ik = InstanceKlass::cast(iface); // Initialization is depth first search ie. we start with top of the inheritance tree // has_nonstatic_concrete_methods drives searching superinterfaces since it // means has_nonstatic_concrete_methods in its superinterface hierarchy if (ik->has_nonstatic_concrete_methods()) { ! ik->initialize_super_interfaces(ik, CHECK); } // Only initialize() interfaces that "declare" concrete methods. if (ik->should_be_initialized() && ik->declares_nonstatic_concrete_methods()) { ik->initialize(CHECK); } } } ! void InstanceKlass::initialize_impl(InstanceKlass* this_k, TRAPS) { HandleMark hm(THREAD); // Make sure klass is linked (verified) before initialization // A class could already be verified, since it has been reflected upon. ! this_k->link_class(CHECK); ! DTRACE_CLASSINIT_PROBE(required, this_k, -1); bool wait = false; // refer to the JVM book page 47 for description of steps // Step 1 { ! Handle init_lock(THREAD, this_k->init_lock()); ! ObjectLocker ol(init_lock, THREAD, init_lock() != NULL); Thread *self = THREAD; // it's passed the current thread // Step 2 // If we were to use wait() instead of waitInterruptibly() then // we might end up throwing IE from link/symbol resolution sites // that aren't expected to throw. This would wreak havoc. See 6320309. ! while(this_k->is_being_initialized() && !this_k->is_reentrant_initialization(self)) { wait = true; ol.waitUninterruptibly(CHECK); } // Step 3 ! if (this_k->is_being_initialized() && this_k->is_reentrant_initialization(self)) { ! DTRACE_CLASSINIT_PROBE_WAIT(recursive, this_k, -1,wait); return; } // Step 4 ! if (this_k->is_initialized()) { ! DTRACE_CLASSINIT_PROBE_WAIT(concurrent, this_k, -1,wait); return; } // Step 5 ! if (this_k->is_in_error_state()) { ! DTRACE_CLASSINIT_PROBE_WAIT(erroneous, this_k, -1,wait); ResourceMark rm(THREAD); const char* desc = "Could not initialize class "; ! const char* className = this_k->external_name(); size_t msglen = strlen(desc) + strlen(className) + 1; char* message = NEW_RESOURCE_ARRAY(char, msglen); if (NULL == message) { // Out of memory: can't create detailed error message THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className); --- 669,744 ---- m->link_method(m, CHECK); } } // Eagerly initialize superinterfaces that declare default methods (concrete instance: any access) ! void InstanceKlass::initialize_super_interfaces(TRAPS) { ! assert (has_nonstatic_concrete_methods(), "caller should have checked this"); ! for (int i = 0; i < local_interfaces()->length(); ++i) { ! Klass* iface = local_interfaces()->at(i); InstanceKlass* ik = InstanceKlass::cast(iface); // Initialization is depth first search ie. we start with top of the inheritance tree // has_nonstatic_concrete_methods drives searching superinterfaces since it // means has_nonstatic_concrete_methods in its superinterface hierarchy if (ik->has_nonstatic_concrete_methods()) { ! ik->initialize_super_interfaces(CHECK); } // Only initialize() interfaces that "declare" concrete methods. if (ik->should_be_initialized() && ik->declares_nonstatic_concrete_methods()) { ik->initialize(CHECK); } } } ! void InstanceKlass::initialize_impl(TRAPS) { HandleMark hm(THREAD); // Make sure klass is linked (verified) before initialization // A class could already be verified, since it has been reflected upon. ! link_class(CHECK); ! DTRACE_CLASSINIT_PROBE(required, -1); bool wait = false; // refer to the JVM book page 47 for description of steps // Step 1 { ! Handle h_init_lock(THREAD, init_lock()); ! ObjectLocker ol(h_init_lock, THREAD, init_lock() != NULL); Thread *self = THREAD; // it's passed the current thread // Step 2 // If we were to use wait() instead of waitInterruptibly() then // we might end up throwing IE from link/symbol resolution sites // that aren't expected to throw. This would wreak havoc. See 6320309. ! while(is_being_initialized() && !is_reentrant_initialization(self)) { wait = true; ol.waitUninterruptibly(CHECK); } // Step 3 ! if (is_being_initialized() && is_reentrant_initialization(self)) { ! DTRACE_CLASSINIT_PROBE_WAIT(recursive, -1, wait); return; } // Step 4 ! if (is_initialized()) { ! DTRACE_CLASSINIT_PROBE_WAIT(concurrent, -1, wait); return; } // Step 5 ! if (is_in_error_state()) { ! DTRACE_CLASSINIT_PROBE_WAIT(erroneous, -1, wait); ResourceMark rm(THREAD); const char* desc = "Could not initialize class "; ! const char* className = external_name(); size_t msglen = strlen(desc) + strlen(className) + 1; char* message = NEW_RESOURCE_ARRAY(char, msglen); if (NULL == message) { // Out of memory: can't create detailed error message THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);
*** 750,819 **** THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message); } } // Step 6 ! this_k->set_init_state(being_initialized); ! this_k->set_init_thread(self); } // Step 7 // Next, if C is a class rather than an interface, initialize it's super class and super // interfaces. ! if (!this_k->is_interface()) { ! Klass* super_klass = this_k->super(); if (super_klass != NULL && super_klass->should_be_initialized()) { super_klass->initialize(THREAD); } // If C implements any interface that declares a non-static, concrete method, // the initialization of C triggers initialization of its super interfaces. // Only need to recurse if has_nonstatic_concrete_methods which includes declaring and // having a superinterface that declares, non-static, concrete methods ! if (!HAS_PENDING_EXCEPTION && this_k->has_nonstatic_concrete_methods()) { ! this_k->initialize_super_interfaces(this_k, THREAD); } // If any exceptions, complete abruptly, throwing the same exception as above. if (HAS_PENDING_EXCEPTION) { Handle e(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; { EXCEPTION_MARK; // Locks object, set state, and notify all waiting threads ! this_k->set_initialization_state_and_notify(initialization_error, THREAD); CLEAR_PENDING_EXCEPTION; } ! DTRACE_CLASSINIT_PROBE_WAIT(super__failed, this_k, -1,wait); THROW_OOP(e()); } } // Look for aot compiled methods for this klass, including class initializer. ! AOTLoader::load_for_klass(this_k, THREAD); // Step 8 { assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); JavaThread* jt = (JavaThread*)THREAD; ! DTRACE_CLASSINIT_PROBE_WAIT(clinit, this_k, -1,wait); // Timer includes any side effects of class initialization (resolution, // etc), but not recursive entry into call_class_initializer(). PerfClassTraceTime timer(ClassLoader::perf_class_init_time(), ClassLoader::perf_class_init_selftime(), ClassLoader::perf_classes_inited(), jt->get_thread_stat()->perf_recursion_counts_addr(), jt->get_thread_stat()->perf_timers_addr(), PerfClassTraceTime::CLASS_CLINIT); ! this_k->call_class_initializer(THREAD); } // Step 9 if (!HAS_PENDING_EXCEPTION) { ! this_k->set_initialization_state_and_notify(fully_initialized, CHECK); { ResourceMark rm(THREAD); ! debug_only(this_k->vtable()->verify(tty, true);) } } else { // Step 10 and 11 Handle e(THREAD, PENDING_EXCEPTION); --- 747,816 ---- THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message); } } // Step 6 ! set_init_state(being_initialized); ! set_init_thread(self); } // Step 7 // Next, if C is a class rather than an interface, initialize it's super class and super // interfaces. ! if (!is_interface()) { ! Klass* super_klass = super(); if (super_klass != NULL && super_klass->should_be_initialized()) { super_klass->initialize(THREAD); } // If C implements any interface that declares a non-static, concrete method, // the initialization of C triggers initialization of its super interfaces. // Only need to recurse if has_nonstatic_concrete_methods which includes declaring and // having a superinterface that declares, non-static, concrete methods ! if (!HAS_PENDING_EXCEPTION && has_nonstatic_concrete_methods()) { ! initialize_super_interfaces(THREAD); } // If any exceptions, complete abruptly, throwing the same exception as above. if (HAS_PENDING_EXCEPTION) { Handle e(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; { EXCEPTION_MARK; // Locks object, set state, and notify all waiting threads ! set_initialization_state_and_notify(initialization_error, THREAD); CLEAR_PENDING_EXCEPTION; } ! DTRACE_CLASSINIT_PROBE_WAIT(super__failed, -1, wait); THROW_OOP(e()); } } // Look for aot compiled methods for this klass, including class initializer. ! AOTLoader::load_for_klass(this, THREAD); // Step 8 { assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); JavaThread* jt = (JavaThread*)THREAD; ! DTRACE_CLASSINIT_PROBE_WAIT(clinit, -1, wait); // Timer includes any side effects of class initialization (resolution, // etc), but not recursive entry into call_class_initializer(). PerfClassTraceTime timer(ClassLoader::perf_class_init_time(), ClassLoader::perf_class_init_selftime(), ClassLoader::perf_classes_inited(), jt->get_thread_stat()->perf_recursion_counts_addr(), jt->get_thread_stat()->perf_timers_addr(), PerfClassTraceTime::CLASS_CLINIT); ! call_class_initializer(THREAD); } // Step 9 if (!HAS_PENDING_EXCEPTION) { ! set_initialization_state_and_notify(fully_initialized, CHECK); { ResourceMark rm(THREAD); ! debug_only(vtable()->verify(tty, true);) } } else { // Step 10 and 11 Handle e(THREAD, PENDING_EXCEPTION);
*** 821,865 **** // JVMTI has already reported the pending exception // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError JvmtiExport::clear_detected_exception((JavaThread*)THREAD); { EXCEPTION_MARK; ! this_k->set_initialization_state_and_notify(initialization_error, THREAD); CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below // JVMTI has already reported the pending exception // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError JvmtiExport::clear_detected_exception((JavaThread*)THREAD); } ! DTRACE_CLASSINIT_PROBE_WAIT(error, this_k, -1,wait); if (e->is_a(SystemDictionary::Error_klass())) { THROW_OOP(e()); } else { JavaCallArguments args(e); THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(), vmSymbols::throwable_void_signature(), &args); } } ! DTRACE_CLASSINIT_PROBE_WAIT(end, this_k, -1,wait); } // Note: implementation moved to static method to expose the this pointer. void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) { ! set_initialization_state_and_notify_impl(this, state, CHECK); } ! void InstanceKlass::set_initialization_state_and_notify_impl(InstanceKlass* this_k, ClassState state, TRAPS) { ! Handle init_lock(THREAD, this_k->init_lock()); if (init_lock() != NULL) { ! ObjectLocker ol(init_lock, THREAD); ! this_k->set_init_state(state); ! this_k->fence_and_clear_init_lock(); ol.notify_all(CHECK); } else { assert(init_lock() != NULL, "The initialization state should never be set twice"); ! this_k->set_init_state(state); } } // The embedded _implementor field can only record one implementor. // When there are more than one implementors, the _implementor field --- 818,862 ---- // JVMTI has already reported the pending exception // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError JvmtiExport::clear_detected_exception((JavaThread*)THREAD); { EXCEPTION_MARK; ! set_initialization_state_and_notify(initialization_error, THREAD); CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below // JVMTI has already reported the pending exception // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError JvmtiExport::clear_detected_exception((JavaThread*)THREAD); } ! DTRACE_CLASSINIT_PROBE_WAIT(error, -1, wait); if (e->is_a(SystemDictionary::Error_klass())) { THROW_OOP(e()); } else { JavaCallArguments args(e); THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(), vmSymbols::throwable_void_signature(), &args); } } ! DTRACE_CLASSINIT_PROBE_WAIT(end, -1, wait); } // Note: implementation moved to static method to expose the this pointer. void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) { ! set_initialization_state_and_notify_impl(state, CHECK); } ! void InstanceKlass::set_initialization_state_and_notify_impl(ClassState state, TRAPS) { ! Handle h_init_lock(THREAD, init_lock()); if (init_lock() != NULL) { ! ObjectLocker ol(h_init_lock, THREAD); ! set_init_state(state); ! fence_and_clear_init_lock(); ol.notify_all(CHECK); } else { assert(init_lock() != NULL, "The initialization state should never be set twice"); ! set_init_state(state); } } // The embedded _implementor field can only record one implementor. // When there are more than one implementors, the _implementor field
*** 1035,1069 **** : vmSymbols::java_lang_IllegalAccessException(), external_name()); } } Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) { - return array_klass_impl(this, or_null, n, THREAD); - } - - Klass* InstanceKlass::array_klass_impl(InstanceKlass* this_k, bool or_null, int n, TRAPS) { // Need load-acquire for lock-free read ! if (this_k->array_klasses_acquire() == NULL) { if (or_null) return NULL; ResourceMark rm; JavaThread *jt = (JavaThread *)THREAD; { // Atomic creation of array_klasses MutexLocker mc(Compile_lock, THREAD); // for vtables MutexLocker ma(MultiArray_lock, THREAD); // Check if update has already taken place ! if (this_k->array_klasses() == NULL) { ! Klass* k = ObjArrayKlass::allocate_objArray_klass(this_k->class_loader_data(), 1, this_k, CHECK_NULL); // use 'release' to pair with lock-free load ! this_k->release_set_array_klasses(k); } } } // _this will always be set at this point ! ObjArrayKlass* oak = (ObjArrayKlass*)this_k->array_klasses(); if (or_null) { return oak->array_klass_or_null(n); } return oak->array_klass(n, THREAD); } --- 1032,1062 ---- : vmSymbols::java_lang_IllegalAccessException(), external_name()); } } Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) { // Need load-acquire for lock-free read ! if (array_klasses_acquire() == NULL) { if (or_null) return NULL; ResourceMark rm; JavaThread *jt = (JavaThread *)THREAD; { // Atomic creation of array_klasses MutexLocker mc(Compile_lock, THREAD); // for vtables MutexLocker ma(MultiArray_lock, THREAD); // Check if update has already taken place ! if (array_klasses() == NULL) { ! Klass* k = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), 1, this, CHECK_NULL); // use 'release' to pair with lock-free load ! release_set_array_klasses(k); } } } // _this will always be set at this point ! ObjArrayKlass* oak = (ObjArrayKlass*)array_klasses(); if (or_null) { return oak->array_klass_or_null(n); } return oak->array_klass(n, THREAD); }
*** 1071,1081 **** Klass* InstanceKlass::array_klass_impl(bool or_null, TRAPS) { return array_klass_impl(or_null, 1, THREAD); } void InstanceKlass::call_class_initializer(TRAPS) { ! call_class_initializer_impl(this, THREAD); } static int call_class_initializer_impl_counter = 0; // for debugging Method* InstanceKlass::class_initializer() const { --- 1064,1074 ---- Klass* InstanceKlass::array_klass_impl(bool or_null, TRAPS) { return array_klass_impl(or_null, 1, THREAD); } void InstanceKlass::call_class_initializer(TRAPS) { ! call_class_initializer_impl(THREAD); } static int call_class_initializer_impl_counter = 0; // for debugging Method* InstanceKlass::class_initializer() const {
*** 1085,1110 **** return clinit; } return NULL; } ! void InstanceKlass::call_class_initializer_impl(InstanceKlass* this_k, TRAPS) { if (ReplayCompiles && (ReplaySuppressInitializers == 1 || ! ReplaySuppressInitializers >= 2 && this_k->class_loader() != NULL)) { // Hide the existence of the initializer for the purpose of replaying the compile return; } ! methodHandle h_method(THREAD, this_k->class_initializer()); ! assert(!this_k->is_initialized(), "we cannot initialize twice"); if (log_is_enabled(Info, class, init)) { ResourceMark rm; outputStream* log = Log(class, init)::info_stream(); log->print("%d Initializing ", call_class_initializer_impl_counter++); ! this_k->name()->print_value_on(log); ! log->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", p2i(this_k)); } if (h_method() != NULL) { JavaCallArguments args; // No arguments JavaValue result(T_VOID); JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args) --- 1078,1103 ---- return clinit; } return NULL; } ! void InstanceKlass::call_class_initializer_impl(TRAPS) { if (ReplayCompiles && (ReplaySuppressInitializers == 1 || ! ReplaySuppressInitializers >= 2 && class_loader() != NULL)) { // Hide the existence of the initializer for the purpose of replaying the compile return; } ! methodHandle h_method(THREAD, class_initializer()); ! assert(!is_initialized(), "we cannot initialize twice"); if (log_is_enabled(Info, class, init)) { ResourceMark rm; outputStream* log = Log(class, init)::info_stream(); log->print("%d Initializing ", call_class_initializer_impl_counter++); ! name()->print_value_on(log); ! log->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", p2i(this)); } if (h_method() != NULL) { JavaCallArguments args; // No arguments JavaValue result(T_VOID); JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args)
*** 1251,1267 **** } } void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle mirror, TRAPS) { ! do_local_static_fields_impl(this, f, mirror, CHECK); } ! void InstanceKlass::do_local_static_fields_impl(InstanceKlass* this_k, ! void f(fieldDescriptor* fd, Handle, TRAPS), Handle mirror, TRAPS) { ! for (JavaFieldStream fs(this_k); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { fieldDescriptor& fd = fs.field_descriptor(); f(&fd, mirror, CHECK); } } --- 1244,1260 ---- } } void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle mirror, TRAPS) { ! do_local_static_fields_impl(f, mirror, CHECK); } ! void InstanceKlass::do_local_static_fields_impl(void f(fieldDescriptor* fd, Handle, TRAPS), ! Handle mirror, TRAPS) { ! for (JavaFieldStream fs(this); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { fieldDescriptor& fd = fs.field_descriptor(); f(&fd, mirror, CHECK); } }
*** 1616,1643 **** } return NULL; } /* jni_id_for_impl for jfieldIds only */ ! JNIid* InstanceKlass::jni_id_for_impl(InstanceKlass* this_k, int offset) { MutexLocker ml(JfieldIdCreation_lock); // Retry lookup after we got the lock ! JNIid* probe = this_k->jni_ids() == NULL ? NULL : this_k->jni_ids()->find(offset); if (probe == NULL) { // Slow case, allocate new static field identifier ! probe = new JNIid(this_k, offset, this_k->jni_ids()); ! this_k->set_jni_ids(probe); } return probe; } /* jni_id_for for jfieldIds only */ JNIid* InstanceKlass::jni_id_for(int offset) { JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset); if (probe == NULL) { ! probe = jni_id_for_impl(this, offset); } return probe; } u2 InstanceKlass::enclosing_method_data(int offset) const { --- 1609,1636 ---- } return NULL; } /* jni_id_for_impl for jfieldIds only */ ! JNIid* InstanceKlass::jni_id_for_impl(int offset) { MutexLocker ml(JfieldIdCreation_lock); // Retry lookup after we got the lock ! JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset); if (probe == NULL) { // Slow case, allocate new static field identifier ! probe = new JNIid(this, offset, jni_ids()); ! set_jni_ids(probe); } return probe; } /* jni_id_for for jfieldIds only */ JNIid* InstanceKlass::jni_id_for(int offset) { JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset); if (probe == NULL) { ! probe = jni_id_for_impl(offset); } return probe; } u2 InstanceKlass::enclosing_method_data(int offset) const {
< prev index next >