--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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() {
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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");
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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();
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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);
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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<<CEIL_LG_OPTION_LIMIT)
+ };
+
+
// Returns a class with a given class name and class loader. Loads the
// class if needed. If not found a NoClassDefFoundError or a
// ClassNotFoundException is thrown, depending on the value on the
@@ -123,6 +244,9 @@
Handle protection_domain,
TRAPS);
+ // If the given name is known to vmSymbols, return the well-know klass:
+ static klassOop find_well_known_klass(symbolOop class_name);
+
// Lookup an instance or array class that has already been loaded
// either into the given class loader, or else into another class
// loader that is constrained (via loader constraints) to produce
@@ -235,85 +359,34 @@
return k;
}
-public:
- static klassOop object_klass() { return check_klass(_object_klass); }
- static klassOop string_klass() { return check_klass(_string_klass); }
- static klassOop class_klass() { return check_klass(_class_klass); }
- static klassOop cloneable_klass() { return check_klass(_cloneable_klass); }
- static klassOop classloader_klass() { return check_klass(_classloader_klass); }
- static klassOop serializable_klass() { return check_klass(_serializable_klass); }
- static klassOop system_klass() { return check_klass(_system_klass); }
-
- static klassOop throwable_klass() { return check_klass(_throwable_klass); }
- static klassOop error_klass() { return check_klass(_error_klass); }
- static klassOop threaddeath_klass() { return check_klass(_threaddeath_klass); }
- static klassOop exception_klass() { return check_klass(_exception_klass); }
- static klassOop runtime_exception_klass() { return check_klass(_runtime_exception_klass); }
- static klassOop classNotFoundException_klass() { return check_klass(_classNotFoundException_klass); }
- static klassOop noClassDefFoundError_klass() { return check_klass(_noClassDefFoundError_klass); }
- static klassOop linkageError_klass() { return check_klass(_linkageError_klass); }
- static klassOop ClassCastException_klass() { return check_klass(_classCastException_klass); }
- static klassOop ArrayStoreException_klass() { return check_klass(_arrayStoreException_klass); }
- static klassOop virtualMachineError_klass() { return check_klass(_virtualMachineError_klass); }
- static klassOop OutOfMemoryError_klass() { return check_klass(_outOfMemoryError_klass); }
- static klassOop StackOverflowError_klass() { return check_klass(_StackOverflowError_klass); }
- static klassOop IllegalMonitorStateException_klass() { return check_klass(_illegalMonitorStateException_klass); }
- static klassOop protectionDomain_klass() { return check_klass(_protectionDomain_klass); }
- static klassOop AccessControlContext_klass() { return check_klass(_AccessControlContext_klass); }
- static klassOop reference_klass() { return check_klass(_reference_klass); }
- static klassOop soft_reference_klass() { return check_klass(_soft_reference_klass); }
- static klassOop weak_reference_klass() { return check_klass(_weak_reference_klass); }
- static klassOop final_reference_klass() { return check_klass(_final_reference_klass); }
- static klassOop phantom_reference_klass() { return check_klass(_phantom_reference_klass); }
- static klassOop finalizer_klass() { return check_klass(_finalizer_klass); }
-
- static klassOop thread_klass() { return check_klass(_thread_klass); }
- static klassOop threadGroup_klass() { return check_klass(_threadGroup_klass); }
- static klassOop properties_klass() { return check_klass(_properties_klass); }
- static klassOop reflect_accessible_object_klass() { return check_klass(_reflect_accessible_object_klass); }
- static klassOop reflect_field_klass() { return check_klass(_reflect_field_klass); }
- static klassOop reflect_method_klass() { return check_klass(_reflect_method_klass); }
- static klassOop reflect_constructor_klass() { return check_klass(_reflect_constructor_klass); }
- static klassOop reflect_method_accessor_klass() {
+ static klassOop check_klass_Pre(klassOop k) { return check_klass(k); }
+ static klassOop check_klass_Opt(klassOop k) { return k; }
+ static klassOop check_klass_Opt_Kernel(klassOop k) { return k; } //== Opt
+ static klassOop check_klass_Opt_Only_JDK15(klassOop k) {
+ assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
+ return k;
+ }
+ static klassOop check_klass_Opt_Only_JDK14NewRef(klassOop k) {
assert(JDK_Version::is_gte_jdk14x_version() && UseNewReflection, "JDK 1.4 only");
- return check_klass(_reflect_method_accessor_klass);
- }
- static klassOop reflect_constructor_accessor_klass() {
- assert(JDK_Version::is_gte_jdk14x_version() && UseNewReflection, "JDK 1.4 only");
- return check_klass(_reflect_constructor_accessor_klass);
- }
- // NOTE: needed too early in bootstrapping process to have checks based on JDK version
- static klassOop reflect_magic_klass() { return _reflect_magic_klass; }
- static klassOop reflect_delegating_classloader_klass() { return _reflect_delegating_classloader_klass; }
- static klassOop reflect_constant_pool_klass() {
- assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
- return _reflect_constant_pool_klass;
- }
- static klassOop reflect_unsafe_static_field_accessor_impl_klass() {
- assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
- return _reflect_unsafe_static_field_accessor_impl_klass;
+ // despite the optional loading, if you use this it must be present:
+ return check_klass(k);
}
- static klassOop vector_klass() { return check_klass(_vector_klass); }
- static klassOop hashtable_klass() { return check_klass(_hashtable_klass); }
- static klassOop stringBuffer_klass() { return check_klass(_stringBuffer_klass); }
- static klassOop stackTraceElement_klass() { return check_klass(_stackTraceElement_klass); }
-
- static klassOop java_nio_Buffer_klass() { return check_klass(_java_nio_Buffer_klass); }
-
- static klassOop sun_misc_AtomicLongCSImpl_klass() { return _sun_misc_AtomicLongCSImpl_klass; }
+ static bool initialize_wk_klass(WKID id, int init_opt, TRAPS);
+ static void initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS);
+ static void initialize_wk_klasses_through(WKID end_id, WKID &start_id, TRAPS) {
+ int limit = (int)end_id + 1;
+ initialize_wk_klasses_until((WKID) limit, start_id, THREAD);
+ }
- // To support incremental JRE downloads (KERNEL JRE). Null if not present.
- static klassOop sun_jkernel_DownloadManager_klass() { return _sun_jkernel_DownloadManager_klass; }
+public:
+ #define WK_KLASS_DECLARE(name, ignore_symbol, option) \
+ static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
+ WK_KLASSES_DO(WK_KLASS_DECLARE);
+ #undef WK_KLASS_DECLARE
- static klassOop boolean_klass() { return check_klass(_boolean_klass); }
- static klassOop char_klass() { return check_klass(_char_klass); }
- static klassOop float_klass() { return check_klass(_float_klass); }
- static klassOop double_klass() { return check_klass(_double_klass); }
- static klassOop byte_klass() { return check_klass(_byte_klass); }
- static klassOop short_klass() { return check_klass(_short_klass); }
- static klassOop int_klass() { return check_klass(_int_klass); }
- static klassOop long_klass() { return check_klass(_long_klass); }
+ // Local definition for direct access to the private array:
+ #define WK_KLASS(name) _well_known_klasses[WK_KLASS_ENUM_NAME(name)]
static klassOop box_klass(BasicType t) {
assert((uint)t < T_VOID+1, "range check");
@@ -335,8 +408,8 @@
// Tells whether ClassLoader.checkPackageAccess is present
static bool has_checkPackageAccess() { return _has_checkPackageAccess; }
- static bool class_klass_loaded() { return _class_klass != NULL; }
- static bool cloneable_klass_loaded() { return _cloneable_klass != NULL; }
+ static bool class_klass_loaded() { return WK_KLASS(class_klass) != NULL; }
+ static bool cloneable_klass_loaded() { return WK_KLASS(cloneable_klass) != NULL; }
// Returns default system loader
static oop java_system_loader();
@@ -498,80 +571,12 @@
instanceKlassHandle k, Handle loader, TRAPS);
// Variables holding commonly used klasses (preloaded)
- static klassOop _object_klass;
- static klassOop _string_klass;
- static klassOop _class_klass;
- static klassOop _cloneable_klass;
- static klassOop _classloader_klass;
- static klassOop _serializable_klass;
- static klassOop _system_klass;
-
- static klassOop _throwable_klass;
- static klassOop _error_klass;
- static klassOop _threaddeath_klass;
- static klassOop _exception_klass;
- static klassOop _runtime_exception_klass;
- static klassOop _classNotFoundException_klass;
- static klassOop _noClassDefFoundError_klass;
- static klassOop _linkageError_klass;
- static klassOop _classCastException_klass;
- static klassOop _arrayStoreException_klass;
- static klassOop _virtualMachineError_klass;
- static klassOop _outOfMemoryError_klass;
- static klassOop _StackOverflowError_klass;
- static klassOop _illegalMonitorStateException_klass;
- static klassOop _protectionDomain_klass;
- static klassOop _AccessControlContext_klass;
- static klassOop _reference_klass;
- static klassOop _soft_reference_klass;
- static klassOop _weak_reference_klass;
- static klassOop _final_reference_klass;
- static klassOop _phantom_reference_klass;
- static klassOop _finalizer_klass;
-
- static klassOop _thread_klass;
- static klassOop _threadGroup_klass;
- static klassOop _properties_klass;
- static klassOop _reflect_accessible_object_klass;
- static klassOop _reflect_field_klass;
- static klassOop _reflect_method_klass;
- static klassOop _reflect_constructor_klass;
- // 1.4 reflection implementation
- static klassOop _reflect_magic_klass;
- static klassOop _reflect_method_accessor_klass;
- static klassOop _reflect_constructor_accessor_klass;
- static klassOop _reflect_delegating_classloader_klass;
- // 1.5 annotations implementation
- static klassOop _reflect_constant_pool_klass;
- static klassOop _reflect_unsafe_static_field_accessor_impl_klass;
-
- static klassOop _stringBuffer_klass;
- static klassOop _vector_klass;
- static klassOop _hashtable_klass;
-
- static klassOop _stackTraceElement_klass;
-
- static klassOop _java_nio_Buffer_klass;
-
- static klassOop _sun_misc_AtomicLongCSImpl_klass;
-
- // KERNEL JRE support.
- static klassOop _sun_jkernel_DownloadManager_klass;
+ static klassOop _well_known_klasses[];
// Lazily loaded klasses
static volatile klassOop _abstract_ownable_synchronizer_klass;
- // Box klasses
- static klassOop _boolean_klass;
- static klassOop _char_klass;
- static klassOop _float_klass;
- static klassOop _double_klass;
- static klassOop _byte_klass;
- static klassOop _short_klass;
- static klassOop _int_klass;
- static klassOop _long_klass;
-
- // table of same
+ // table of box klasses (int_klass, etc.)
static klassOop _box_klasses[T_VOID+1];
static oop _java_system_loader;
--- a/hotspot/src/share/vm/opto/divnode.cpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/src/share/vm/opto/divnode.cpp Fri May 02 08:22:11 2008 -0700
@@ -421,7 +421,7 @@
// x/x == 1, we ignore 0/0.
// Note: if t1 and t2 are zero then result is NaN (JVMS page 213)
- // does not work for variables because of NaN's
+ // 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()) && 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));
}
//=============================================================================
--- a/hotspot/src/share/vm/opto/parse2.cpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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()) {
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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)") \
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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 */ \
--- a/hotspot/src/share/vm/services/threadService.cpp Thu May 01 09:38:23 2008 -0400
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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)];
+ }
+}