< prev index next >

src/share/vm/oops/instanceKlass.cpp

Print this page
rev 9040 : 8225141: Better handling of classes in error state in fast class initialization checks
Reviewed-by: dlong, dholmes


 277   set_methods(NULL);
 278   set_method_ordering(NULL);
 279   set_default_methods(NULL);
 280   set_default_vtable_indices(NULL);
 281   set_local_interfaces(NULL);
 282   set_transitive_interfaces(NULL);
 283   init_implementor();
 284   set_fields(NULL, 0);
 285   set_constants(NULL);
 286   set_class_loader_data(NULL);
 287   set_source_file_name_index(0);
 288   set_source_debug_extension(NULL, 0);
 289   set_array_name(NULL);
 290   set_inner_classes(NULL);
 291   set_static_oop_field_count(0);
 292   set_nonstatic_field_size(0);
 293   set_is_marked_dependent(false);
 294   set_has_unloaded_dependent(false);
 295   set_init_state(InstanceKlass::allocated);
 296   set_init_thread(NULL);

 297   set_reference_type(rt);
 298   set_oop_map_cache(NULL);
 299   set_jni_ids(NULL);
 300   set_osr_nmethods_head(NULL);
 301   set_breakpoints(NULL);
 302   init_previous_versions();
 303   set_generic_signature_index(0);
 304   release_set_methods_jmethod_ids(NULL);
 305   set_annotations(NULL);
 306   set_jvmti_cached_class_field_map(NULL);
 307   set_initial_method_idnum(0);
 308   _dependencies = NULL;
 309   set_jvmti_cached_class_field_map(NULL);
 310   set_cached_class_file(NULL);
 311   set_initial_method_idnum(0);
 312   set_minor_version(0);
 313   set_major_version(0);
 314   NOT_PRODUCT(_verify_count = 0;)
 315 
 316   // initialize the non-header words to zero


 961       JavaCallArguments args(e);
 962       THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(),
 963                 vmSymbols::throwable_void_signature(),
 964                 &args);
 965     }
 966   }
 967   DTRACE_CLASSINIT_PROBE_WAIT(end, InstanceKlass::cast(this_oop()), -1,wait);
 968 }
 969 
 970 
 971 // Note: implementation moved to static method to expose the this pointer.
 972 void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) {
 973   instanceKlassHandle kh(THREAD, this);
 974   set_initialization_state_and_notify_impl(kh, state, CHECK);
 975 }
 976 
 977 void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) {
 978   oop init_lock = this_oop->init_lock();
 979   if (init_lock != NULL) {
 980     ObjectLocker ol(init_lock, THREAD);

 981     this_oop->set_init_state(state);
 982     this_oop->fence_and_clear_init_lock();
 983     ol.notify_all(CHECK);
 984   } else {
 985     assert(init_lock != NULL, "The initialization state should never be set twice");

 986     this_oop->set_init_state(state);
 987   }
 988 }
 989 
 990 // The embedded _implementor field can only record one implementor.
 991 // When there are more than one implementors, the _implementor field
 992 // is set to the interface Klass* itself. Following are the possible
 993 // values for the _implementor field:
 994 //   NULL                  - no implementor
 995 //   implementor Klass*    - one implementor
 996 //   self                  - more than one implementor
 997 //
 998 // The _implementor field only exists for interfaces.
 999 void InstanceKlass::add_implementor(Klass* k) {
1000   assert(Compile_lock->owned_by_self(), "");
1001   assert(is_interface(), "not interface");
1002   // Filter out my subinterfaces.
1003   // (Note: Interfaces are never on the subklass list.)
1004   if (InstanceKlass::cast(k)->is_interface()) return;
1005 


3585 
3586   JNIid* current = this;
3587   while (current != NULL) {
3588     guarantee(current->holder() == holder, "Invalid klass in JNIid");
3589 #ifdef ASSERT
3590     int o = current->offset();
3591     if (current->is_static_field_id()) {
3592       guarantee(o >= first_field_offset  && o < end_field_offset,  "Invalid static field offset in JNIid");
3593     }
3594 #endif
3595     current = current->next();
3596   }
3597 }
3598 
3599 
3600 #ifdef ASSERT
3601 void InstanceKlass::set_init_state(ClassState state) {
3602   bool good_state = is_shared() ? (_init_state <= state)
3603                                                : (_init_state < state);
3604   assert(good_state || state == allocated, "illegal state transition");

3605   _init_state = (u1)state;
3606 }
3607 #endif
3608 
3609 
3610 // RedefineClasses() support for previous versions:
3611 
3612 // Purge previous versions
3613 void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
3614   if (ik->previous_versions() != NULL) {
3615     // This klass has previous versions so see what we can cleanup
3616     // while it is safe to do so.
3617 
3618     int deleted_count = 0;    // leave debugging breadcrumbs
3619     int live_count = 0;
3620     ClassLoaderData* loader_data = ik->class_loader_data();
3621     assert(loader_data != NULL, "should never be null");
3622 
3623     // RC_TRACE macro has an embedded ResourceMark
3624     RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name()));




 277   set_methods(NULL);
 278   set_method_ordering(NULL);
 279   set_default_methods(NULL);
 280   set_default_vtable_indices(NULL);
 281   set_local_interfaces(NULL);
 282   set_transitive_interfaces(NULL);
 283   init_implementor();
 284   set_fields(NULL, 0);
 285   set_constants(NULL);
 286   set_class_loader_data(NULL);
 287   set_source_file_name_index(0);
 288   set_source_debug_extension(NULL, 0);
 289   set_array_name(NULL);
 290   set_inner_classes(NULL);
 291   set_static_oop_field_count(0);
 292   set_nonstatic_field_size(0);
 293   set_is_marked_dependent(false);
 294   set_has_unloaded_dependent(false);
 295   set_init_state(InstanceKlass::allocated);
 296   set_init_thread(NULL);
 297   set_init_state(allocated);
 298   set_reference_type(rt);
 299   set_oop_map_cache(NULL);
 300   set_jni_ids(NULL);
 301   set_osr_nmethods_head(NULL);
 302   set_breakpoints(NULL);
 303   init_previous_versions();
 304   set_generic_signature_index(0);
 305   release_set_methods_jmethod_ids(NULL);
 306   set_annotations(NULL);
 307   set_jvmti_cached_class_field_map(NULL);
 308   set_initial_method_idnum(0);
 309   _dependencies = NULL;
 310   set_jvmti_cached_class_field_map(NULL);
 311   set_cached_class_file(NULL);
 312   set_initial_method_idnum(0);
 313   set_minor_version(0);
 314   set_major_version(0);
 315   NOT_PRODUCT(_verify_count = 0;)
 316 
 317   // initialize the non-header words to zero


 962       JavaCallArguments args(e);
 963       THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(),
 964                 vmSymbols::throwable_void_signature(),
 965                 &args);
 966     }
 967   }
 968   DTRACE_CLASSINIT_PROBE_WAIT(end, InstanceKlass::cast(this_oop()), -1,wait);
 969 }
 970 
 971 
 972 // Note: implementation moved to static method to expose the this pointer.
 973 void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) {
 974   instanceKlassHandle kh(THREAD, this);
 975   set_initialization_state_and_notify_impl(kh, state, CHECK);
 976 }
 977 
 978 void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) {
 979   oop init_lock = this_oop->init_lock();
 980   if (init_lock != NULL) {
 981     ObjectLocker ol(init_lock, THREAD);
 982     this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
 983     this_oop->set_init_state(state);
 984     this_oop->fence_and_clear_init_lock();
 985     ol.notify_all(CHECK);
 986   } else {
 987     assert(init_lock != NULL, "The initialization state should never be set twice");
 988     this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
 989     this_oop->set_init_state(state);
 990   }
 991 }
 992 
 993 // The embedded _implementor field can only record one implementor.
 994 // When there are more than one implementors, the _implementor field
 995 // is set to the interface Klass* itself. Following are the possible
 996 // values for the _implementor field:
 997 //   NULL                  - no implementor
 998 //   implementor Klass*    - one implementor
 999 //   self                  - more than one implementor
1000 //
1001 // The _implementor field only exists for interfaces.
1002 void InstanceKlass::add_implementor(Klass* k) {
1003   assert(Compile_lock->owned_by_self(), "");
1004   assert(is_interface(), "not interface");
1005   // Filter out my subinterfaces.
1006   // (Note: Interfaces are never on the subklass list.)
1007   if (InstanceKlass::cast(k)->is_interface()) return;
1008 


3588 
3589   JNIid* current = this;
3590   while (current != NULL) {
3591     guarantee(current->holder() == holder, "Invalid klass in JNIid");
3592 #ifdef ASSERT
3593     int o = current->offset();
3594     if (current->is_static_field_id()) {
3595       guarantee(o >= first_field_offset  && o < end_field_offset,  "Invalid static field offset in JNIid");
3596     }
3597 #endif
3598     current = current->next();
3599   }
3600 }
3601 
3602 
3603 #ifdef ASSERT
3604 void InstanceKlass::set_init_state(ClassState state) {
3605   bool good_state = is_shared() ? (_init_state <= state)
3606                                                : (_init_state < state);
3607   assert(good_state || state == allocated, "illegal state transition");
3608   set_initialization_state_and_notify_implassert(_init_thread == NULL, "should be cleared before state change");
3609   _init_state = (u1)state;
3610 }
3611 #endif
3612 
3613 
3614 // RedefineClasses() support for previous versions:
3615 
3616 // Purge previous versions
3617 void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
3618   if (ik->previous_versions() != NULL) {
3619     // This klass has previous versions so see what we can cleanup
3620     // while it is safe to do so.
3621 
3622     int deleted_count = 0;    // leave debugging breadcrumbs
3623     int live_count = 0;
3624     ClassLoaderData* loader_data = ik->class_loader_data();
3625     assert(loader_data != NULL, "should never be null");
3626 
3627     // RC_TRACE macro has an embedded ResourceMark
3628     RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name()));


< prev index next >