Mercurial > hg > truffle
diff src/share/vm/oops/instanceKlass.cpp @ 8883:b9a918201d47
Merge with hsx25
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Sat, 06 Apr 2013 20:04:06 +0200 |
parents | 5fc51c1ecdeb 46f6f063b272 |
children | 89e4d67fdd2a |
line wrap: on
line diff
--- a/src/share/vm/oops/instanceKlass.cpp Fri Apr 05 18:53:57 2013 +0200 +++ b/src/share/vm/oops/instanceKlass.cpp Sat Apr 06 20:04:06 2013 +0200 @@ -165,7 +165,8 @@ volatile int InstanceKlass::_total_instanceKlass_count = 0; -Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data, +InstanceKlass* InstanceKlass::allocate_instance_klass( + ClassLoaderData* loader_data, int vtable_len, int itable_len, int static_field_size, @@ -207,10 +208,35 @@ access_flags, is_anonymous); } + // Check for pending exception before adding to the loader data and incrementing + // class count. Can get OOM here. + if (HAS_PENDING_EXCEPTION) { + return NULL; + } + + // Add all classes to our internal class loader list here, + // including classes in the bootstrap (NULL) class loader. + loader_data->add_class(ik); + Atomic::inc(&_total_instanceKlass_count); return ik; } + +// copy method ordering from resource area to Metaspace +void InstanceKlass::copy_method_ordering(intArray* m, TRAPS) { + if (m != NULL) { + // allocate a new array and copy contents (memcpy?) + _method_ordering = MetadataFactory::new_array<int>(class_loader_data(), m->length(), CHECK); + for (int i = 0; i < m->length(); i++) { + _method_ordering->at_put(i, m->at(i)); + } + } else { + _method_ordering = Universe::the_empty_int_array(); + } +} + + InstanceKlass::InstanceKlass(int vtable_len, int itable_len, int static_field_size, @@ -220,72 +246,116 @@ bool is_anonymous) { No_Safepoint_Verifier no_safepoint; // until k becomes parsable - int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, - access_flags.is_interface(), is_anonymous); - - // The sizes of these these three variables are used for determining the - // size of the instanceKlassOop. It is critical that these are set to the right - // sizes before the first GC, i.e., when we allocate the mirror. - this->set_vtable_length(vtable_len); - this->set_itable_length(itable_len); - this->set_static_field_size(static_field_size); - this->set_nonstatic_oop_map_size(nonstatic_oop_map_size); - this->set_access_flags(access_flags); - this->set_is_anonymous(is_anonymous); - assert(this->size() == size, "wrong size for object"); - - this->set_array_klasses(NULL); - this->set_methods(NULL); - this->set_method_ordering(NULL); - this->set_local_interfaces(NULL); - this->set_transitive_interfaces(NULL); - this->init_implementor(); - this->set_fields(NULL, 0); - this->set_constants(NULL); - this->set_class_loader_data(NULL); - this->set_protection_domain(NULL); - this->set_signers(NULL); - this->set_source_file_name(NULL); - this->set_source_debug_extension(NULL, 0); - this->set_array_name(NULL); - this->set_inner_classes(NULL); - this->set_static_oop_field_count(0); - this->set_nonstatic_field_size(0); - this->set_is_marked_dependent(false); - this->set_init_state(InstanceKlass::allocated); - this->set_init_thread(NULL); - this->set_init_lock(NULL); - this->set_reference_type(rt); - this->set_oop_map_cache(NULL); - this->set_jni_ids(NULL); - this->set_osr_nmethods_head(NULL); - this->set_breakpoints(NULL); - this->init_previous_versions(); - this->set_generic_signature(NULL); - this->release_set_methods_jmethod_ids(NULL); - this->release_set_methods_cached_itable_indices(NULL); - this->set_annotations(NULL); - this->set_jvmti_cached_class_field_map(NULL); - this->set_initial_method_idnum(0); + int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, + access_flags.is_interface(), is_anonymous); + + set_vtable_length(vtable_len); + set_itable_length(itable_len); + set_static_field_size(static_field_size); + set_nonstatic_oop_map_size(nonstatic_oop_map_size); + set_access_flags(access_flags); + _misc_flags = 0; // initialize to zero + set_is_anonymous(is_anonymous); + assert(size() == iksize, "wrong size for object"); + + set_array_klasses(NULL); + set_methods(NULL); + set_method_ordering(NULL); + set_local_interfaces(NULL); + set_transitive_interfaces(NULL); + init_implementor(); + set_fields(NULL, 0); + set_constants(NULL); + set_class_loader_data(NULL); + set_protection_domain(NULL); + set_signers(NULL); + set_source_file_name(NULL); + set_source_debug_extension(NULL, 0); + set_array_name(NULL); + set_inner_classes(NULL); + set_static_oop_field_count(0); + set_nonstatic_field_size(0); + set_is_marked_dependent(false); + set_init_state(InstanceKlass::allocated); + set_init_thread(NULL); + set_init_lock(NULL); + set_reference_type(rt); + set_oop_map_cache(NULL); + set_jni_ids(NULL); + set_osr_nmethods_head(NULL); + set_breakpoints(NULL); + init_previous_versions(); + set_generic_signature(NULL); + release_set_methods_jmethod_ids(NULL); + release_set_methods_cached_itable_indices(NULL); + set_annotations(NULL); + set_jvmti_cached_class_field_map(NULL); + set_initial_method_idnum(0); + _dependencies = NULL; + set_jvmti_cached_class_field_map(NULL); + set_cached_class_file(NULL, 0); + set_initial_method_idnum(0); + set_minor_version(0); + set_major_version(0); + NOT_PRODUCT(_verify_count = 0;) // initialize the non-header words to zero intptr_t* p = (intptr_t*)this; - for (int index = InstanceKlass::header_size(); index < size; index++) { + for (int index = InstanceKlass::header_size(); index < iksize; index++) { p[index] = NULL_WORD; } // Set temporary value until parseClassFile updates it with the real instance // size. - this->set_layout_helper(Klass::instance_layout_helper(0, true)); + set_layout_helper(Klass::instance_layout_helper(0, true)); +} + + +void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, + Array<Method*>* methods) { + if (methods != NULL && methods != Universe::the_empty_method_array()) { + for (int i = 0; i < methods->length(); i++) { + Method* method = methods->at(i); + if (method == NULL) continue; // maybe null if error processing + // Only want to delete methods that are not executing for RedefineClasses. + // The previous version will point to them so they're not totally dangling + assert (!method->on_stack(), "shouldn't be called with methods on stack"); + MetadataFactory::free_metadata(loader_data, method); + } + MetadataFactory::free_array<Method*>(loader_data, methods); + } } +void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data, + Klass* super_klass, + Array<Klass*>* local_interfaces, + Array<Klass*>* transitive_interfaces) { + // Only deallocate transitive interfaces if not empty, same as super class + // or same as local interfaces. See code in parseClassFile. + Array<Klass*>* ti = transitive_interfaces; + if (ti != Universe::the_empty_klass_array() && ti != local_interfaces) { + // check that the interfaces don't come from super class + Array<Klass*>* sti = (super_klass == NULL) ? NULL : + InstanceKlass::cast(super_klass)->transitive_interfaces(); + if (ti != sti) { + MetadataFactory::free_array<Klass*>(loader_data, ti); + } + } + + // local interfaces can be empty + if (local_interfaces != Universe::the_empty_klass_array()) { + MetadataFactory::free_array<Klass*>(loader_data, local_interfaces); + } +} // This function deallocates the metadata and C heap pointers that the // InstanceKlass points to. void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { // Orphan the mirror first, CMS thinks it's still live. - java_lang_Class::set_klass(java_mirror(), NULL); + if (java_mirror() != NULL) { + java_lang_Class::set_klass(java_mirror(), NULL); + } // Need to take this class off the class loader data list. loader_data->remove_class(this); @@ -300,17 +370,7 @@ // reference counting symbol names. release_C_heap_structures(); - Array<Method*>* ms = methods(); - if (ms != Universe::the_empty_method_array()) { - for (int i = 0; i <= methods()->length() -1 ; i++) { - Method* method = methods()->at(i); - // Only want to delete methods that are not executing for RedefineClasses. - // The previous version will point to them so they're not totally dangling - assert (!method->on_stack(), "shouldn't be called with methods on stack"); - MetadataFactory::free_metadata(loader_data, method); - } - MetadataFactory::free_array<Method*>(loader_data, methods()); - } + deallocate_methods(loader_data, methods()); set_methods(NULL); if (method_ordering() != Universe::the_empty_int_array()) { @@ -327,24 +387,8 @@ } set_secondary_supers(NULL); - // Only deallocate transitive interfaces if not empty, same as super class - // or same as local interfaces. See code in parseClassFile. - Array<Klass*>* ti = transitive_interfaces(); - if (ti != Universe::the_empty_klass_array() && ti != local_interfaces()) { - // check that the interfaces don't come from super class - Array<Klass*>* sti = (super() == NULL) ? NULL : - InstanceKlass::cast(super())->transitive_interfaces(); - if (ti != sti) { - MetadataFactory::free_array<Klass*>(loader_data, ti); - } - } + deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces()); set_transitive_interfaces(NULL); - - // local interfaces can be empty - Array<Klass*>* li = local_interfaces(); - if (li != Universe::the_empty_klass_array()) { - MetadataFactory::free_array<Klass*>(loader_data, li); - } set_local_interfaces(NULL); MetadataFactory::free_array<jushort>(loader_data, fields()); @@ -352,9 +396,11 @@ // If a method from a redefined class is using this constant pool, don't // delete it, yet. The new class's previous version will point to this. - assert (!constants()->on_stack(), "shouldn't be called if anything is onstack"); - MetadataFactory::free_metadata(loader_data, constants()); - set_constants(NULL); + if (constants() != NULL) { + assert (!constants()->on_stack(), "shouldn't be called if anything is onstack"); + MetadataFactory::free_metadata(loader_data, constants()); + set_constants(NULL); + } if (inner_classes() != Universe::the_empty_short_array()) { MetadataFactory::free_array<jushort>(loader_data, inner_classes()); @@ -2170,7 +2216,11 @@ if (impl != NULL) { if (!impl->is_loader_alive(is_alive)) { // remove this guy - *adr_implementor() = NULL; + Klass** klass = adr_implementor(); + assert(klass != NULL, "null klass"); + if (klass != NULL) { + *klass = NULL; + } } } } @@ -2178,8 +2228,6 @@ } void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) { -#if defined(COMPILER2) || defined(GRAAL) - // Currently only used by C2 and Graal for (int m = 0; m < methods()->length(); m++) { MethodData* mdo = methods()->at(m)->method_data(); if (mdo != NULL) { @@ -2190,15 +2238,6 @@ } } } -#else -#ifdef ASSERT - // Verify that we haven't started to use MDOs for C1. - for (int m = 0; m < methods()->length(); m++) { - MethodData* mdo = methods()->at(m)->method_data(); - assert(mdo == NULL, "Didn't expect C1 to use MDOs"); - } -#endif // ASSERT -#endif // !COMPILER2 } @@ -2781,7 +2820,7 @@ st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr(); st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr(); st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr(); - st->print(BULLET"init_lock: "); ((oop)init_lock())->print_value_on(st); st->cr(); + st->print(BULLET"init_lock: "); ((oop)_init_lock)->print_value_on(st); st->cr(); if (source_file_name() != NULL) { st->print(BULLET"source file: "); source_file_name()->print_value_on(st); @@ -2911,7 +2950,7 @@ } } -#endif +#endif //PRODUCT void InstanceKlass::oop_print_value_on(oop obj, outputStream* st) { st->print("a ");