< 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 >