diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp index 385899a552e38111d153df241a72f1d566ada458..59db6c3301acba074d476a4e8d2323c9d32e2e49 100644 --- a/src/share/vm/classfile/javaClasses.cpp +++ b/src/share/vm/classfile/javaClasses.cpp @@ -503,12 +503,8 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) { // Allocate mirror (java.lang.Class instance) Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); - // Setup indirections - mirror->obj_field_put(_klass_offset, k()); - k->set_java_mirror(mirror()); instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass()); - java_lang_Class::set_oop_size(mirror(), mk->instance_size(k)); java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); // It might also have a component mirror. This mirror must already exist. @@ -571,9 +567,10 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic assert(aklass != NULL, "correct bootstrap"); set_array_klass(java_class, aklass); } +#ifdef ASSERT instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass()); - java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL))); - java_lang_Class::set_static_oop_field_count(java_class, 0); + assert(java_lang_Class::static_oop_field_count(java_class) == 0, "should have been zeroed by allocation"); +#endif return java_class; } @@ -587,6 +584,12 @@ klassOop java_lang_Class::as_klassOop(oop java_class) { } +void java_lang_Class::set_klass(oop java_class, klassOop klass) { + assert(java_lang_Class::is_instance(java_class), "must be a Class object"); + java_class->obj_field_put(_klass_offset, klass); +} + + void java_lang_Class::print_signature(oop java_class, outputStream* st) { assert(java_lang_Class::is_instance(java_class), "must be a Class object"); Symbol* name = NULL; diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp index fca98970de0e08c98f4b60828af0453880239941..2a32801fc73c4d1f65ce750c2d9d659f83061076 100644 --- a/src/share/vm/classfile/javaClasses.hpp +++ b/src/share/vm/classfile/javaClasses.hpp @@ -188,6 +188,7 @@ class java_lang_Class : AllStatic { static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS); // Conversion static klassOop as_klassOop(oop java_class); + static void set_klass(oop java_class, klassOop klass); static BasicType as_BasicType(oop java_class, klassOop* reference_klass = NULL); static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) { klassOop refk_oop = NULL; diff --git a/src/share/vm/gc_interface/collectedHeap.cpp b/src/share/vm/gc_interface/collectedHeap.cpp index 0a4b42c420dfa967f2f24e3669d03176432f559f..3623e9b52e3448b37b2a1bff88edabc5d1cc65b6 100644 --- a/src/share/vm/gc_interface/collectedHeap.cpp +++ b/src/share/vm/gc_interface/collectedHeap.cpp @@ -28,6 +28,7 @@ #include "gc_interface/collectedHeap.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "oops/oop.inline.hpp" +#include "oops/instanceMirrorKlass.hpp" #include "runtime/init.hpp" #include "services/heapDumper.hpp" #ifdef TARGET_OS_FAMILY_linux @@ -436,3 +437,37 @@ void CollectedHeap::post_full_gc_dump() { inspector.doit(); } } + +oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS) { + debug_only(check_for_valid_allocation_state()); + assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed"); + assert(size >= 0, "int won't convert to size_t"); + HeapWord* obj; + if (JavaObjectsInPerm) { + obj = common_permanent_mem_allocate_init(size, CHECK_NULL); + } else { + assert(ScavengeRootsInCode > 0, "must be"); + obj = common_mem_allocate_init(size, CHECK_NULL); + } + post_allocation_setup_common(klass, obj, size); + assert(Universe::is_bootstrapping() || + !((oop)obj)->blueprint()->oop_is_array(), "must not be an array"); + NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size)); + oop mirror = (oop)obj; + + java_lang_Class::set_oop_size(mirror, size); + + // Setup indirections + if (!real_klass.is_null()) { + java_lang_Class::set_klass(mirror, real_klass()); + real_klass->set_java_mirror(mirror); + } + + instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass()); + assert(size == mk->instance_size(real_klass), "should have been set"); + + // notify jvmti and dtrace + post_allocation_notify(klass, (oop)obj); + + return mirror; +} diff --git a/src/share/vm/gc_interface/collectedHeap.hpp b/src/share/vm/gc_interface/collectedHeap.hpp index 5761ea554acc7ad71f2f6fff5c0c1e0ba5ffb93d..ff7a112b1d6aff02e504e31cdfc53418f965d3aa 100644 --- a/src/share/vm/gc_interface/collectedHeap.hpp +++ b/src/share/vm/gc_interface/collectedHeap.hpp @@ -319,6 +319,9 @@ class CollectedHeap : public CHeapObj { // VM (then terminate). virtual void preload_and_dump(TRAPS) { ShouldNotReachHere(); } + // Allocate and initialize instances of Class + static oop Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS); + // General obj/array allocation facilities. inline static oop obj_allocate(KlassHandle klass, int size, TRAPS); inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS); diff --git a/src/share/vm/oops/instanceMirrorKlass.cpp b/src/share/vm/oops/instanceMirrorKlass.cpp index 8f6644139c4a56a83bce6fb80682ba0f372b6a1e..e0dd7d76aad3fa2422bc3aa86cdad5c1defd03f1 100644 --- a/src/share/vm/oops/instanceMirrorKlass.cpp +++ b/src/share/vm/oops/instanceMirrorKlass.cpp @@ -288,15 +288,7 @@ instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { // Query before forming handle. int size = instance_size(k); KlassHandle h_k(THREAD, as_klassOop()); - instanceOop i; - - if (JavaObjectsInPerm) { - i = (instanceOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); - } else { - assert(ScavengeRootsInCode > 0, "must be"); - i = (instanceOop) CollectedHeap::obj_allocate(h_k, size, CHECK_NULL); - } - + instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL); return i; }