< prev index next >

src/share/vm/oops/instanceKlass.cpp

Print this page

        

*** 372,382 **** bool InstanceKlass::should_be_initialized() const { return !is_initialized(); } klassItable* InstanceKlass::itable() const { ! return new klassItable(instanceKlassHandle(this)); } void InstanceKlass::eager_initialize(Thread *thread) { if (!EagerInitialization) return; --- 372,382 ---- bool InstanceKlass::should_be_initialized() const { return !is_initialized(); } klassItable* InstanceKlass::itable() const { ! return new klassItable(const_cast<InstanceKlass*>(this)); } void InstanceKlass::eager_initialize(Thread *thread) { if (!EagerInitialization) return;
*** 390,401 **** // abort if the super class should be initialized if (!InstanceKlass::cast(super)->is_initialized()) return; // call body to expose the this pointer ! instanceKlassHandle this_k(thread, this); ! eager_initialize_impl(this_k); } } // JVMTI spec thinks there are signers and protection domain in the // instanceKlass. These accessors pretend these fields are there. --- 390,400 ---- // 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.
*** 430,440 **** 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(instanceKlassHandle this_k) { EXCEPTION_MARK; HandleMark hm(THREAD); Handle init_lock(THREAD, this_k->init_lock()); ObjectLocker ol(init_lock, THREAD, init_lock() != NULL); --- 429,439 ---- 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);
*** 468,490 **** // 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()) { ! instanceKlassHandle this_k(THREAD, this); ! initialize_impl(this_k, 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( ! instanceKlassHandle 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); } --- 467,488 ---- // 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); }
*** 499,526 **** } void InstanceKlass::link_class(TRAPS) { assert(is_loaded(), "must be loaded"); if (!is_linked()) { ! instanceKlassHandle this_k(THREAD, this); ! link_class_impl(this_k, 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()) { ! instanceKlassHandle this_k(THREAD, this); ! link_class_impl(this_k, false, CHECK_false); } return is_linked(); } bool InstanceKlass::link_class_impl( ! instanceKlassHandle 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. // --- 497,522 ---- } 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. //
*** 540,551 **** // 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 ! instanceKlassHandle super(THREAD, this_k->super()); ! if (super.not_null()) { if (super->is_interface()) { // check if super class is an interface ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), --- 536,547 ---- // 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(),
*** 554,572 **** super->external_name() ); return false; } ! link_class_impl(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++) { ! instanceKlassHandle ih(THREAD, interfaces->at(index)); ! link_class_impl(ih, throw_verifyerror, CHECK_false); } // in case the class is linked in the process of linking its superclasses if (this_k->is_linked()) { return true; --- 550,569 ---- 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;
*** 640,650 **** #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; } --- 637,647 ---- #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; }
*** 653,669 **** // Rewrite the byte codes of all of the methods of a class. // The rewriter must be called exactly once. Rewriting must happen after // verification but before the first method of the class is executed. void InstanceKlass::rewrite_class(TRAPS) { assert(is_loaded(), "must be loaded"); ! instanceKlassHandle this_k(THREAD, this); ! if (this_k->is_rewritten()) { ! assert(this_k()->is_shared(), "rewriting an unshared class?"); return; } ! Rewriter::rewrite(this_k, CHECK); ! this_k->set_rewritten(); } // Now relocate and link method entry points after class is rewritten. // This is outside is_rewritten flag. In case of an exception, it can be // executed more than once. --- 650,665 ---- // Rewrite the byte codes of all of the methods of a class. // The rewriter must be called exactly once. Rewriting must happen after // verification but before the first method of the class is executed. void InstanceKlass::rewrite_class(TRAPS) { assert(is_loaded(), "must be loaded"); ! if (is_rewritten()) { ! assert(is_shared(), "rewriting an unshared class?"); return; } ! Rewriter::rewrite(this, CHECK); ! set_rewritten(); } // Now relocate and link method entry points after class is rewritten. // This is outside is_rewritten flag. In case of an exception, it can be // executed more than once.
*** 676,686 **** m->link_method(m, CHECK); } } // Eagerly initialize superinterfaces that declare default methods (concrete instance: any access) ! void InstanceKlass::initialize_super_interfaces(instanceKlassHandle 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); --- 672,682 ---- 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);
*** 696,713 **** ik->initialize(CHECK); } } } ! void InstanceKlass::initialize_impl(instanceKlassHandle 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 --- 692,709 ---- 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
*** 726,748 **** 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); --- 722,744 ---- 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);
*** 784,794 **** 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()); } } --- 780,790 ---- 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()); } }
*** 797,807 **** // 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(), --- 793,803 ---- // 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(),
*** 831,861 **** 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) { ! instanceKlassHandle kh(THREAD, this); ! set_initialization_state_and_notify_impl(kh, state, CHECK); } ! void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle 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(); --- 827,856 ---- 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();
*** 993,1005 **** JvmtiExport::post_array_size_exhausted(); THROW_OOP_0(Universe::out_of_memory_error_array_size()); } int size = objArrayOopDesc::object_size(length); Klass* ak = array_klass(n, CHECK_NULL); - KlassHandle h_ak (THREAD, ak); objArrayOop o = ! (objArrayOop)CollectedHeap::array_allocate(h_ak, size, length, CHECK_NULL); return o; } instanceOop InstanceKlass::register_finalizer(instanceOop i, TRAPS) { if (TraceFinalizerRegistration) { --- 988,999 ---- JvmtiExport::post_array_size_exhausted(); THROW_OOP_0(Universe::out_of_memory_error_array_size()); } int size = objArrayOopDesc::object_size(length); Klass* ak = array_klass(n, CHECK_NULL); objArrayOop o = ! (objArrayOop)CollectedHeap::array_allocate(ak, size, length, CHECK_NULL); return o; } instanceOop InstanceKlass::register_finalizer(instanceOop i, TRAPS) { if (TraceFinalizerRegistration) {
*** 1018,1032 **** instanceOop InstanceKlass::allocate_instance(TRAPS) { bool has_finalizer_flag = has_finalizer(); // Query before possible GC int size = size_helper(); // Query before forming handle. - KlassHandle h_k(THREAD, this); - instanceOop i; ! i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL); if (has_finalizer_flag && !RegisterFinalizersAtInit) { i = register_finalizer(i, CHECK_NULL); } return i; } --- 1012,1024 ---- instanceOop InstanceKlass::allocate_instance(TRAPS) { bool has_finalizer_flag = has_finalizer(); // Query before possible GC int size = size_helper(); // Query before forming handle. instanceOop i; ! i = (instanceOop)CollectedHeap::obj_allocate(this, size, CHECK_NULL); if (has_finalizer_flag && !RegisterFinalizersAtInit) { i = register_finalizer(i, CHECK_NULL); } return i; }
*** 1043,1057 **** : vmSymbols::java_lang_IllegalAccessException(), external_name()); } } Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) { ! instanceKlassHandle this_k(THREAD, this); ! return array_klass_impl(this_k, or_null, n, THREAD); } ! Klass* InstanceKlass::array_klass_impl(instanceKlassHandle 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; --- 1035,1048 ---- : 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;
*** 1080,1105 **** Klass* InstanceKlass::array_klass_impl(bool or_null, TRAPS) { return array_klass_impl(or_null, 1, THREAD); } void InstanceKlass::call_class_initializer(TRAPS) { ! instanceKlassHandle ik (THREAD, this); ! call_class_initializer_impl(ik, THREAD); } static int call_class_initializer_impl_counter = 0; // for debugging ! Method* InstanceKlass::class_initializer() { Method* clinit = find_method( vmSymbols::class_initializer_name(), vmSymbols::void_method_signature()); if (clinit != NULL && clinit->has_valid_initializer_flags()) { return clinit; } return NULL; } ! void InstanceKlass::call_class_initializer_impl(instanceKlassHandle 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; --- 1071,1095 ---- 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 { Method* clinit = find_method( vmSymbols::class_initializer_name(), vmSymbols::void_method_signature()); if (clinit != NULL && clinit->has_valid_initializer_flags()) { 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;
*** 1110,1120 **** 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) --- 1100,1110 ---- 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)
*** 1261,1278 **** } } void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle mirror, TRAPS) { ! instanceKlassHandle h_this(THREAD, this); ! do_local_static_fields_impl(h_this, f, mirror, CHECK); } ! void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle 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); } } --- 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); } }
*** 1627,1643 **** } return NULL; } /* jni_id_for_impl for jfieldIds only */ ! JNIid* InstanceKlass::jni_id_for_impl(instanceKlassHandle 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; } --- 1616,1632 ---- } 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; }
*** 1682,1694 **** // Lookup or create a jmethodID. // This code is called by the VMThread and JavaThreads so the // locking has to be done very carefully to avoid deadlocks // and/or other cache consistency problems. // ! jmethodID InstanceKlass::get_jmethod_id(instanceKlassHandle ik_h, const methodHandle& method_h) { size_t idnum = (size_t)method_h->method_idnum(); ! jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire(); size_t length = 0; jmethodID id = NULL; // We use a double-check locking idiom here because this cache is // performance sensitive. In the normal system, this cache only --- 1671,1683 ---- // Lookup or create a jmethodID. // This code is called by the VMThread and JavaThreads so the // locking has to be done very carefully to avoid deadlocks // and/or other cache consistency problems. // ! jmethodID InstanceKlass::get_jmethod_id(InstanceKlass* ik, const methodHandle& method_h) { size_t idnum = (size_t)method_h->method_idnum(); ! jmethodID* jmeths = ik->methods_jmethod_ids_acquire(); size_t length = 0; jmethodID id = NULL; // We use a double-check locking idiom here because this cache is // performance sensitive. In the normal system, this cache only
*** 1708,1718 **** // cache accesses and freeing of the old cache so a lock is generally // acquired when the RedefineClasses() API has been used. if (jmeths != NULL) { // the cache already exists ! if (!ik_h->idnum_can_increment()) { // the cache can't grow so we can just get the current values get_jmethod_id_length_value(jmeths, idnum, &length, &id); } else { // cache can grow so we have to be more careful if (Threads::number_of_threads() == 0 || --- 1697,1707 ---- // cache accesses and freeing of the old cache so a lock is generally // acquired when the RedefineClasses() API has been used. if (jmeths != NULL) { // the cache already exists ! if (!ik->idnum_can_increment()) { // the cache can't grow so we can just get the current values get_jmethod_id_length_value(jmeths, idnum, &length, &id); } else { // cache can grow so we have to be more careful if (Threads::number_of_threads() == 0 ||
*** 1742,1790 **** // may not allocate new_jmeths or use it if we allocate it jmethodID* new_jmeths = NULL; if (length <= idnum) { // allocate a new cache that might be used ! size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count()); new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1, mtClass); memset(new_jmeths, 0, (size+1)*sizeof(jmethodID)); // cache size is stored in element[0], other elements offset by one new_jmeths[0] = (jmethodID)size; } // allocate a new jmethodID that might be used jmethodID new_id = NULL; if (method_h->is_old() && !method_h->is_obsolete()) { // The method passed in is old (but not obsolete), we need to use the current version ! Method* current_method = ik_h->method_with_idnum((int)idnum); assert(current_method != NULL, "old and but not obsolete, so should exist"); ! new_id = Method::make_jmethod_id(ik_h->class_loader_data(), current_method); } else { // It is the current version of the method or an obsolete method, // use the version passed in ! new_id = Method::make_jmethod_id(ik_h->class_loader_data(), method_h()); } if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { // we're single threaded or at a safepoint - no locking needed ! id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths, &to_dealloc_id, &to_dealloc_jmeths); } else { MutexLocker ml(JmethodIdCreation_lock); ! id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths, &to_dealloc_id, &to_dealloc_jmeths); } // The lock has been dropped so we can free resources. // Free up either the old cache or the new cache if we allocated one. if (to_dealloc_jmeths != NULL) { FreeHeap(to_dealloc_jmeths); } // free up the new ID since it wasn't needed if (to_dealloc_id != NULL) { ! Method::destroy_jmethod_id(ik_h->class_loader_data(), to_dealloc_id); } } return id; } --- 1731,1779 ---- // may not allocate new_jmeths or use it if we allocate it jmethodID* new_jmeths = NULL; if (length <= idnum) { // allocate a new cache that might be used ! size_t size = MAX2(idnum+1, (size_t)ik->idnum_allocated_count()); new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1, mtClass); memset(new_jmeths, 0, (size+1)*sizeof(jmethodID)); // cache size is stored in element[0], other elements offset by one new_jmeths[0] = (jmethodID)size; } // allocate a new jmethodID that might be used jmethodID new_id = NULL; if (method_h->is_old() && !method_h->is_obsolete()) { // The method passed in is old (but not obsolete), we need to use the current version ! Method* current_method = ik->method_with_idnum((int)idnum); assert(current_method != NULL, "old and but not obsolete, so should exist"); ! new_id = Method::make_jmethod_id(ik->class_loader_data(), current_method); } else { // It is the current version of the method or an obsolete method, // use the version passed in ! new_id = Method::make_jmethod_id(ik->class_loader_data(), method_h()); } if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { // we're single threaded or at a safepoint - no locking needed ! id = get_jmethod_id_fetch_or_update(ik, idnum, new_id, new_jmeths, &to_dealloc_id, &to_dealloc_jmeths); } else { MutexLocker ml(JmethodIdCreation_lock); ! id = get_jmethod_id_fetch_or_update(ik, idnum, new_id, new_jmeths, &to_dealloc_id, &to_dealloc_jmeths); } // The lock has been dropped so we can free resources. // Free up either the old cache or the new cache if we allocated one. if (to_dealloc_jmeths != NULL) { FreeHeap(to_dealloc_jmeths); } // free up the new ID since it wasn't needed if (to_dealloc_id != NULL) { ! Method::destroy_jmethod_id(ik->class_loader_data(), to_dealloc_id); } } return id; }
*** 1812,1833 **** // cache with the new jmethodID. This function should never do anything // that causes the caller to go to a safepoint or we can deadlock with // the VMThread or have cache consistency issues. // jmethodID InstanceKlass::get_jmethod_id_fetch_or_update( ! instanceKlassHandle ik_h, size_t idnum, jmethodID new_id, jmethodID* new_jmeths, jmethodID* to_dealloc_id_p, jmethodID** to_dealloc_jmeths_p) { assert(new_id != NULL, "sanity check"); assert(to_dealloc_id_p != NULL, "sanity check"); assert(to_dealloc_jmeths_p != NULL, "sanity check"); assert(Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint() || JmethodIdCreation_lock->owned_by_self(), "sanity check"); // reacquire the cache - we are locked, single threaded or at a safepoint ! jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire(); jmethodID id = NULL; size_t length = 0; if (jmeths == NULL || // no cache yet (length = (size_t)jmeths[0]) <= idnum) { // cache is too short --- 1801,1822 ---- // cache with the new jmethodID. This function should never do anything // that causes the caller to go to a safepoint or we can deadlock with // the VMThread or have cache consistency issues. // jmethodID InstanceKlass::get_jmethod_id_fetch_or_update( ! InstanceKlass* ik, size_t idnum, jmethodID new_id, jmethodID* new_jmeths, jmethodID* to_dealloc_id_p, jmethodID** to_dealloc_jmeths_p) { assert(new_id != NULL, "sanity check"); assert(to_dealloc_id_p != NULL, "sanity check"); assert(to_dealloc_jmeths_p != NULL, "sanity check"); assert(Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint() || JmethodIdCreation_lock->owned_by_self(), "sanity check"); // reacquire the cache - we are locked, single threaded or at a safepoint ! jmethodID* jmeths = ik->methods_jmethod_ids_acquire(); jmethodID id = NULL; size_t length = 0; if (jmeths == NULL || // no cache yet (length = (size_t)jmeths[0]) <= idnum) { // cache is too short
*** 1836,1846 **** for (size_t index = 0; index < length; index++) { new_jmeths[index+1] = jmeths[index+1]; } *to_dealloc_jmeths_p = jmeths; // save old cache for later delete } ! ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths); } else { // fetch jmethodID (if any) from the existing cache id = jmeths[idnum+1]; *to_dealloc_jmeths_p = new_jmeths; // save new cache for later delete } --- 1825,1835 ---- for (size_t index = 0; index < length; index++) { new_jmeths[index+1] = jmeths[index+1]; } *to_dealloc_jmeths_p = jmeths; // save old cache for later delete } ! ik->release_set_methods_jmethod_ids(jmeths = new_jmeths); } else { // fetch jmethodID (if any) from the existing cache id = jmeths[idnum+1]; *to_dealloc_jmeths_p = new_jmeths; // save new cache for later delete }
*** 2056,2070 **** // --> see ArrayKlass::complete_create_array_klass() k->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK); } void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { ! instanceKlassHandle ik(THREAD, this); ! ik->set_package(loader_data, CHECK); Klass::restore_unshareable_info(loader_data, protection_domain, CHECK); ! Array<Method*>* methods = ik->methods(); int num_methods = methods->length(); for (int index2 = 0; index2 < num_methods; ++index2) { methodHandle m(THREAD, methods->at(index2)); m->restore_unshareable_info(CHECK); } --- 2045,2058 ---- // --> see ArrayKlass::complete_create_array_klass() k->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK); } void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { ! set_package(loader_data, CHECK); Klass::restore_unshareable_info(loader_data, protection_domain, CHECK); ! Array<Method*>* methods = this->methods(); int num_methods = methods->length(); for (int index2 = 0; index2 < num_methods; ++index2) { methodHandle m(THREAD, methods->at(index2)); m->restore_unshareable_info(CHECK); }
*** 2073,2090 **** // entries in this vtable for super classes so the CDS vtable might // point to old or obsolete entries. RedefineClasses doesn't fix up // vtables in the shared system dictionary, only the main one. // It also redefines the itable too so fix that too. ResourceMark rm(THREAD); ! ik->vtable()->initialize_vtable(false, CHECK); ! ik->itable()->initialize_itable(false, CHECK); } // restore constant pool resolved references ! ik->constants()->restore_unshareable_info(CHECK); ! ik->array_klasses_do(restore_unshareable_in_class, CHECK); } // returns true IFF is_in_error_state() has been changed as a result of this call. bool InstanceKlass::check_sharing_error_state() { assert(DumpSharedSpaces, "should only be called during dumping"); --- 2061,2078 ---- // entries in this vtable for super classes so the CDS vtable might // point to old or obsolete entries. RedefineClasses doesn't fix up // vtables in the shared system dictionary, only the main one. // It also redefines the itable too so fix that too. ResourceMark rm(THREAD); ! vtable()->initialize_vtable(false, CHECK); ! itable()->initialize_itable(false, CHECK); } // restore constant pool resolved references ! constants()->restore_unshareable_info(CHECK); ! array_klasses_do(restore_unshareable_in_class, CHECK); } // returns true IFF is_in_error_state() has been changed as a result of this call. bool InstanceKlass::check_sharing_error_state() { assert(DumpSharedSpaces, "should only be called during dumping");
*** 2446,2456 **** assert(super_method->is_package_private(), "must be package private"); return(is_same_class_package(targetclassloader(), targetclassname)); } /* defined for now in jvm.cpp, for historical reasons *-- ! Klass* InstanceKlass::compute_enclosing_class_impl(instanceKlassHandle self, Symbol*& simple_name_result, TRAPS) { ... } */ --- 2434,2444 ---- assert(super_method->is_package_private(), "must be package private"); return(is_same_class_package(targetclassloader(), targetclassname)); } /* defined for now in jvm.cpp, for historical reasons *-- ! Klass* InstanceKlass::compute_enclosing_class_impl(InstanceKlass* self, Symbol*& simple_name_result, TRAPS) { ... } */
*** 2520,2539 **** // If by this point we have not found an equality between the // two classes, we know they are in separate package members. return false; } ! bool InstanceKlass::find_inner_classes_attr(instanceKlassHandle k, int* ooff, int* noff, TRAPS) { constantPoolHandle i_cp(THREAD, k->constants()); for (InnerClassesIterator iter(k); !iter.done(); iter.next()) { int ioff = iter.inner_class_info_index(); if (ioff != 0) { // Check to see if the name matches the class we're looking for // before attempting to find the class. if (i_cp->klass_name_at_matches(k, ioff)) { Klass* inner_klass = i_cp->klass_at(ioff, CHECK_false); ! if (k() == inner_klass) { *ooff = iter.outer_class_info_index(); *noff = iter.inner_name_index(); return true; } } --- 2508,2527 ---- // If by this point we have not found an equality between the // two classes, we know they are in separate package members. return false; } ! bool InstanceKlass::find_inner_classes_attr(const InstanceKlass* k, int* ooff, int* noff, TRAPS) { constantPoolHandle i_cp(THREAD, k->constants()); for (InnerClassesIterator iter(k); !iter.done(); iter.next()) { int ioff = iter.inner_class_info_index(); if (ioff != 0) { // Check to see if the name matches the class we're looking for // before attempting to find the class. if (i_cp->klass_name_at_matches(k, ioff)) { Klass* inner_klass = i_cp->klass_at(ioff, CHECK_false); ! if (k == inner_klass) { *ooff = iter.outer_class_info_index(); *noff = iter.inner_name_index(); return true; } }
*** 2578,2599 **** jint InstanceKlass::compute_modifier_flags(TRAPS) const { jint access = access_flags().as_int(); // But check if it happens to be member class. ! instanceKlassHandle ik(THREAD, this); ! InnerClassesIterator iter(ik); for (; !iter.done(); iter.next()) { int ioff = iter.inner_class_info_index(); // Inner class attribute can be zero, skip it. // Strange but true: JVM spec. allows null inner class refs. if (ioff == 0) continue; // only look at classes that are already loaded // since we are looking for the flags for our self. ! Symbol* inner_name = ik->constants()->klass_name_at(ioff); ! if ((ik->name() == inner_name)) { // This is really a member class. access = iter.inner_access_flags(); break; } } --- 2566,2586 ---- jint InstanceKlass::compute_modifier_flags(TRAPS) const { jint access = access_flags().as_int(); // But check if it happens to be member class. ! InnerClassesIterator iter(this); for (; !iter.done(); iter.next()) { int ioff = iter.inner_class_info_index(); // Inner class attribute can be zero, skip it. // Strange but true: JVM spec. allows null inner class refs. if (ioff == 0) continue; // only look at classes that are already loaded // since we are looking for the flags for our self. ! Symbol* inner_name = constants()->klass_name_at(ioff); ! if ((name() == inner_name)) { // This is really a member class. access = iter.inner_access_flags(); break; } }
*** 3607,3617 **** } // Save the scratch_class as the previous version if any of the methods are running. // The previous_versions are used to set breakpoints in EMCP methods and they are // also used to clean MethodData links to redefined methods that are no longer running. ! void InstanceKlass::add_previous_version(instanceKlassHandle scratch_class, int emcp_method_count) { assert(Thread::current()->is_VM_thread(), "only VMThread can add previous versions"); ResourceMark rm; --- 3594,3604 ---- } // Save the scratch_class as the previous version if any of the methods are running. // The previous_versions are used to set breakpoints in EMCP methods and they are // also used to clean MethodData links to redefined methods that are no longer running. ! void InstanceKlass::add_previous_version(InstanceKlass* scratch_class, int emcp_method_count) { assert(Thread::current()->is_VM_thread(), "only VMThread can add previous versions"); ResourceMark rm;
*** 3633,3643 **** ConstantPool* cp_ref = scratch_class->constants(); if (!cp_ref->on_stack()) { log_trace(redefine, class, iklass, add)("scratch class not added; no methods are running"); // For debugging purposes. scratch_class->set_is_scratch_class(); ! scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class()); return; } if (emcp_method_count != 0) { // At least one method is still running, check for EMCP methods --- 3620,3630 ---- ConstantPool* cp_ref = scratch_class->constants(); if (!cp_ref->on_stack()) { log_trace(redefine, class, iklass, add)("scratch class not added; no methods are running"); // For debugging purposes. scratch_class->set_is_scratch_class(); ! scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class); return; } if (emcp_method_count != 0) { // At least one method is still running, check for EMCP methods
*** 3666,3676 **** // Set has_previous_version flag for processing during class unloading. _has_previous_versions = true; log_trace(redefine, class, iklass, add) ("scratch class added; one of its methods is on_stack."); assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version"); scratch_class->link_previous_versions(previous_versions()); ! link_previous_versions(scratch_class()); } // end add_previous_version() #endif // INCLUDE_JVMTI Method* InstanceKlass::method_with_idnum(int idnum) { --- 3653,3663 ---- // Set has_previous_version flag for processing during class unloading. _has_previous_versions = true; log_trace(redefine, class, iklass, add) ("scratch class added; one of its methods is on_stack."); assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version"); scratch_class->link_previous_versions(previous_versions()); ! link_previous_versions(scratch_class); } // end add_previous_version() #endif // INCLUDE_JVMTI Method* InstanceKlass::method_with_idnum(int idnum) {
< prev index next >