src/share/vm/classfile/javaClasses.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
7017732 Cdiff src/share/vm/classfile/javaClasses.cpp
src/share/vm/classfile/javaClasses.cpp
Print this page
*** 31,40 ****
--- 31,41 ----
#include "interpreter/interpreter.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
+ #include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.hpp"
#include "oops/klassOop.hpp"
#include "oops/methodOop.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp"
*** 389,413 ****
}
st->print("\"");
}
}
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
assert(k->java_mirror() == NULL, "should only assign mirror once");
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
// the cached flags after the class file is parsed, but before the
// class is put into the system dictionary.
int computed_modifiers = k->compute_modifier_flags(CHECK_0);
k->set_modifier_flags(computed_modifiers);
! if (SystemDictionary::Class_klass_loaded()) {
// Allocate mirror (java.lang.Class instance)
! Handle mirror = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
// Setup indirections
mirror->obj_field_put(klass_offset, k());
k->set_java_mirror(mirror());
// It might also have a component mirror. This mirror must already exist.
if (k->oop_is_javaArray()) {
Handle comp_mirror;
if (k->oop_is_typeArray()) {
BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type();
--- 390,488 ----
}
st->print("\"");
}
}
+ static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
+ Handle mirror (THREAD, fd->field_holder()->java_mirror());
+ assert(mirror.not_null() && fd->is_static(), "just checking");
+ if (fd->has_initial_value()) {
+ BasicType t = fd->field_type();
+ switch (t) {
+ case T_BYTE:
+ mirror()->byte_field_put(fd->offset(), fd->int_initial_value());
+ break;
+ case T_BOOLEAN:
+ mirror()->bool_field_put(fd->offset(), fd->int_initial_value());
+ break;
+ case T_CHAR:
+ mirror()->char_field_put(fd->offset(), fd->int_initial_value());
+ break;
+ case T_SHORT:
+ mirror()->short_field_put(fd->offset(), fd->int_initial_value());
+ break;
+ case T_INT:
+ mirror()->int_field_put(fd->offset(), fd->int_initial_value());
+ break;
+ case T_FLOAT:
+ mirror()->float_field_put(fd->offset(), fd->float_initial_value());
+ break;
+ case T_DOUBLE:
+ mirror()->double_field_put(fd->offset(), fd->double_initial_value());
+ break;
+ case T_LONG:
+ mirror()->long_field_put(fd->offset(), fd->long_initial_value());
+ break;
+ case T_OBJECT:
+ {
+ #ifdef ASSERT
+ TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
+ assert(fd->signature() == sym, "just checking");
+ #endif
+ oop string = fd->string_initial_value(CHECK);
+ mirror()->obj_field_put(fd->offset(), string);
+ }
+ break;
+ default:
+ THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
+ "Illegal ConstantValue attribute in class file");
+ }
+ }
+ }
+
+ // During bootstrap, java.lang.Class wasn't loaded so static field
+ // offsets were computed without the size added it. Go back and
+ // update all the static field offsets to included the size.
+ static void fixup_static_field(fieldDescriptor* fd, TRAPS) {
+ if (fd->is_static()) {
+ int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields();
+ typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields();
+ fields->short_at_put(fd->index() + instanceKlass::low_offset, extract_low_short_from_int(real_offset));
+ fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
+ }
+ }
+
+ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
+ assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already");
+
+ if (k->oop_is_instance()) {
+ // Fixup the offsets
+ instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK);
+ }
+ create_mirror(k, CHECK);
+ }
+
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
assert(k->java_mirror() == NULL, "should only assign mirror once");
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
// the cached flags after the class file is parsed, but before the
// class is put into the system dictionary.
int computed_modifiers = k->compute_modifier_flags(CHECK_0);
k->set_modifier_flags(computed_modifiers);
! 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.
if (k->oop_is_javaArray()) {
Handle comp_mirror;
if (k->oop_is_typeArray()) {
BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type();
*** 426,458 ****
if (comp_mirror.not_null()) {
// Two-way link between the array klass and its component mirror:
arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror());
set_array_klass(comp_mirror(), k->as_klassOop());
}
}
return mirror();
} else {
return NULL;
}
}
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
! oop java_class = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
if (type != T_VOID) {
klassOop aklass = Universe::typeArrayKlassObj(type);
assert(aklass != NULL, "correct bootstrap");
set_array_klass(java_class, aklass);
}
return java_class;
}
klassOop java_lang_Class::as_klassOop(oop java_class) {
//%note memory_2
klassOop k = klassOop(java_class->obj_field(klass_offset));
assert(k == NULL || k->is_klass(), "type check");
return k;
}
--- 501,561 ----
if (comp_mirror.not_null()) {
// Two-way link between the array klass and its component mirror:
arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror());
set_array_klass(comp_mirror(), k->as_klassOop());
}
+ } else if (k->oop_is_instance()) {
+ // Initialize static fields
+ instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
}
return mirror();
} else {
return NULL;
}
}
+
+ int java_lang_Class::oop_size(oop java_class) {
+ assert(oop_size_offset != 0, "must be set");
+ return java_class->int_field(oop_size_offset);
+ }
+ void java_lang_Class::set_oop_size(oop java_class, int size) {
+ assert(oop_size_offset != 0, "must be set");
+ java_class->int_field_put(oop_size_offset, size);
+ }
+ int java_lang_Class::static_oop_field_count(oop java_class) {
+ assert(static_oop_field_count_offset != 0, "must be set");
+ return java_class->int_field(static_oop_field_count_offset);
+ }
+ void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
+ assert(static_oop_field_count_offset != 0, "must be set");
+ java_class->int_field_put(static_oop_field_count_offset, size);
+ }
+
+
+
+
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
! oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0);
if (type != T_VOID) {
klassOop aklass = Universe::typeArrayKlassObj(type);
assert(aklass != NULL, "correct bootstrap");
set_array_klass(java_class, aklass);
}
+ 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);
return java_class;
}
klassOop java_lang_Class::as_klassOop(oop java_class) {
//%note memory_2
+ assert(java_lang_Class::is_instance(java_class), "must be a Class object");
klassOop k = klassOop(java_class->obj_field(klass_offset));
assert(k == NULL || k->is_klass(), "type check");
return k;
}
*** 2150,2170 ****
// Support for java_lang_ref_Reference
oop java_lang_ref_Reference::pending_list_lock() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
! char *addr = (((char *)ik->start_of_static_fields()) + static_lock_offset);
if (UseCompressedOops) {
return oopDesc::load_decode_heap_oop((narrowOop *)addr);
} else {
return oopDesc::load_decode_heap_oop((oop*)addr);
}
}
HeapWord *java_lang_ref_Reference::pending_list_addr() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
! char *addr = (((char *)ik->start_of_static_fields()) + static_pending_offset);
// XXX This might not be HeapWord aligned, almost rather be char *.
return (HeapWord*)addr;
}
oop java_lang_ref_Reference::pending_list() {
--- 2253,2273 ----
// Support for java_lang_ref_Reference
oop java_lang_ref_Reference::pending_list_lock() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
! address addr = ik->static_field_addr(static_lock_offset);
if (UseCompressedOops) {
return oopDesc::load_decode_heap_oop((narrowOop *)addr);
} else {
return oopDesc::load_decode_heap_oop((oop*)addr);
}
}
HeapWord *java_lang_ref_Reference::pending_list_addr() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
! address addr = ik->static_field_addr(static_pending_offset);
// XXX This might not be HeapWord aligned, almost rather be char *.
return (HeapWord*)addr;
}
oop java_lang_ref_Reference::pending_list() {
*** 2183,2202 ****
return ref->long_field(timestamp_offset);
}
jlong java_lang_ref_SoftReference::clock() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
! int offset = ik->offset_of_static_fields() + static_clock_offset;
!
! return SystemDictionary::SoftReference_klass()->long_field(offset);
}
void java_lang_ref_SoftReference::set_clock(jlong value) {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
! int offset = ik->offset_of_static_fields() + static_clock_offset;
!
! SystemDictionary::SoftReference_klass()->long_field_put(offset, value);
}
// Support for java_lang_invoke_MethodHandle
--- 2286,2303 ----
return ref->long_field(timestamp_offset);
}
jlong java_lang_ref_SoftReference::clock() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
! jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
! return *offset;
}
void java_lang_ref_SoftReference::set_clock(jlong value) {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
! jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
! *offset = value;
}
// Support for java_lang_invoke_MethodHandle
*** 2623,2652 ****
return loader;
}
// Support for java_lang_System
-
- void java_lang_System::compute_offsets() {
- assert(offset_of_static_fields == 0, "offsets should be initialized only once");
-
- instanceKlass* ik = instanceKlass::cast(SystemDictionary::System_klass());
- offset_of_static_fields = ik->offset_of_static_fields();
- }
-
int java_lang_System::in_offset_in_bytes() {
! return (offset_of_static_fields + static_in_offset);
}
int java_lang_System::out_offset_in_bytes() {
! return (offset_of_static_fields + static_out_offset);
}
int java_lang_System::err_offset_in_bytes() {
! return (offset_of_static_fields + static_err_offset);
}
int java_lang_String::value_offset;
--- 2724,2745 ----
return loader;
}
// Support for java_lang_System
int java_lang_System::in_offset_in_bytes() {
! return (instanceMirrorKlass::offset_of_static_fields() + static_in_offset);
}
int java_lang_System::out_offset_in_bytes() {
! return (instanceMirrorKlass::offset_of_static_fields() + static_out_offset);
}
int java_lang_System::err_offset_in_bytes() {
! return (instanceMirrorKlass::offset_of_static_fields() + static_err_offset);
}
int java_lang_String::value_offset;
*** 2655,2664 ****
--- 2748,2759 ----
int java_lang_String::hash_offset;
int java_lang_Class::klass_offset;
int java_lang_Class::array_klass_offset;
int java_lang_Class::resolved_constructor_offset;
int java_lang_Class::number_of_fake_oop_fields;
+ int java_lang_Class::oop_size_offset;
+ int java_lang_Class::static_oop_field_count_offset;
int java_lang_Throwable::backtrace_offset;
int java_lang_Throwable::detailMessage_offset;
int java_lang_Throwable::cause_offset;
int java_lang_Throwable::stackTrace_offset;
int java_lang_reflect_AccessibleObject::override_offset;
*** 2698,2708 ****
int java_lang_ref_Reference::static_pending_offset;
int java_lang_ref_Reference::number_of_fake_oop_fields;
int java_lang_ref_SoftReference::timestamp_offset;
int java_lang_ref_SoftReference::static_clock_offset;
int java_lang_ClassLoader::parent_offset;
- int java_lang_System::offset_of_static_fields;
int java_lang_System::static_in_offset;
int java_lang_System::static_out_offset;
int java_lang_System::static_err_offset;
int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
--- 2793,2802 ----
*** 2815,2828 ****
java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header;
java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header;
java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint);
java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint);
// Do the Class Class
! java_lang_Class::klass_offset = java_lang_Class::hc_klass_offset * x + header;
! java_lang_Class::array_klass_offset = java_lang_Class::hc_array_klass_offset * x + header;
! java_lang_Class::resolved_constructor_offset = java_lang_Class::hc_resolved_constructor_offset * x + header;
// This is NOT an offset
java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields;
// Throwable Class
--- 2909,2931 ----
java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header;
java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header;
java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint);
java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint);
+ {
// Do the Class Class
! int offset = header;
! java_lang_Class::oop_size_offset = header;
! offset += BytesPerInt;
! java_lang_Class::static_oop_field_count_offset = offset;
! offset = align_size_up(offset + BytesPerInt, x);
! java_lang_Class::klass_offset = offset;
! offset += x;
! java_lang_Class::array_klass_offset = offset;
! offset += x;
! java_lang_Class::resolved_constructor_offset = offset;
! }
// This is NOT an offset
java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields;
// Throwable Class
*** 2875,2885 ****
// Compute non-hard-coded field offsets of all the classes in this file
void JavaClasses::compute_offsets() {
java_lang_Class::compute_offsets();
- java_lang_System::compute_offsets();
java_lang_Thread::compute_offsets();
java_lang_ThreadGroup::compute_offsets();
if (EnableMethodHandles) {
java_lang_invoke_MethodHandle::compute_offsets();
java_lang_invoke_MemberName::compute_offsets();
--- 2978,2987 ----
*** 2959,2972 ****
}
if (!fd.is_static()) {
tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
return false;
}
! if (fd.offset() == hardcoded_offset + h_klass->offset_of_static_fields()) {
return true;
} else {
! tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - h_klass->offset_of_static_fields());
return false;
}
}
--- 3061,3074 ----
}
if (!fd.is_static()) {
tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
return false;
}
! if (fd.offset() == hardcoded_offset + instanceMirrorKlass::offset_of_static_fields()) {
return true;
} else {
! tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - instanceMirrorKlass::offset_of_static_fields());
return false;
}
}
src/share/vm/classfile/javaClasses.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File