src/share/vm/classfile/javaClasses.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/classfile/javaClasses.cpp	Fri Sep  9 11:54:58 2011
--- new/src/share/vm/classfile/javaClasses.cpp	Fri Sep  9 11:54:58 2011

*** 31,40 **** --- 31,41 ---- #include "compiler/compilerOracle.hpp" #include "interpreter/interpreter.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" + #include "oops/fieldStreams.hpp" #include "oops/instanceKlass.hpp" #include "oops/instanceMirrorKlass.hpp" #include "oops/klass.hpp" #include "oops/klassOop.hpp" #include "oops/methodOop.hpp"
*** 56,65 **** --- 57,109 ---- #endif #ifdef TARGET_OS_FAMILY_windows # include "thread_windows.inline.hpp" #endif + #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ + klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum); + + #define DECLARE_INJECTED_FIELD(klass, name, signature, may_be_java) \ + { SystemDictionary::WK_KLASS_ENUM_NAME(klass), vmSymbols::VM_SYMBOL_ENUM_NAME(name##_name), vmSymbols::VM_SYMBOL_ENUM_NAME(signature), may_be_java }, + + InjectedField JavaClasses::_injected_fields[] = { + ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD) + }; + + int JavaClasses::compute_injected_offset(InjectedFieldID id) { + return _injected_fields[id].compute_offset(); + } + + + InjectedField* JavaClasses::get_injected(Symbol* class_name, int* field_count) { + *field_count = 0; + + vmSymbols::SID sid = vmSymbols::find_sid(class_name); + if (sid == vmSymbols::NO_SID) { + // Only well known classes can inject fields + return NULL; + } + + int count = 0; + int start = -1; + + #define LOOKUP_INJECTED_FIELD(klass, name, signature, may_be_java) \ + if (sid == vmSymbols::VM_SYMBOL_ENUM_NAME(klass)) { \ + count++; \ + if (start == -1) start = klass##_##name##_enum; \ + } + ALL_INJECTED_FIELDS(LOOKUP_INJECTED_FIELD); + #undef LOOKUP_INJECTED_FIELD + + if (start != -1) { + *field_count = count; + return _injected_fields + start; + } + return NULL; + } + + static bool find_field(instanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol, fieldDescriptor* fd, bool allow_super = false) { if (allow_super)
*** 426,454 **** --- 470,493 ---- } } } // 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); + // 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. + for (JavaFieldStream fs(instanceKlass::cast(k())); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + int real_offset = fs.offset() + instanceMirrorKlass::offset_of_static_fields(); + fs.set_offset(real_offset); } + } + } create_mirror(k, CHECK); } oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { assert(k->java_mirror() == NULL, "should only assign mirror once");
*** 460,470 **** --- 499,509 ---- 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()));
*** 502,530 **** --- 541,566 ---- } 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) {
*** 540,550 **** --- 576,586 ---- 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; }
*** 596,641 **** --- 632,677 ---- return name; } klassOop java_lang_Class::array_klass(oop java_class) { ! klassOop k = klassOop(java_class->obj_field(_array_klass_offset)); assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_javaArray(), "should be array klass"); return k; } void java_lang_Class::set_array_klass(oop java_class, klassOop klass) { assert(klass->is_klass() && Klass::cast(klass)->oop_is_javaArray(), "should be array klass"); ! java_class->obj_field_put(_array_klass_offset, klass); } methodOop java_lang_Class::resolved_constructor(oop java_class) { ! oop constructor = java_class->obj_field(_resolved_constructor_offset); assert(constructor == NULL || constructor->is_method(), "should be method"); return methodOop(constructor); } void java_lang_Class::set_resolved_constructor(oop java_class, methodOop constructor) { assert(constructor->is_method(), "should be method"); ! java_class->obj_field_put(_resolved_constructor_offset, constructor); } bool java_lang_Class::is_primitive(oop java_class) { // should assert: //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); ! klassOop k = klassOop(java_class->obj_field(_klass_offset)); return k == NULL; } BasicType java_lang_Class::primitive_type(oop java_class) { assert(java_lang_Class::is_primitive(java_class), "just checking"); ! klassOop ak = klassOop(java_class->obj_field(_array_klass_offset)); BasicType type = T_VOID; if (ak != NULL) { // Note: create_basic_type_mirror above initializes ak to a non-null value. type = arrayKlass::cast(ak)->element_type(); } else {
*** 666,705 **** --- 702,725 ---- return mirror; } bool java_lang_Class::offsets_computed = false; int java_lang_Class::classRedefinedCount_offset = -1; int java_lang_Class::parallelCapable_offset = -1; void java_lang_Class::compute_offsets() { assert(!offsets_computed, "offsets should be initialized only once"); offsets_computed = true; ! klassOop klass_oop = SystemDictionary::Class_klass(); // The classRedefinedCount field is only present starting in 1.5, // so don't go fatal. compute_optional_offset(classRedefinedCount_offset, ! klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature()); // The field indicating parallelCapable (parallelLockMap) is only present starting in 7, klassOop k1 = SystemDictionary::ClassLoader_klass(); compute_optional_offset(parallelCapable_offset, k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); + CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } // For class loader classes, parallelCapable defined // based on non-null field // Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it bool java_lang_Class::parallelCapable(oop class_loader) { if (!JDK_Version::is_gte_jdk17x_version() || parallelCapable_offset == -1) { // Default for backward compatibility is false return false; } return (class_loader->obj_field(parallelCapable_offset) != NULL); } int java_lang_Class::classRedefinedCount(oop the_class_mirror) { if (!JDK_Version::is_gte_jdk15x_version() || classRedefinedCount_offset == -1) { // The classRedefinedCount field is only present starting in 1.5. // If we don't have an offset for it then just return -1 as a marker.
*** 2306,2316 **** --- 2326,2335 ---- // Support for java_lang_invoke_MethodHandle int java_lang_invoke_MethodHandle::_type_offset; int java_lang_invoke_MethodHandle::_vmtarget_offset; int java_lang_invoke_MethodHandle::_vmentry_offset; int java_lang_invoke_MethodHandle::_vmslots_offset; int java_lang_invoke_MemberName::_clazz_offset; int java_lang_invoke_MemberName::_name_offset; int java_lang_invoke_MemberName::_type_offset; int java_lang_invoke_MemberName::_flags_offset;
*** 2325,2363 **** --- 2344,2377 ---- int java_lang_invoke_AdapterMethodHandle::_conversion_offset; int java_lang_invoke_CountingMethodHandle::_vmcount_offset; void java_lang_invoke_MethodHandle::compute_offsets() { ! klassOop klass_oop = SystemDictionary::MethodHandle_klass(); ! if (k != NULL && EnableInvokeDynamic) { ! if (klass_oop != NULL && EnableInvokeDynamic) { bool allow_super = false; ! compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super); ! compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), allow_super); compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), allow_super); // Note: MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots. // It is optional pending experiments to keep or toss. compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), allow_super); ! METHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } } void java_lang_invoke_MemberName::compute_offsets() { ! klassOop klass_oop = SystemDictionary::MemberName_klass(); ! if (klass_oop != NULL && EnableInvokeDynamic) { ! compute_offset(_clazz_offset, klass_oop, vmSymbols::clazz_name(), vmSymbols::class_signature()); ! compute_offset(_name_offset, klass_oop, vmSymbols::name_name(), vmSymbols::string_signature()); ! compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::object_signature()); ! compute_offset(_flags_offset, klass_oop, vmSymbols::flags_name(), vmSymbols::int_signature()); ! compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature()); ! compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature()); ! compute_offset(_vmindex_offset, klass_oop, vmSymbols::vmindex_name(), vmSymbols::int_signature()); ! MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } } void java_lang_invoke_DirectMethodHandle::compute_offsets() { klassOop k = SystemDictionary::DirectMethodHandle_klass(); if (k != NULL && EnableInvokeDynamic) { ! compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true); ! DIRECTMETHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } } void java_lang_invoke_BoundMethodHandle::compute_offsets() { klassOop k = SystemDictionary::BoundMethodHandle_klass();
*** 2397,2431 **** --- 2411,2423 ---- void java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) { mh->obj_field_put(_type_offset, mtype); } int java_lang_invoke_MethodHandle::vmslots(oop mh) { int vmslots_offset = _vmslots_offset; if (vmslots_offset != 0) { #ifdef ASSERT int x = mh->int_field(vmslots_offset); int y = compute_vmslots(mh); assert(x == y, "correct hoisted value"); #endif return mh->int_field(vmslots_offset); } else { return compute_vmslots(mh); } } // if MH.vmslots exists, hoist into it the value of type.form.vmslots void java_lang_invoke_MethodHandle::init_vmslots(oop mh) { int vmslots_offset = _vmslots_offset; if (vmslots_offset != 0) { mh->int_field_put(vmslots_offset, compute_vmslots(mh)); } } // fetch type.form.vmslots, which is the number of JVM stack slots // required to carry the arguments of this MH - int java_lang_invoke_MethodHandle::compute_vmslots(oop mh) { oop mtype = type(mh); if (mtype == NULL) return 0; // Java code would get NPE oop form = java_lang_invoke_MethodType::form(mtype); if (form == NULL) return 0; // Java code would get NPE return java_lang_invoke_MethodTypeForm::vmslots(form);
*** 2641,2650 **** --- 2633,2643 ---- compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true); compute_optional_offset(_vmlayout_offset, k, vmSymbols::vmlayout_name(), vmSymbols::object_signature()); compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true); compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true); if (_genericInvoker_offset == 0) _genericInvoker_offset = -1; // set to explicit "empty" value + METHODTYPEFORM_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } } int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) { assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
*** 2749,2765 **** --- 2742,2782 ---- return result; } // Support for java_lang_ClassLoader + bool java_lang_ClassLoader::offsets_computed = false; + int java_lang_ClassLoader::parallelCapable_offset = -1; + void java_lang_ClassLoader::compute_offsets() { + assert(!offsets_computed, "offsets should be initialized only once"); + offsets_computed = true; + + // The field indicating parallelCapable (parallelLockMap) is only present starting in 7, + klassOop k1 = SystemDictionary::ClassLoader_klass(); + compute_optional_offset(parallelCapable_offset, + k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); + } + oop java_lang_ClassLoader::parent(oop loader) { assert(loader->is_oop(), "loader must be oop"); return loader->obj_field(parent_offset); } + // For class loader classes, parallelCapable defined + // based on non-null field + // Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it + bool java_lang_ClassLoader::parallelCapable(oop class_loader) { + if (!JDK_Version::is_gte_jdk17x_version() + || parallelCapable_offset == -1) { + // Default for backward compatibility is false + return false; + } + return (class_loader->obj_field(parallelCapable_offset) != NULL); + } + bool java_lang_ClassLoader::is_trusted_loader(oop loader) { // Fix for 4474172; see evaluation for more details loader = non_reflection_class_loader(loader); oop cl = SystemDictionary::java_system_loader();
*** 2805,2820 **** --- 2822,2836 ---- int java_lang_String::value_offset; int java_lang_String::offset_offset; int java_lang_String::count_offset; 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_Class::_array_klass_offset; ! int java_lang_Class::_resolved_constructor_offset; ! 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_Throwable::static_unassigned_stacktrace_offset;
*** 2923,2946 **** --- 2939,2962 ---- return _limit_offset; } void java_nio_Buffer::compute_offsets() { - klassOop k = SystemDictionary::java_nio_Buffer_klass(); assert(k != NULL, "must be loaded in 1.4+"); compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature()); } // Support for intrinsification of sun.misc.AtomicLongCSImpl.attemptUpdate int sun_misc_AtomicLongCSImpl::value_offset() { - assert(SystemDictionary::sun_misc_AtomicLongCSImpl_klass() != NULL, "can't call this"); return _value_offset; } void sun_misc_AtomicLongCSImpl::compute_offsets() { - klassOop k = SystemDictionary::sun_misc_AtomicLongCSImpl_klass(); // If this class is not present, its value field offset won't be referenced. if (k != NULL) { compute_offset(_value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature()); } }
*** 2971,2997 **** --- 2987,2996 ---- 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 java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
*** 3039,3050 **** --- 3038,3049 ---- } // Compute non-hard-coded field offsets of all the classes in this file void JavaClasses::compute_offsets() { ! java_lang_ClassLoader::compute_offsets(); + // java_lang_Class::compute_offsets was called earlier in bootstrap java_lang_Thread::compute_offsets(); java_lang_ThreadGroup::compute_offsets(); if (EnableInvokeDynamic) { java_lang_invoke_MethodHandle::compute_offsets(); java_lang_invoke_MemberName::compute_offsets();
*** 3265,3274 **** --- 3264,3290 ---- if (!valid) vm_exit_during_initialization("Hard-coded field offset verification failed"); } #endif // PRODUCT + int InjectedField::compute_offset() { + klassOop klass_oop = klass(); + for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) { + if (!may_be_java && !fs.access_flags().is_internal()) { + // Only look at injected fields + continue; + } + if (fs.name() == name() && fs.signature() == signature()) { + return fs.offset(); + } + } + ResourceMark rm; + tty->print_cr("Invalid layout of %s at %s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string()); + fatal("Invalid layout of preloaded class"); + return -1; + } + void javaClasses_init() { JavaClasses::compute_offsets(); JavaClasses::check_offsets(); FilteredFieldsMap::initialize(); // must be done after computing offsets. }

src/share/vm/classfile/javaClasses.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File