# HG changeset patch # User sbohne # Date 1209741731 25200 # Node ID bcdc68eb7e1ff03d17c47f9a1834ff80065ce9a4 # Parent 53735b80b9f16f880a1597db87dcb3155fd98d21# Parent 60b728ec77c195aebdc52cb94045e9bf2527d654 Merge diff -r 53735b80b9f1 -r bcdc68eb7e1f agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu May 01 09:38:23 2008 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Fri May 02 08:22:11 2008 -0700 @@ -29,21 +29,27 @@ import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.types.OopField; // resolve ambiguity with oops.OopField + +// following needed for on-the-fly field construction: +import sun.jvm.hotspot.types.basic.BasicOopField; +import sun.jvm.hotspot.types.basic.BasicTypeDataBase; public class SystemDictionary { private static AddressField dictionaryField; private static AddressField sharedDictionaryField; private static AddressField placeholdersField; private static AddressField loaderConstraintTableField; - private static sun.jvm.hotspot.types.OopField javaSystemLoaderField; + private static OopField javaSystemLoaderField; private static int nofBuckets; - private static sun.jvm.hotspot.types.OopField objectKlassField; - private static sun.jvm.hotspot.types.OopField classLoaderKlassField; - private static sun.jvm.hotspot.types.OopField stringKlassField; - private static sun.jvm.hotspot.types.OopField systemKlassField; - private static sun.jvm.hotspot.types.OopField threadKlassField; - private static sun.jvm.hotspot.types.OopField threadGroupKlassField; + private static OopField wellKnownKlasses; + private static OopField objectKlassField; + private static OopField classLoaderKlassField; + private static OopField stringKlassField; + private static OopField systemKlassField; + private static OopField threadKlassField; + private static OopField threadGroupKlassField; static { VM.registerVMInitializedObserver(new Observer() { @@ -63,12 +69,20 @@ javaSystemLoaderField = type.getOopField("_java_system_loader"); nofBuckets = db.lookupIntConstant("SystemDictionary::_nof_buckets").intValue(); - objectKlassField = type.getOopField("_object_klass"); - classLoaderKlassField = type.getOopField("_classloader_klass"); - stringKlassField = type.getOopField("_string_klass"); - systemKlassField = type.getOopField("_system_klass"); - threadKlassField = type.getOopField("_thread_klass"); - threadGroupKlassField = type.getOopField("_threadGroup_klass"); + wellKnownKlasses = type.getOopField("_well_known_klasses[0]"); + objectKlassField = findWellKnownKlass("object_klass", type, db); + classLoaderKlassField = findWellKnownKlass("classloader_klass", type, db); + stringKlassField = findWellKnownKlass("string_klass", type, db); + systemKlassField = findWellKnownKlass("system_klass", type, db); + threadKlassField = findWellKnownKlass("thread_klass", type, db); + threadGroupKlassField = findWellKnownKlass("threadGroup_klass", type, db); + } + + private static OopField findWellKnownKlass(String indexName, Type type, TypeDataBase db) { + Address wkk = wellKnownKlasses.getStaticFieldAddress(); + int index = db.lookupIntConstant("SystemDictionary::#"+indexName).intValue(); + return new BasicOopField((BasicTypeDataBase)db, type, indexName, type, + true, index * db.getAddressSize(), wkk); } public Dictionary dictionary() { diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/classfile/javaClasses.cpp Fri May 02 08:22:11 2008 -0700 @@ -25,25 +25,29 @@ # include "incls/_precompiled.incl" # include "incls/_javaClasses.cpp.incl" -// Helpful macro for computing field offsets at run time rather than hardcoding them -#define COMPUTE_OFFSET(klass_name_as_C_str, dest_offset, klass_oop, name_symbol, signature_symbol) \ -{ \ - fieldDescriptor fd; \ - instanceKlass* ik = instanceKlass::cast(klass_oop); \ - if (!ik->find_local_field(name_symbol, signature_symbol, &fd)) { \ - fatal("Invalid layout of " klass_name_as_C_str); \ - } \ - dest_offset = fd.offset(); \ +// Helpful routine for computing field offsets at run time rather than hardcoding them +static void +compute_offset(int &dest_offset, + klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol) { + fieldDescriptor fd; + instanceKlass* ik = instanceKlass::cast(klass_oop); + if (!ik->find_local_field(name_symbol, signature_symbol, &fd)) { + ResourceMark rm; + tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string()); + fatal("Invalid layout of preloaded class"); + } + dest_offset = fd.offset(); } // Same as above but for "optional" offsets that might not be present in certain JDK versions -#define COMPUTE_OPTIONAL_OFFSET(klass_name_as_C_str, dest_offset, klass_oop, name_symbol, signature_symbol) \ -{ \ - fieldDescriptor fd; \ - instanceKlass* ik = instanceKlass::cast(klass_oop); \ - if (ik->find_local_field(name_symbol, signature_symbol, &fd)) { \ - dest_offset = fd.offset(); \ - } \ +static void +compute_optional_offset(int& dest_offset, + klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol) { + fieldDescriptor fd; + instanceKlass* ik = instanceKlass::cast(klass_oop); + if (ik->find_local_field(name_symbol, signature_symbol, &fd)) { + dest_offset = fd.offset(); + } } Handle java_lang_String::basic_create(int length, bool tenured, TRAPS) { @@ -445,7 +449,7 @@ klassOop k = SystemDictionary::class_klass(); // The classRedefinedCount field is only present starting in 1.5, // so don't go fatal. - COMPUTE_OPTIONAL_OFFSET("java.lang.Class", classRedefinedCount_offset, + compute_optional_offset(classRedefinedCount_offset, k, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature()); } @@ -499,22 +503,22 @@ assert(_group_offset == 0, "offsets should be initialized only once"); klassOop k = SystemDictionary::thread_klass(); - COMPUTE_OFFSET("java.lang.Thread", _name_offset, k, vmSymbols::name_name(), vmSymbols::char_array_signature()); - COMPUTE_OFFSET("java.lang.Thread", _group_offset, k, vmSymbols::group_name(), vmSymbols::threadgroup_signature()); - COMPUTE_OFFSET("java.lang.Thread", _contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), vmSymbols::classloader_signature()); - COMPUTE_OFFSET("java.lang.Thread", _inheritedAccessControlContext_offset, k, vmSymbols::inheritedAccessControlContext_name(), vmSymbols::accesscontrolcontext_signature()); - COMPUTE_OFFSET("java.lang.Thread", _priority_offset, k, vmSymbols::priority_name(), vmSymbols::int_signature()); - COMPUTE_OFFSET("java.lang.Thread", _daemon_offset, k, vmSymbols::daemon_name(), vmSymbols::bool_signature()); - COMPUTE_OFFSET("java.lang.Thread", _eetop_offset, k, vmSymbols::eetop_name(), vmSymbols::long_signature()); - COMPUTE_OFFSET("java.lang.Thread", _stillborn_offset, k, vmSymbols::stillborn_name(), vmSymbols::bool_signature()); + compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::char_array_signature()); + compute_offset(_group_offset, k, vmSymbols::group_name(), vmSymbols::threadgroup_signature()); + compute_offset(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), vmSymbols::classloader_signature()); + compute_offset(_inheritedAccessControlContext_offset, k, vmSymbols::inheritedAccessControlContext_name(), vmSymbols::accesscontrolcontext_signature()); + compute_offset(_priority_offset, k, vmSymbols::priority_name(), vmSymbols::int_signature()); + compute_offset(_daemon_offset, k, vmSymbols::daemon_name(), vmSymbols::bool_signature()); + compute_offset(_eetop_offset, k, vmSymbols::eetop_name(), vmSymbols::long_signature()); + compute_offset(_stillborn_offset, k, vmSymbols::stillborn_name(), vmSymbols::bool_signature()); // The stackSize field is only present starting in 1.4, so don't go fatal. - COMPUTE_OPTIONAL_OFFSET("java.lang.Thread", _stackSize_offset, k, vmSymbols::stackSize_name(), vmSymbols::long_signature()); + compute_optional_offset(_stackSize_offset, k, vmSymbols::stackSize_name(), vmSymbols::long_signature()); // The tid and thread_status fields are only present starting in 1.5, so don't go fatal. - COMPUTE_OPTIONAL_OFFSET("java.lang.Thread", _tid_offset, k, vmSymbols::thread_id_name(), vmSymbols::long_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.Thread", _thread_status_offset, k, vmSymbols::thread_status_name(), vmSymbols::int_signature()); + compute_optional_offset(_tid_offset, k, vmSymbols::thread_id_name(), vmSymbols::long_signature()); + compute_optional_offset(_thread_status_offset, k, vmSymbols::thread_status_name(), vmSymbols::int_signature()); // The parkBlocker field is only present starting in 1.6, so don't go fatal. - COMPUTE_OPTIONAL_OFFSET("java.lang.Thread", _park_blocker_offset, k, vmSymbols::park_blocker_name(), vmSymbols::object_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.Thread", _park_event_offset, k, vmSymbols::park_event_name(), + compute_optional_offset(_park_blocker_offset, k, vmSymbols::park_blocker_name(), vmSymbols::object_signature()); + compute_optional_offset(_park_event_offset, k, vmSymbols::park_event_name(), vmSymbols::long_signature()); } @@ -759,16 +763,16 @@ klassOop k = SystemDictionary::threadGroup_klass(); - COMPUTE_OFFSET("java.lang.ThreadGroup", _parent_offset, k, vmSymbols::parent_name(), vmSymbols::threadgroup_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _threads_offset, k, vmSymbols::threads_name(), vmSymbols::thread_array_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _groups_offset, k, vmSymbols::groups_name(), vmSymbols::threadgroup_array_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _maxPriority_offset, k, vmSymbols::maxPriority_name(), vmSymbols::int_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _destroyed_offset, k, vmSymbols::destroyed_name(), vmSymbols::bool_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _daemon_offset, k, vmSymbols::daemon_name(), vmSymbols::bool_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _vmAllowSuspension_offset, k, vmSymbols::vmAllowSuspension_name(), vmSymbols::bool_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _nthreads_offset, k, vmSymbols::nthreads_name(), vmSymbols::int_signature()); - COMPUTE_OFFSET("java.lang.ThreadGroup", _ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); + compute_offset(_parent_offset, k, vmSymbols::parent_name(), vmSymbols::threadgroup_signature()); + compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); + compute_offset(_threads_offset, k, vmSymbols::threads_name(), vmSymbols::thread_array_signature()); + compute_offset(_groups_offset, k, vmSymbols::groups_name(), vmSymbols::threadgroup_array_signature()); + compute_offset(_maxPriority_offset, k, vmSymbols::maxPriority_name(), vmSymbols::int_signature()); + compute_offset(_destroyed_offset, k, vmSymbols::destroyed_name(), vmSymbols::bool_signature()); + compute_offset(_daemon_offset, k, vmSymbols::daemon_name(), vmSymbols::bool_signature()); + compute_offset(_vmAllowSuspension_offset, k, vmSymbols::vmAllowSuspension_name(), vmSymbols::bool_signature()); + compute_offset(_nthreads_offset, k, vmSymbols::nthreads_name(), vmSymbols::int_signature()); + compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); } oop java_lang_Throwable::backtrace(oop throwable) { @@ -1361,6 +1365,7 @@ // Allocate java.lang.StackTraceElement instance klassOop k = SystemDictionary::stackTraceElement_klass(); + assert(k != NULL, "must be loaded in 1.4+"); instanceKlassHandle ik (THREAD, k); if (ik->should_be_initialized()) { ik->initialize(CHECK_0); @@ -1398,7 +1403,7 @@ void java_lang_reflect_AccessibleObject::compute_offsets() { klassOop k = SystemDictionary::reflect_accessible_object_klass(); - COMPUTE_OFFSET("java.lang.reflect.AccessibleObject", override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature()); + compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature()); } jboolean java_lang_reflect_AccessibleObject::override(oop reflect) { @@ -1413,22 +1418,22 @@ void java_lang_reflect_Method::compute_offsets() { klassOop k = SystemDictionary::reflect_method_klass(); - COMPUTE_OFFSET("java.lang.reflect.Method", clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); - COMPUTE_OFFSET("java.lang.reflect.Method", name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); - COMPUTE_OFFSET("java.lang.reflect.Method", returnType_offset, k, vmSymbols::returnType_name(), vmSymbols::class_signature()); - COMPUTE_OFFSET("java.lang.reflect.Method", parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature()); - COMPUTE_OFFSET("java.lang.reflect.Method", exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature()); - COMPUTE_OFFSET("java.lang.reflect.Method", slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); - COMPUTE_OFFSET("java.lang.reflect.Method", modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); + compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); + compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); + compute_offset(returnType_offset, k, vmSymbols::returnType_name(), vmSymbols::class_signature()); + compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature()); + compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature()); + compute_offset(slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); + compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); // The generic signature and annotations fields are only present in 1.5 signature_offset = -1; annotations_offset = -1; parameter_annotations_offset = -1; annotation_default_offset = -1; - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Method", signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Method", annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Method", parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Method", annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); + compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Method::create(TRAPS) { @@ -1576,18 +1581,18 @@ void java_lang_reflect_Constructor::compute_offsets() { klassOop k = SystemDictionary::reflect_constructor_klass(); - COMPUTE_OFFSET("java.lang.reflect.Constructor", clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); - COMPUTE_OFFSET("java.lang.reflect.Constructor", parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature()); - COMPUTE_OFFSET("java.lang.reflect.Constructor", exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature()); - COMPUTE_OFFSET("java.lang.reflect.Constructor", slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); - COMPUTE_OFFSET("java.lang.reflect.Constructor", modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); + compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); + compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature()); + compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature()); + compute_offset(slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); + compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); // The generic signature and annotations fields are only present in 1.5 signature_offset = -1; annotations_offset = -1; parameter_annotations_offset = -1; - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Constructor", signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Constructor", annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Constructor", parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); + compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Constructor::create(TRAPS) { @@ -1700,16 +1705,16 @@ void java_lang_reflect_Field::compute_offsets() { klassOop k = SystemDictionary::reflect_field_klass(); - COMPUTE_OFFSET("java.lang.reflect.Field", clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); - COMPUTE_OFFSET("java.lang.reflect.Field", name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); - COMPUTE_OFFSET("java.lang.reflect.Field", type_offset, k, vmSymbols::type_name(), vmSymbols::class_signature()); - COMPUTE_OFFSET("java.lang.reflect.Field", slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); - COMPUTE_OFFSET("java.lang.reflect.Field", modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); + compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); + compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); + compute_offset(type_offset, k, vmSymbols::type_name(), vmSymbols::class_signature()); + compute_offset(slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); + compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); // The generic signature and annotations fields are only present in 1.5 signature_offset = -1; annotations_offset = -1; - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Field", signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); - COMPUTE_OPTIONAL_OFFSET("java.lang.reflect.Field", annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); + compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Field::create(TRAPS) { @@ -1809,7 +1814,7 @@ klassOop k = SystemDictionary::reflect_constant_pool_klass(); // This null test can be removed post beta if (k != NULL) { - COMPUTE_OFFSET("sun.reflect.ConstantPool", _cp_oop_offset, k, vmSymbols::constantPoolOop_name(), vmSymbols::object_signature()); + compute_offset(_cp_oop_offset, k, vmSymbols::constantPoolOop_name(), vmSymbols::object_signature()); } } @@ -1839,51 +1844,46 @@ klassOop k = SystemDictionary::reflect_unsafe_static_field_accessor_impl_klass(); // This null test can be removed post beta if (k != NULL) { - COMPUTE_OFFSET("sun.reflect.UnsafeStaticFieldAccessorImpl", _base_offset, k, + compute_offset(_base_offset, k, vmSymbols::base_name(), vmSymbols::object_signature()); } } -oop java_lang_boxing_object::initialize_and_allocate(klassOop k, TRAPS) { - instanceKlassHandle h (THREAD, k); - if (!h->is_initialized()) h->initialize(CHECK_0); - return h->allocate_instance(THREAD); +oop java_lang_boxing_object::initialize_and_allocate(BasicType type, TRAPS) { + klassOop k = SystemDictionary::box_klass(type); + if (k == NULL) return NULL; + instanceKlassHandle h (THREAD, k); + if (!h->is_initialized()) h->initialize(CHECK_0); + return h->allocate_instance(THREAD); } oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) { - oop box; + oop box = initialize_and_allocate(type, CHECK_0); + if (box == NULL) return NULL; switch (type) { case T_BOOLEAN: - box = initialize_and_allocate(SystemDictionary::boolean_klass(), CHECK_0); box->bool_field_put(value_offset, value->z); break; case T_CHAR: - box = initialize_and_allocate(SystemDictionary::char_klass(), CHECK_0); box->char_field_put(value_offset, value->c); break; case T_FLOAT: - box = initialize_and_allocate(SystemDictionary::float_klass(), CHECK_0); box->float_field_put(value_offset, value->f); break; case T_DOUBLE: - box = initialize_and_allocate(SystemDictionary::double_klass(), CHECK_0); box->double_field_put(value_offset, value->d); break; case T_BYTE: - box = initialize_and_allocate(SystemDictionary::byte_klass(), CHECK_0); box->byte_field_put(value_offset, value->b); break; case T_SHORT: - box = initialize_and_allocate(SystemDictionary::short_klass(), CHECK_0); box->short_field_put(value_offset, value->s); break; case T_INT: - box = initialize_and_allocate(SystemDictionary::int_klass(), CHECK_0); box->int_field_put(value_offset, value->i); break; case T_LONG: - box = initialize_and_allocate(SystemDictionary::long_klass(), CHECK_0); box->long_field_put(value_offset, value->j); break; default: @@ -1893,79 +1893,80 @@ } +BasicType java_lang_boxing_object::basic_type(oop box) { + if (box == NULL) return T_ILLEGAL; + BasicType type = SystemDictionary::box_klass_type(box->klass()); + if (type == T_OBJECT) // 'unknown' value returned by SD::bkt + return T_ILLEGAL; + return type; +} + + BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) { - klassOop k = box->klass(); - if (k == SystemDictionary::boolean_klass()) { + BasicType type = SystemDictionary::box_klass_type(box->klass()); + switch (type) { + case T_BOOLEAN: value->z = box->bool_field(value_offset); - return T_BOOLEAN; - } - if (k == SystemDictionary::char_klass()) { + break; + case T_CHAR: value->c = box->char_field(value_offset); - return T_CHAR; - } - if (k == SystemDictionary::float_klass()) { + break; + case T_FLOAT: value->f = box->float_field(value_offset); - return T_FLOAT; - } - if (k == SystemDictionary::double_klass()) { + break; + case T_DOUBLE: value->d = box->double_field(value_offset); - return T_DOUBLE; - } - if (k == SystemDictionary::byte_klass()) { + break; + case T_BYTE: value->b = box->byte_field(value_offset); - return T_BYTE; - } - if (k == SystemDictionary::short_klass()) { + break; + case T_SHORT: value->s = box->short_field(value_offset); - return T_SHORT; - } - if (k == SystemDictionary::int_klass()) { + break; + case T_INT: value->i = box->int_field(value_offset); - return T_INT; - } - if (k == SystemDictionary::long_klass()) { + break; + case T_LONG: value->j = box->long_field(value_offset); - return T_LONG; - } - return T_ILLEGAL; + break; + default: + return T_ILLEGAL; + } // end switch + return type; } BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) { - klassOop k = box->klass(); - if (k == SystemDictionary::boolean_klass()) { + BasicType type = SystemDictionary::box_klass_type(box->klass()); + switch (type) { + case T_BOOLEAN: box->bool_field_put(value_offset, value->z); - return T_BOOLEAN; - } - if (k == SystemDictionary::char_klass()) { + break; + case T_CHAR: box->char_field_put(value_offset, value->c); - return T_CHAR; - } - if (k == SystemDictionary::float_klass()) { + break; + case T_FLOAT: box->float_field_put(value_offset, value->f); - return T_FLOAT; - } - if (k == SystemDictionary::double_klass()) { + break; + case T_DOUBLE: box->double_field_put(value_offset, value->d); - return T_DOUBLE; - } - if (k == SystemDictionary::byte_klass()) { + break; + case T_BYTE: box->byte_field_put(value_offset, value->b); - return T_BYTE; - } - if (k == SystemDictionary::short_klass()) { + break; + case T_SHORT: box->short_field_put(value_offset, value->s); - return T_SHORT; - } - if (k == SystemDictionary::int_klass()) { + break; + case T_INT: box->int_field_put(value_offset, value->i); - return T_INT; - } - if (k == SystemDictionary::long_klass()) { + break; + case T_LONG: box->long_field_put(value_offset, value->j); - return T_LONG; - } - return T_ILLEGAL; + break; + default: + return T_ILLEGAL; + } // end switch + return type; } @@ -2242,7 +2243,8 @@ void java_nio_Buffer::compute_offsets() { klassOop k = SystemDictionary::java_nio_Buffer_klass(); - COMPUTE_OFFSET("java.nio.Buffer", _limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature()); + 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 @@ -2256,7 +2258,7 @@ 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("sun.misc.AtomicLongCSImpl", _value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature()); + compute_offset(_value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature()); } } @@ -2266,7 +2268,7 @@ assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later"); SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK); klassOop k = SystemDictionary::abstract_ownable_synchronizer_klass(); - COMPUTE_OFFSET("java.util.concurrent.locks.AbstractOwnableSynchronizer", _owner_offset, k, + compute_offset(_owner_offset, k, vmSymbols::exclusive_owner_thread_name(), vmSymbols::thread_signature()); } @@ -2429,6 +2431,36 @@ } +bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) { + EXCEPTION_MARK; + fieldDescriptor fd; + symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); + klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); + instanceKlassHandle h_klass (THREAD, k); + symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); + symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); + if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { + tty->print_cr("Static field %s.%s not found", klass_name, field_name); + return false; + } + if (!fd.is_static() || !fd.has_initial_value()) { + tty->print_cr("Static field %s.%s appears to be non-constant", klass_name, field_name); + return false; + } + if (!fd.initial_value_tag().is_int()) { + tty->print_cr("Static field %s.%s is not an int", klass_name, field_name); + return false; + } + jint field_value = fd.int_initial_value(); + if (field_value == hardcoded_constant) { + return true; + } else { + tty->print_cr("Constant value of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_constant, field_value); + return false; + } +} + + // Check the hard-coded field offsets of all the classes in this file void JavaClasses::check_offsets() { @@ -2440,6 +2472,9 @@ #define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig) +#define CHECK_CONSTANT(klass_name, cpp_klass_name, field_name, field_sig) \ + valid &= check_constant(klass_name, cpp_klass_name :: field_name, #field_name, field_sig) + // java.lang.String CHECK_OFFSET("java/lang/String", java_lang_String, value, "[C"); diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/classfile/javaClasses.hpp Fri May 02 08:22:11 2008 -0700 @@ -45,9 +45,9 @@ private: enum { hc_value_offset = 0, - hc_offset_offset = 1, - hc_count_offset = 2, - hc_hash_offset = 3 + hc_offset_offset = 1 + //hc_count_offset = 2 -- not a word-scaled offset + //hc_hash_offset = 3 -- not a word-scaled offset }; static int value_offset; @@ -149,6 +149,9 @@ // Conversion static klassOop as_klassOop(oop java_class); // Testing + static bool is_instance(oop obj) { + return obj != NULL && obj->klass() == SystemDictionary::class_klass(); + } static bool is_primitive(oop java_class); static BasicType primitive_type(oop java_class); static oop primitive_mirror(BasicType t); @@ -651,13 +654,16 @@ }; static int value_offset; - static oop initialize_and_allocate(klassOop klass, TRAPS); + static oop initialize_and_allocate(BasicType type, TRAPS); public: // Allocation. Returns a boxed value, or NULL for invalid type. static oop create(BasicType type, jvalue* value, TRAPS); // Accessors. Returns the basic type being boxed, or T_ILLEGAL for invalid oop. static BasicType get_value(oop box, jvalue* value); static BasicType set_value(oop box, jvalue* value); + static BasicType basic_type(oop box); + static bool is_instance(oop box) { return basic_type(box) != T_ILLEGAL; } + static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; } static int value_offset_in_bytes() { return value_offset; } @@ -921,6 +927,7 @@ private: static bool check_offset(const char *klass_name, int offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0; static bool check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0; + static bool check_constant(const char *klass_name, int constant, const char *field_name, const char* field_sig) PRODUCT_RETURN0; public: static void compute_hard_coded_offsets(); static void compute_offsets(); diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri May 02 08:22:11 2008 -0700 @@ -37,71 +37,9 @@ oop SystemDictionary::_system_loader_lock_obj = NULL; -klassOop SystemDictionary::_object_klass = NULL; -klassOop SystemDictionary::_string_klass = NULL; -klassOop SystemDictionary::_class_klass = NULL; -klassOop SystemDictionary::_cloneable_klass = NULL; -klassOop SystemDictionary::_classloader_klass = NULL; -klassOop SystemDictionary::_serializable_klass = NULL; -klassOop SystemDictionary::_system_klass = NULL; - -klassOop SystemDictionary::_throwable_klass = NULL; -klassOop SystemDictionary::_error_klass = NULL; -klassOop SystemDictionary::_threaddeath_klass = NULL; -klassOop SystemDictionary::_exception_klass = NULL; -klassOop SystemDictionary::_runtime_exception_klass = NULL; -klassOop SystemDictionary::_classNotFoundException_klass = NULL; -klassOop SystemDictionary::_noClassDefFoundError_klass = NULL; -klassOop SystemDictionary::_linkageError_klass = NULL; -klassOop SystemDictionary::_classCastException_klass = NULL; -klassOop SystemDictionary::_arrayStoreException_klass = NULL; -klassOop SystemDictionary::_virtualMachineError_klass = NULL; -klassOop SystemDictionary::_outOfMemoryError_klass = NULL; -klassOop SystemDictionary::_StackOverflowError_klass = NULL; -klassOop SystemDictionary::_illegalMonitorStateException_klass = NULL; -klassOop SystemDictionary::_protectionDomain_klass = NULL; -klassOop SystemDictionary::_AccessControlContext_klass = NULL; - -klassOop SystemDictionary::_reference_klass = NULL; -klassOop SystemDictionary::_soft_reference_klass = NULL; -klassOop SystemDictionary::_weak_reference_klass = NULL; -klassOop SystemDictionary::_final_reference_klass = NULL; -klassOop SystemDictionary::_phantom_reference_klass = NULL; -klassOop SystemDictionary::_finalizer_klass = NULL; +klassOop SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT] + = { NULL /*, NULL...*/ }; -klassOop SystemDictionary::_thread_klass = NULL; -klassOop SystemDictionary::_threadGroup_klass = NULL; -klassOop SystemDictionary::_properties_klass = NULL; -klassOop SystemDictionary::_reflect_accessible_object_klass = NULL; -klassOop SystemDictionary::_reflect_field_klass = NULL; -klassOop SystemDictionary::_reflect_method_klass = NULL; -klassOop SystemDictionary::_reflect_constructor_klass = NULL; -klassOop SystemDictionary::_reflect_magic_klass = NULL; -klassOop SystemDictionary::_reflect_method_accessor_klass = NULL; -klassOop SystemDictionary::_reflect_constructor_accessor_klass = NULL; -klassOop SystemDictionary::_reflect_delegating_classloader_klass = NULL; -klassOop SystemDictionary::_reflect_constant_pool_klass = NULL; -klassOop SystemDictionary::_reflect_unsafe_static_field_accessor_impl_klass = NULL; - -klassOop SystemDictionary::_vector_klass = NULL; -klassOop SystemDictionary::_hashtable_klass = NULL; -klassOop SystemDictionary::_stringBuffer_klass = NULL; - -klassOop SystemDictionary::_stackTraceElement_klass = NULL; - -klassOop SystemDictionary::_java_nio_Buffer_klass = NULL; - -klassOop SystemDictionary::_sun_misc_AtomicLongCSImpl_klass = NULL; -klassOop SystemDictionary::_sun_jkernel_DownloadManager_klass = NULL; - -klassOop SystemDictionary::_boolean_klass = NULL; -klassOop SystemDictionary::_char_klass = NULL; -klassOop SystemDictionary::_float_klass = NULL; -klassOop SystemDictionary::_double_klass = NULL; -klassOop SystemDictionary::_byte_klass = NULL; -klassOop SystemDictionary::_short_klass = NULL; -klassOop SystemDictionary::_int_klass = NULL; -klassOop SystemDictionary::_long_klass = NULL; klassOop SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*, NULL...*/ }; oop SystemDictionary::_java_system_loader = NULL; @@ -121,10 +59,10 @@ } void SystemDictionary::compute_java_system_loader(TRAPS) { - KlassHandle system_klass(THREAD, _classloader_klass); + KlassHandle system_klass(THREAD, WK_KLASS(classloader_klass)); JavaValue result(T_OBJECT); JavaCalls::call_static(&result, - KlassHandle(THREAD, _classloader_klass), + KlassHandle(THREAD, WK_KLASS(classloader_klass)), vmSymbolHandles::getSystemClassLoader_name(), vmSymbolHandles::void_classloader_signature(), CHECK); @@ -292,6 +230,15 @@ bool is_superclass, TRAPS) { + // Try to get one of the well-known klasses. + // They are trusted, and do not participate in circularities. + if (LinkWellKnownClasses) { + klassOop k = find_well_known_klass(class_name()); + if (k != NULL) { + return k; + } + } + // Double-check, if child class is already loaded, just return super-class,interface // Don't add a placedholder if already loaded, i.e. already in system dictionary // Make sure there's a placeholder for the *child* before resolving. @@ -919,6 +866,15 @@ TRAPS) { klassOop k = NULL; assert(class_name() != NULL, "class name must be non NULL"); + + // Try to get one of the well-known klasses. + if (LinkWellKnownClasses) { + k = find_well_known_klass(class_name()); + if (k != NULL) { + return k; + } + } + if (FieldType::is_array(class_name())) { // The name refers to an array. Parse the name. jint dimension; @@ -942,6 +898,38 @@ return k; } +// Quick range check for names of well-known classes: +static symbolOop wk_klass_name_limits[2] = {NULL, NULL}; + +#ifndef PRODUCT +static int find_wkk_calls, find_wkk_probes, find_wkk_wins; +// counts for "hello world": 3983, 1616, 1075 +// => 60% hit after limit guard, 25% total win rate +#endif + +klassOop SystemDictionary::find_well_known_klass(symbolOop class_name) { + // A bounds-check on class_name will quickly get a negative result. + NOT_PRODUCT(find_wkk_calls++); + if (class_name >= wk_klass_name_limits[0] && + class_name <= wk_klass_name_limits[1]) { + NOT_PRODUCT(find_wkk_probes++); + vmSymbols::SID sid = vmSymbols::find_sid(class_name); + if (sid != vmSymbols::NO_SID) { + klassOop k = NULL; + switch (sid) { + #define WK_KLASS_CASE(name, symbol, ignore_option) \ + case vmSymbols::VM_SYMBOL_ENUM_NAME(symbol): \ + k = WK_KLASS(name); break; + WK_KLASSES_DO(WK_KLASS_CASE) + #undef WK_KLASS_CASE + } + NOT_PRODUCT(if (k != NULL) find_wkk_wins++); + return k; + } + } + return NULL; +} + // Note: this method is much like resolve_from_stream, but // updates no supplemental data structures. // TODO consolidate the two methods with a helper routine? @@ -1684,71 +1672,13 @@ void SystemDictionary::preloaded_oops_do(OopClosure* f) { - f->do_oop((oop*) &_string_klass); - f->do_oop((oop*) &_object_klass); - f->do_oop((oop*) &_class_klass); - f->do_oop((oop*) &_cloneable_klass); - f->do_oop((oop*) &_classloader_klass); - f->do_oop((oop*) &_serializable_klass); - f->do_oop((oop*) &_system_klass); - - f->do_oop((oop*) &_throwable_klass); - f->do_oop((oop*) &_error_klass); - f->do_oop((oop*) &_threaddeath_klass); - f->do_oop((oop*) &_exception_klass); - f->do_oop((oop*) &_runtime_exception_klass); - f->do_oop((oop*) &_classNotFoundException_klass); - f->do_oop((oop*) &_noClassDefFoundError_klass); - f->do_oop((oop*) &_linkageError_klass); - f->do_oop((oop*) &_classCastException_klass); - f->do_oop((oop*) &_arrayStoreException_klass); - f->do_oop((oop*) &_virtualMachineError_klass); - f->do_oop((oop*) &_outOfMemoryError_klass); - f->do_oop((oop*) &_StackOverflowError_klass); - f->do_oop((oop*) &_illegalMonitorStateException_klass); - f->do_oop((oop*) &_protectionDomain_klass); - f->do_oop((oop*) &_AccessControlContext_klass); - - f->do_oop((oop*) &_reference_klass); - f->do_oop((oop*) &_soft_reference_klass); - f->do_oop((oop*) &_weak_reference_klass); - f->do_oop((oop*) &_final_reference_klass); - f->do_oop((oop*) &_phantom_reference_klass); - f->do_oop((oop*) &_finalizer_klass); + f->do_oop((oop*) &wk_klass_name_limits[0]); + f->do_oop((oop*) &wk_klass_name_limits[1]); - f->do_oop((oop*) &_thread_klass); - f->do_oop((oop*) &_threadGroup_klass); - f->do_oop((oop*) &_properties_klass); - f->do_oop((oop*) &_reflect_accessible_object_klass); - f->do_oop((oop*) &_reflect_field_klass); - f->do_oop((oop*) &_reflect_method_klass); - f->do_oop((oop*) &_reflect_constructor_klass); - f->do_oop((oop*) &_reflect_magic_klass); - f->do_oop((oop*) &_reflect_method_accessor_klass); - f->do_oop((oop*) &_reflect_constructor_accessor_klass); - f->do_oop((oop*) &_reflect_delegating_classloader_klass); - f->do_oop((oop*) &_reflect_constant_pool_klass); - f->do_oop((oop*) &_reflect_unsafe_static_field_accessor_impl_klass); + for (int k = (int)FIRST_WKID; k < (int)WKID_LIMIT; k++) { + f->do_oop((oop*) &_well_known_klasses[k]); + } - f->do_oop((oop*) &_stringBuffer_klass); - f->do_oop((oop*) &_vector_klass); - f->do_oop((oop*) &_hashtable_klass); - - f->do_oop((oop*) &_stackTraceElement_klass); - - f->do_oop((oop*) &_java_nio_Buffer_klass); - - f->do_oop((oop*) &_sun_misc_AtomicLongCSImpl_klass); - f->do_oop((oop*) &_sun_jkernel_DownloadManager_klass); - - f->do_oop((oop*) &_boolean_klass); - f->do_oop((oop*) &_char_klass); - f->do_oop((oop*) &_float_klass); - f->do_oop((oop*) &_double_klass); - f->do_oop((oop*) &_byte_klass); - f->do_oop((oop*) &_short_klass); - f->do_oop((oop*) &_int_klass); - f->do_oop((oop*) &_long_klass); { for (int i = 0; i < T_VOID+1; i++) { if (_box_klasses[i] != NULL) { @@ -1841,14 +1771,72 @@ initialize_preloaded_classes(CHECK); } +// Compact table of directions on the initialization of klasses: +static const short wk_init_info[] = { + #define WK_KLASS_INIT_INFO(name, symbol, option) \ + ( ((int)vmSymbols::VM_SYMBOL_ENUM_NAME(symbol) \ + << SystemDictionary::CEIL_LG_OPTION_LIMIT) \ + | (int)SystemDictionary::option ), + WK_KLASSES_DO(WK_KLASS_INIT_INFO) + #undef WK_KLASS_INIT_INFO + 0 +}; + +bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) { + assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob"); + int info = wk_init_info[id - FIRST_WKID]; + int sid = (info >> CEIL_LG_OPTION_LIMIT); + symbolHandle symbol = vmSymbolHandles::symbol_handle_at((vmSymbols::SID)sid); + klassOop* klassp = &_well_known_klasses[id]; + bool must_load = (init_opt < SystemDictionary::Opt); + bool try_load = true; + if (init_opt == SystemDictionary::Opt_Kernel) { +#ifndef KERNEL + try_load = false; +#endif //KERNEL + } + if ((*klassp) == NULL && try_load) { + if (must_load) { + (*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class + } else { + (*klassp) = resolve_or_null(symbol, CHECK_0); // load optional klass + } + } + return ((*klassp) != NULL); +} + +void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS) { + assert((int)start_id <= (int)limit_id, "IDs are out of order!"); + for (int id = (int)start_id; id < (int)limit_id; id++) { + assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob"); + int info = wk_init_info[id - FIRST_WKID]; + int sid = (info >> CEIL_LG_OPTION_LIMIT); + int opt = (info & right_n_bits(CEIL_LG_OPTION_LIMIT)); + + initialize_wk_klass((WKID)id, opt, CHECK); + + // Update limits, so find_well_known_klass can be very fast: + symbolOop s = vmSymbols::symbol_at((vmSymbols::SID)sid); + if (wk_klass_name_limits[1] == NULL) { + wk_klass_name_limits[0] = wk_klass_name_limits[1] = s; + } else if (wk_klass_name_limits[1] < s) { + wk_klass_name_limits[1] = s; + } else if (wk_klass_name_limits[0] > s) { + wk_klass_name_limits[0] = s; + } + } +} + void SystemDictionary::initialize_preloaded_classes(TRAPS) { - assert(_object_klass == NULL, "preloaded classes should only be initialized once"); + assert(WK_KLASS(object_klass) == NULL, "preloaded classes should only be initialized once"); // Preload commonly used klasses - _object_klass = resolve_or_fail(vmSymbolHandles::java_lang_Object(), true, CHECK); - _string_klass = resolve_or_fail(vmSymbolHandles::java_lang_String(), true, CHECK); - _class_klass = resolve_or_fail(vmSymbolHandles::java_lang_Class(), true, CHECK); - debug_only(instanceKlass::verify_class_klass_nonstatic_oop_maps(_class_klass)); + WKID scan = FIRST_WKID; + // first do Object, String, Class + initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(class_klass), scan, CHECK); + + debug_only(instanceKlass::verify_class_klass_nonstatic_oop_maps(WK_KLASS(class_klass))); + // Fixup mirrors for classes loaded before java.lang.Class. // These calls iterate over the objects currently in the perm gen // so calling them at this point is matters (not before when there @@ -1857,100 +1845,37 @@ Universe::initialize_basic_type_mirrors(CHECK); Universe::fixup_mirrors(CHECK); - _cloneable_klass = resolve_or_fail(vmSymbolHandles::java_lang_Cloneable(), true, CHECK); - _classloader_klass = resolve_or_fail(vmSymbolHandles::java_lang_ClassLoader(), true, CHECK); - _serializable_klass = resolve_or_fail(vmSymbolHandles::java_io_Serializable(), true, CHECK); - _system_klass = resolve_or_fail(vmSymbolHandles::java_lang_System(), true, CHECK); - - _throwable_klass = resolve_or_fail(vmSymbolHandles::java_lang_Throwable(), true, CHECK); - _error_klass = resolve_or_fail(vmSymbolHandles::java_lang_Error(), true, CHECK); - _threaddeath_klass = resolve_or_fail(vmSymbolHandles::java_lang_ThreadDeath(), true, CHECK); - _exception_klass = resolve_or_fail(vmSymbolHandles::java_lang_Exception(), true, CHECK); - _runtime_exception_klass = resolve_or_fail(vmSymbolHandles::java_lang_RuntimeException(), true, CHECK); - _protectionDomain_klass = resolve_or_fail(vmSymbolHandles::java_security_ProtectionDomain(), true, CHECK); - _AccessControlContext_klass = resolve_or_fail(vmSymbolHandles::java_security_AccessControlContext(), true, CHECK); - _classNotFoundException_klass = resolve_or_fail(vmSymbolHandles::java_lang_ClassNotFoundException(), true, CHECK); - _noClassDefFoundError_klass = resolve_or_fail(vmSymbolHandles::java_lang_NoClassDefFoundError(), true, CHECK); - _linkageError_klass = resolve_or_fail(vmSymbolHandles::java_lang_LinkageError(), true, CHECK); - _classCastException_klass = resolve_or_fail(vmSymbolHandles::java_lang_ClassCastException(), true, CHECK); - _arrayStoreException_klass = resolve_or_fail(vmSymbolHandles::java_lang_ArrayStoreException(), true, CHECK); - _virtualMachineError_klass = resolve_or_fail(vmSymbolHandles::java_lang_VirtualMachineError(), true, CHECK); - _outOfMemoryError_klass = resolve_or_fail(vmSymbolHandles::java_lang_OutOfMemoryError(), true, CHECK); - _StackOverflowError_klass = resolve_or_fail(vmSymbolHandles::java_lang_StackOverflowError(), true, CHECK); - _illegalMonitorStateException_klass = resolve_or_fail(vmSymbolHandles::java_lang_IllegalMonitorStateException(), true, CHECK); + // do a bunch more: + initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(reference_klass), scan, CHECK); // Preload ref klasses and set reference types - _reference_klass = resolve_or_fail(vmSymbolHandles::java_lang_ref_Reference(), true, CHECK); - instanceKlass::cast(_reference_klass)->set_reference_type(REF_OTHER); - instanceRefKlass::update_nonstatic_oop_maps(_reference_klass); + instanceKlass::cast(WK_KLASS(reference_klass))->set_reference_type(REF_OTHER); + instanceRefKlass::update_nonstatic_oop_maps(WK_KLASS(reference_klass)); - _soft_reference_klass = resolve_or_fail(vmSymbolHandles::java_lang_ref_SoftReference(), true, CHECK); - instanceKlass::cast(_soft_reference_klass)->set_reference_type(REF_SOFT); - _weak_reference_klass = resolve_or_fail(vmSymbolHandles::java_lang_ref_WeakReference(), true, CHECK); - instanceKlass::cast(_weak_reference_klass)->set_reference_type(REF_WEAK); - _final_reference_klass = resolve_or_fail(vmSymbolHandles::java_lang_ref_FinalReference(), true, CHECK); - instanceKlass::cast(_final_reference_klass)->set_reference_type(REF_FINAL); - _phantom_reference_klass = resolve_or_fail(vmSymbolHandles::java_lang_ref_PhantomReference(), true, CHECK); - instanceKlass::cast(_phantom_reference_klass)->set_reference_type(REF_PHANTOM); - _finalizer_klass = resolve_or_fail(vmSymbolHandles::java_lang_ref_Finalizer(), true, CHECK); + initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(phantom_reference_klass), scan, CHECK); + instanceKlass::cast(WK_KLASS(soft_reference_klass))->set_reference_type(REF_SOFT); + instanceKlass::cast(WK_KLASS(weak_reference_klass))->set_reference_type(REF_WEAK); + instanceKlass::cast(WK_KLASS(final_reference_klass))->set_reference_type(REF_FINAL); + instanceKlass::cast(WK_KLASS(phantom_reference_klass))->set_reference_type(REF_PHANTOM); + + initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK); - _thread_klass = resolve_or_fail(vmSymbolHandles::java_lang_Thread(), true, CHECK); - _threadGroup_klass = resolve_or_fail(vmSymbolHandles::java_lang_ThreadGroup(), true, CHECK); - _properties_klass = resolve_or_fail(vmSymbolHandles::java_util_Properties(), true, CHECK); - _reflect_accessible_object_klass = resolve_or_fail(vmSymbolHandles::java_lang_reflect_AccessibleObject(), true, CHECK); - _reflect_field_klass = resolve_or_fail(vmSymbolHandles::java_lang_reflect_Field(), true, CHECK); - _reflect_method_klass = resolve_or_fail(vmSymbolHandles::java_lang_reflect_Method(), true, CHECK); - _reflect_constructor_klass = resolve_or_fail(vmSymbolHandles::java_lang_reflect_Constructor(), true, CHECK); - // Universe::is_gte_jdk14x_version() is not set up by this point. - // It's okay if these turn out to be NULL in non-1.4 JDKs. - _reflect_magic_klass = resolve_or_null(vmSymbolHandles::sun_reflect_MagicAccessorImpl(), CHECK); - _reflect_method_accessor_klass = resolve_or_null(vmSymbolHandles::sun_reflect_MethodAccessorImpl(), CHECK); - _reflect_constructor_accessor_klass = resolve_or_null(vmSymbolHandles::sun_reflect_ConstructorAccessorImpl(), CHECK); - _reflect_delegating_classloader_klass = resolve_or_null(vmSymbolHandles::sun_reflect_DelegatingClassLoader(), CHECK); - _reflect_constant_pool_klass = resolve_or_null(vmSymbolHandles::sun_reflect_ConstantPool(), CHECK); - _reflect_unsafe_static_field_accessor_impl_klass = resolve_or_null(vmSymbolHandles::sun_reflect_UnsafeStaticFieldAccessorImpl(), CHECK); + _box_klasses[T_BOOLEAN] = WK_KLASS(boolean_klass); + _box_klasses[T_CHAR] = WK_KLASS(char_klass); + _box_klasses[T_FLOAT] = WK_KLASS(float_klass); + _box_klasses[T_DOUBLE] = WK_KLASS(double_klass); + _box_klasses[T_BYTE] = WK_KLASS(byte_klass); + _box_klasses[T_SHORT] = WK_KLASS(short_klass); + _box_klasses[T_INT] = WK_KLASS(int_klass); + _box_klasses[T_LONG] = WK_KLASS(long_klass); + //_box_klasses[T_OBJECT] = WK_KLASS(object_klass); + //_box_klasses[T_ARRAY] = WK_KLASS(object_klass); - _vector_klass = resolve_or_fail(vmSymbolHandles::java_util_Vector(), true, CHECK); - _hashtable_klass = resolve_or_fail(vmSymbolHandles::java_util_Hashtable(), true, CHECK); - _stringBuffer_klass = resolve_or_fail(vmSymbolHandles::java_lang_StringBuffer(), true, CHECK); - - // It's NULL in non-1.4 JDKs. - _stackTraceElement_klass = resolve_or_null(vmSymbolHandles::java_lang_StackTraceElement(), CHECK); - - // Universe::is_gte_jdk14x_version() is not set up by this point. - // It's okay if this turns out to be NULL in non-1.4 JDKs. - _java_nio_Buffer_klass = resolve_or_null(vmSymbolHandles::java_nio_Buffer(), CHECK); - - // If this class isn't present, it won't be referenced. - _sun_misc_AtomicLongCSImpl_klass = resolve_or_null(vmSymbolHandles::sun_misc_AtomicLongCSImpl(), CHECK); #ifdef KERNEL - _sun_jkernel_DownloadManager_klass = resolve_or_null(vmSymbolHandles::sun_jkernel_DownloadManager(), CHECK); - if (_sun_jkernel_DownloadManager_klass == NULL) { + if (sun_jkernel_DownloadManager_klass() == NULL) { warning("Cannot find sun/jkernel/DownloadManager"); } #endif // KERNEL - - // Preload boxing klasses - _boolean_klass = resolve_or_fail(vmSymbolHandles::java_lang_Boolean(), true, CHECK); - _char_klass = resolve_or_fail(vmSymbolHandles::java_lang_Character(), true, CHECK); - _float_klass = resolve_or_fail(vmSymbolHandles::java_lang_Float(), true, CHECK); - _double_klass = resolve_or_fail(vmSymbolHandles::java_lang_Double(), true, CHECK); - _byte_klass = resolve_or_fail(vmSymbolHandles::java_lang_Byte(), true, CHECK); - _short_klass = resolve_or_fail(vmSymbolHandles::java_lang_Short(), true, CHECK); - _int_klass = resolve_or_fail(vmSymbolHandles::java_lang_Integer(), true, CHECK); - _long_klass = resolve_or_fail(vmSymbolHandles::java_lang_Long(), true, CHECK); - - _box_klasses[T_BOOLEAN] = _boolean_klass; - _box_klasses[T_CHAR] = _char_klass; - _box_klasses[T_FLOAT] = _float_klass; - _box_klasses[T_DOUBLE] = _double_klass; - _box_klasses[T_BYTE] = _byte_klass; - _box_klasses[T_SHORT] = _short_klass; - _box_klasses[T_INT] = _int_klass; - _box_klasses[T_LONG] = _long_klass; - //_box_klasses[T_OBJECT] = _object_klass; - //_box_klasses[T_ARRAY] = _object_klass; - { // Compute whether we should use loadClass or loadClassInternal when loading classes. methodOop method = instanceKlass::cast(classloader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature()); _has_loadClassInternal = (method != NULL); diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri May 02 08:22:11 2008 -0700 @@ -64,12 +64,133 @@ class HashtableBucket; class ResolutionErrorTable; +// Certain classes are preloaded, such as java.lang.Object and java.lang.String. +// They are all "well-known", in the sense that no class loader is allowed +// to provide a different definition. +// +// These klasses must all have names defined in vmSymbols. + +#define WK_KLASS_ENUM_NAME(kname) kname##_knum + +// Each well-known class has a short klass name (like object_klass), +// a vmSymbol name (like java_lang_Object), and a flag word +// that makes some minor distinctions, like whether the klass +// is preloaded, optional, release-specific, etc. +// The order of these definitions is significant; it is the order in which +// preloading is actually performed by initialize_preloaded_classes. + +#define WK_KLASSES_DO(template) \ + /* well-known classes */ \ + template(object_klass, java_lang_Object, Pre) \ + template(string_klass, java_lang_String, Pre) \ + template(class_klass, java_lang_Class, Pre) \ + template(cloneable_klass, java_lang_Cloneable, Pre) \ + template(classloader_klass, java_lang_ClassLoader, Pre) \ + template(serializable_klass, java_io_Serializable, Pre) \ + template(system_klass, java_lang_System, Pre) \ + template(throwable_klass, java_lang_Throwable, Pre) \ + template(error_klass, java_lang_Error, Pre) \ + template(threaddeath_klass, java_lang_ThreadDeath, Pre) \ + template(exception_klass, java_lang_Exception, Pre) \ + template(runtime_exception_klass, java_lang_RuntimeException, Pre) \ + template(protectionDomain_klass, java_security_ProtectionDomain, Pre) \ + template(AccessControlContext_klass, java_security_AccessControlContext, Pre) \ + template(classNotFoundException_klass, java_lang_ClassNotFoundException, Pre) \ + template(noClassDefFoundError_klass, java_lang_NoClassDefFoundError, Pre) \ + template(linkageError_klass, java_lang_LinkageError, Pre) \ + template(ClassCastException_klass, java_lang_ClassCastException, Pre) \ + template(ArrayStoreException_klass, java_lang_ArrayStoreException, Pre) \ + template(virtualMachineError_klass, java_lang_VirtualMachineError, Pre) \ + template(OutOfMemoryError_klass, java_lang_OutOfMemoryError, Pre) \ + template(StackOverflowError_klass, java_lang_StackOverflowError, Pre) \ + template(IllegalMonitorStateException_klass, java_lang_IllegalMonitorStateException, Pre) \ + template(reference_klass, java_lang_ref_Reference, Pre) \ + \ + /* Preload ref klasses and set reference types */ \ + template(soft_reference_klass, java_lang_ref_SoftReference, Pre) \ + template(weak_reference_klass, java_lang_ref_WeakReference, Pre) \ + template(final_reference_klass, java_lang_ref_FinalReference, Pre) \ + template(phantom_reference_klass, java_lang_ref_PhantomReference, Pre) \ + template(finalizer_klass, java_lang_ref_Finalizer, Pre) \ + \ + template(thread_klass, java_lang_Thread, Pre) \ + template(threadGroup_klass, java_lang_ThreadGroup, Pre) \ + template(properties_klass, java_util_Properties, Pre) \ + template(reflect_accessible_object_klass, java_lang_reflect_AccessibleObject, Pre) \ + template(reflect_field_klass, java_lang_reflect_Field, Pre) \ + template(reflect_method_klass, java_lang_reflect_Method, Pre) \ + template(reflect_constructor_klass, java_lang_reflect_Constructor, Pre) \ + \ + /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \ + /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \ + /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \ + template(reflect_magic_klass, sun_reflect_MagicAccessorImpl, Opt) \ + template(reflect_method_accessor_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \ + template(reflect_constructor_accessor_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \ + template(reflect_delegating_classloader_klass, sun_reflect_DelegatingClassLoader, Opt) \ + template(reflect_constant_pool_klass, sun_reflect_ConstantPool, Opt_Only_JDK15) \ + template(reflect_unsafe_static_field_accessor_impl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \ + \ + template(vector_klass, java_util_Vector, Pre) \ + template(hashtable_klass, java_util_Hashtable, Pre) \ + template(stringBuffer_klass, java_lang_StringBuffer, Pre) \ + \ + /* It's NULL in non-1.4 JDKs. */ \ + template(stackTraceElement_klass, java_lang_StackTraceElement, Opt) \ + /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \ + /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \ + template(java_nio_Buffer_klass, java_nio_Buffer, Opt) \ + \ + /* If this class isn't present, it won't be referenced. */ \ + template(sun_misc_AtomicLongCSImpl_klass, sun_misc_AtomicLongCSImpl, Opt) \ + \ + template(sun_jkernel_DownloadManager_klass, sun_jkernel_DownloadManager, Opt_Kernel) \ + \ + /* Preload boxing klasses */ \ + template(boolean_klass, java_lang_Boolean, Pre) \ + template(char_klass, java_lang_Character, Pre) \ + template(float_klass, java_lang_Float, Pre) \ + template(double_klass, java_lang_Double, Pre) \ + template(byte_klass, java_lang_Byte, Pre) \ + template(short_klass, java_lang_Short, Pre) \ + template(int_klass, java_lang_Integer, Pre) \ + template(long_klass, java_lang_Long, Pre) \ + /*end*/ + + class SystemDictionary : AllStatic { friend class VMStructs; friend class CompactingPermGenGen; NOT_PRODUCT(friend class instanceKlassKlass;) public: + enum WKID { + NO_WKID = 0, + + #define WK_KLASS_ENUM(name, ignore_s, ignore_o) WK_KLASS_ENUM_NAME(name), + WK_KLASSES_DO(WK_KLASS_ENUM) + #undef WK_KLASS_ENUM + + WKID_LIMIT, + + FIRST_WKID = NO_WKID + 1 + }; + + enum InitOption { + Pre, // preloaded; error if not present + + // Order is significant. Options before this point require resolve_or_fail. + // Options after this point will use resolve_or_null instead. + + Opt, // preload tried; NULL if not present + Opt_Only_JDK14NewRef, // preload tried; use only with NewReflection + Opt_Only_JDK15, // preload tried; use only with JDK1.5+ + Opt_Kernel, // preload tried only #ifdef KERNEL + OPTION_LIMIT, + CEIL_LG_OPTION_LIMIT = 4 // OPTION_LIMIT <= (1<eqv( in(1), in(2) ) && t1->base() == Type::FloatCon) if (!g_isnan(t1->getf()) && g_isfinite(t1->getf()) && t1->getf() != 0.0) // could be negative ZERO or NaN return TypeF::ONE; @@ -491,7 +491,7 @@ //============================================================================= //------------------------------Value------------------------------------------ // An DivDNode divides its inputs. The third input is a Control input, used to -// prvent hoisting the divide above an unsafe test. +// prevent hoisting the divide above an unsafe test. const Type *DivDNode::Value( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP const Type *t1 = phase->type( in(1) ); @@ -872,56 +872,32 @@ (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) return bot; - // If either is a NaN, return an input NaN - if( g_isnan(t1->getf()) ) return t1; - if( g_isnan(t2->getf()) ) return t2; - - // It is not worth trying to constant fold this stuff! - return Type::FLOAT; - - /* - // If dividend is infinity or divisor is zero, or both, the result is NaN - if( !g_isfinite(t1->getf()) || ((t2->getf() == 0.0) || (jint_cast(t2->getf()) == 0x80000000)) ) + // If either number is not a constant, we know nothing. + if ((t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon)) { + return Type::FLOAT; // note: x%x can be either NaN or 0 + } - // X MOD infinity = X - if( !g_isfinite(t2->getf()) && !g_isnan(t2->getf()) ) return t1; - // 0 MOD finite = dividend (positive or negative zero) - // Not valid for: NaN MOD any; any MOD nan; 0 MOD 0; or for 0 MOD NaN - // NaNs are handled previously. - if( !(t2->getf() == 0.0) && !((int)t2->getf() == 0x80000000)) { - if (((t1->getf() == 0.0) || ((int)t1->getf() == 0x80000000)) && g_isfinite(t2->getf()) ) { - return t1; - } - } - // X MOD X is 0 - // Does not work for variables because of NaN's - if( phase->eqv( in(1), in(2) ) && t1->base() == Type::FloatCon) - if (!g_isnan(t1->getf()) && (t1->getf() != 0.0) && ((int)t1->getf() != 0x80000000)) { - if(t1->getf() < 0.0) { - float result = jfloat_cast(0x80000000); - return TypeF::make( result ); - } - else - return TypeF::ZERO; - } + float f1 = t1->getf(); + float f2 = t2->getf(); + jint x1 = jint_cast(f1); // note: *(int*)&f1, not just (int)f1 + jint x2 = jint_cast(f2); - // If both numbers are not constants, we know nothing. - if( (t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon) ) + // If either is a NaN, return an input NaN + if (g_isnan(f1)) return t1; + if (g_isnan(f2)) return t2; + + // If an operand is infinity or the divisor is +/- zero, punt. + if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jint) return Type::FLOAT; // We must be modulo'ing 2 float constants. // Make sure that the sign of the fmod is equal to the sign of the dividend - float result = (float)fmod( t1->getf(), t2->getf() ); - float dividend = t1->getf(); - if( (dividend < 0.0) || ((int)dividend == 0x80000000) ) { - if( result > 0.0 ) - result = 0.0 - result; - else if( result == 0.0 ) { - result = jfloat_cast(0x80000000); - } + jint xr = jint_cast(fmod(f1, f2)); + if ((x1 ^ xr) < 0) { + xr ^= min_jint; } - return TypeF::make( result ); - */ + + return TypeF::make(jfloat_cast(xr)); } @@ -940,33 +916,32 @@ (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) return bot; - // If either is a NaN, return an input NaN - if( g_isnan(t1->getd()) ) return t1; - if( g_isnan(t2->getd()) ) return t2; - // X MOD infinity = X - if( !g_isfinite(t2->getd())) return t1; - // 0 MOD finite = dividend (positive or negative zero) - // Not valid for: NaN MOD any; any MOD nan; 0 MOD 0; or for 0 MOD NaN - // NaNs are handled previously. - if( !(t2->getd() == 0.0) ) { - if( t1->getd() == 0.0 && g_isfinite(t2->getd()) ) { - return t1; - } + // If either number is not a constant, we know nothing. + if ((t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon)) { + return Type::DOUBLE; // note: x%x can be either NaN or 0 } - // X MOD X is 0 - // does not work for variables because of NaN's - if( phase->eqv( in(1), in(2) ) && t1->base() == Type::DoubleCon ) - if (!g_isnan(t1->getd()) && t1->getd() != 0.0) - return TypeD::ZERO; + double f1 = t1->getd(); + double f2 = t2->getd(); + jlong x1 = jlong_cast(f1); // note: *(long*)&f1, not just (long)f1 + jlong x2 = jlong_cast(f2); + // If either is a NaN, return an input NaN + if (g_isnan(f1)) return t1; + if (g_isnan(f2)) return t2; - // If both numbers are not constants, we know nothing. - if( (t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon) ) + // If an operand is infinity or the divisor is +/- zero, punt. + if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) return Type::DOUBLE; // We must be modulo'ing 2 double constants. - return TypeD::make( fmod( t1->getd(), t2->getd() ) ); + // Make sure that the sign of the fmod is equal to the sign of the dividend + jlong xr = jlong_cast(fmod(f1, f2)); + if ((x1 ^ xr) < 0) { + xr ^= min_jlong; + } + + return TypeD::make(jdouble_cast(xr)); } //============================================================================= diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/opto/parse2.cpp --- a/src/share/vm/opto/parse2.cpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/opto/parse2.cpp Fri May 02 08:22:11 2008 -0700 @@ -105,10 +105,19 @@ if (GenerateRangeChecks && need_range_check) { // Range is constant in array-oop, so we can use the original state of mem Node* len = load_array_length(ary); - // Test length vs index (standard trick using unsigned compare) - Node* chk = _gvn.transform( new (C, 3) CmpUNode(idx, len) ); - BoolTest::mask btest = BoolTest::lt; - Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, btest) ); + Node* tst; + if (sizetype->_hi <= 0) { + // If the greatest array bound is negative, we can conclude that we're + // compiling unreachable code, but the unsigned compare trick used below + // only works with non-negative lengths. Instead, hack "tst" to be zero so + // the uncommon_trap path will always be taken. + tst = _gvn.intcon(0); + } else { + // Test length vs index (standard trick using unsigned compare) + Node* chk = _gvn.transform( new (C, 3) CmpUNode(idx, len) ); + BoolTest::mask btest = BoolTest::lt; + tst = _gvn.transform( new (C, 2) BoolNode(chk, btest) ); + } // Branch to failure if out of bounds { BuildCutout unless(this, tst, PROB_MAX); if (C->allow_range_check_smearing()) { diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/runtime/globals.hpp Fri May 02 08:22:11 2008 -0700 @@ -779,6 +779,9 @@ product(bool, ClassUnloading, true, \ "Do unloading of classes") \ \ + diagnostic(bool, LinkWellKnownClasses, true, \ + "Resolve a well known class as soon as its name is seen") \ + \ develop(bool, DisableStartThread, false, \ "Disable starting of additional Java threads " \ "(for debugging only)") \ diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/runtime/vmStructs.cpp Fri May 02 08:22:11 2008 -0700 @@ -453,40 +453,7 @@ static_field(SystemDictionary, _shared_dictionary, Dictionary*) \ static_field(SystemDictionary, _system_loader_lock_obj, oop) \ static_field(SystemDictionary, _loader_constraints, LoaderConstraintTable*) \ - static_field(SystemDictionary, _object_klass, klassOop) \ - static_field(SystemDictionary, _string_klass, klassOop) \ - static_field(SystemDictionary, _class_klass, klassOop) \ - static_field(SystemDictionary, _cloneable_klass, klassOop) \ - static_field(SystemDictionary, _classloader_klass, klassOop) \ - static_field(SystemDictionary, _serializable_klass, klassOop) \ - static_field(SystemDictionary, _system_klass, klassOop) \ - static_field(SystemDictionary, _throwable_klass, klassOop) \ - static_field(SystemDictionary, _threaddeath_klass, klassOop) \ - static_field(SystemDictionary, _error_klass, klassOop) \ - static_field(SystemDictionary, _exception_klass, klassOop) \ - static_field(SystemDictionary, _runtime_exception_klass, klassOop) \ - static_field(SystemDictionary, _classNotFoundException_klass, klassOop) \ - static_field(SystemDictionary, _noClassDefFoundError_klass, klassOop) \ - static_field(SystemDictionary, _linkageError_klass, klassOop) \ - static_field(SystemDictionary, _classCastException_klass, klassOop) \ - static_field(SystemDictionary, _arrayStoreException_klass, klassOop) \ - static_field(SystemDictionary, _virtualMachineError_klass, klassOop) \ - static_field(SystemDictionary, _outOfMemoryError_klass, klassOop) \ - static_field(SystemDictionary, _StackOverflowError_klass, klassOop) \ - static_field(SystemDictionary, _protectionDomain_klass, klassOop) \ - static_field(SystemDictionary, _AccessControlContext_klass, klassOop) \ - static_field(SystemDictionary, _reference_klass, klassOop) \ - static_field(SystemDictionary, _soft_reference_klass, klassOop) \ - static_field(SystemDictionary, _weak_reference_klass, klassOop) \ - static_field(SystemDictionary, _final_reference_klass, klassOop) \ - static_field(SystemDictionary, _phantom_reference_klass, klassOop) \ - static_field(SystemDictionary, _finalizer_klass, klassOop) \ - static_field(SystemDictionary, _thread_klass, klassOop) \ - static_field(SystemDictionary, _threadGroup_klass, klassOop) \ - static_field(SystemDictionary, _properties_klass, klassOop) \ - static_field(SystemDictionary, _stringBuffer_klass, klassOop) \ - static_field(SystemDictionary, _vector_klass, klassOop) \ - static_field(SystemDictionary, _hashtable_klass, klassOop) \ + static_field(SystemDictionary, _well_known_klasses[0], klassOop) \ static_field(SystemDictionary, _box_klasses[0], klassOop) \ static_field(SystemDictionary, _java_system_loader, oop) \ \ @@ -1400,6 +1367,13 @@ \ declare_constant(SystemDictionary::_loader_constraint_size) \ declare_constant(SystemDictionary::_nof_buckets) \ + /* these #foo numbers are enums used to index _well_known_klasses: */ \ + declare_preprocessor_constant("SystemDictionary::#object_klass", SystemDictionary::WK_KLASS_ENUM_NAME(object_klass)) \ + declare_preprocessor_constant("SystemDictionary::#classloader_klass", SystemDictionary::WK_KLASS_ENUM_NAME(classloader_klass)) \ + declare_preprocessor_constant("SystemDictionary::#string_klass", SystemDictionary::WK_KLASS_ENUM_NAME(string_klass)) \ + declare_preprocessor_constant("SystemDictionary::#system_klass", SystemDictionary::WK_KLASS_ENUM_NAME(system_klass)) \ + declare_preprocessor_constant("SystemDictionary::#thread_klass", SystemDictionary::WK_KLASS_ENUM_NAME(thread_klass)) \ + declare_preprocessor_constant("SystemDictionary::#threadGroup_klass", SystemDictionary::WK_KLASS_ENUM_NAME(threadGroup_klass)) \ \ /***********************************/ \ /* LoaderConstraintTable constants */ \ diff -r 53735b80b9f1 -r bcdc68eb7e1f src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Thu May 01 09:38:23 2008 -0400 +++ b/src/share/vm/services/threadService.cpp Fri May 02 08:22:11 2008 -0700 @@ -541,6 +541,7 @@ Handle ThreadStackTrace::allocate_fill_stack_trace_element_array(TRAPS) { klassOop k = SystemDictionary::stackTraceElement_klass(); + assert(k != NULL, "must be loaded in 1.4+"); instanceKlassHandle ik(THREAD, k); // Allocate an array of java/lang/StackTraceElement object diff -r 53735b80b9f1 -r bcdc68eb7e1f test/compiler/6646019/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6646019/Test.java Fri May 02 08:22:11 2008 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * @test + * @bug 6646019 + * @summary array subscript expressions become top() with -d64 + * @run main/othervm -Xcomp -XX:CompileOnly=Test.test Test +*/ + + +public class Test { + final static int i = 2076285318; + long l = 2; + short s; + + public static void main(String[] args) { + Test t = new Test(); + try { t.test(); } + catch (Throwable e) { + if (t.l != 5) { + System.out.println("Fails: " + t.l + " != 5"); + } + } + } + + private void test() { + l = 5; + l = (new short[(byte)-2])[(byte)(l = i)]; + } +}