--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Apr 08 00:12:59 2009 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Apr 08 10:56:49 2009 -0700
@@ -1842,6 +1842,11 @@
_has_vanilla_constructor = true;
}
+ if (EnableMethodHandles && m->is_method_handle_invoke()) {
+ THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
+ "Method handle invokers must be defined internally to the VM", nullHandle);
+ }
+
return m;
}
@@ -2465,9 +2470,84 @@
}
+// Force MethodHandle.vmentry to be an unmanaged pointer.
+// There is no way for a classfile to express this, so we must help it.
+void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
+ typeArrayHandle* fields_ptr,
+ FieldAllocationCount *fac_ptr,
+ TRAPS) {
+ // Add fake fields for java.dyn.MethodHandle instances
+ //
+ // This is not particularly nice, but since there is no way to express
+ // a native wordSize field in Java, we must do it at this level.
+
+ if (!EnableMethodHandles) return;
+
+ int word_sig_index = 0;
+ const int cp_size = cp->length();
+ for (int index = 1; index < cp_size; index++) {
+ if (cp->tag_at(index).is_utf8() &&
+ cp->symbol_at(index) == vmSymbols::machine_word_signature()) {
+ word_sig_index = index;
+ break;
+ }
+ }
+
+ if (word_sig_index == 0)
+ THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
+ "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
+
+ bool found_vmentry = false;
+
+ const int n = (*fields_ptr)()->length();
+ for (int i = 0; i < n; i += instanceKlass::next_offset) {
+ int name_index = (*fields_ptr)->ushort_at(i + instanceKlass::name_index_offset);
+ int sig_index = (*fields_ptr)->ushort_at(i + instanceKlass::signature_index_offset);
+ int acc_flags = (*fields_ptr)->ushort_at(i + instanceKlass::access_flags_offset);
+ symbolOop f_name = cp->symbol_at(name_index);
+ symbolOop f_sig = cp->symbol_at(sig_index);
+ if (f_sig == vmSymbols::byte_signature() &&
+ f_name == vmSymbols::vmentry_name() &&
+ (acc_flags & JVM_ACC_STATIC) == 0) {
+ // Adjust the field type from byte to an unmanaged pointer.
+ assert(fac_ptr->nonstatic_byte_count > 0, "");
+ fac_ptr->nonstatic_byte_count -= 1;
+ (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
+ word_sig_index);
+ if (wordSize == jintSize) {
+ fac_ptr->nonstatic_word_count += 1;
+ } else {
+ fac_ptr->nonstatic_double_count += 1;
+ }
+
+ FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i+4);
+ assert(atype == NONSTATIC_BYTE, "");
+ FieldAllocationType new_atype = NONSTATIC_WORD;
+ if (wordSize > jintSize) {
+ if (Universe::field_type_should_be_aligned(T_LONG)) {
+ atype = NONSTATIC_ALIGNED_DOUBLE;
+ } else {
+ atype = NONSTATIC_DOUBLE;
+ }
+ }
+ (*fields_ptr)->ushort_at_put(i+4, new_atype);
+
+ found_vmentry = true;
+ break;
+ }
+ }
+
+ if (!found_vmentry)
+ THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
+ "missing vmentry byte field in java.dyn.MethodHandle");
+
+}
+
+
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
Handle class_loader,
Handle protection_domain,
+ KlassHandle host_klass,
GrowableArray<Handle>* cp_patches,
symbolHandle& parsed_name,
TRAPS) {
@@ -2500,6 +2580,7 @@
}
}
+ _host_klass = host_klass;
_cp_patches = cp_patches;
instanceKlassHandle nullHandle;
@@ -2808,6 +2889,11 @@
java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
}
+ // adjust the vmentry field declaration in java.dyn.MethodHandle
+ if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
+ java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle));
+ }
+
// Add a fake "discovered" field if it is not present
// for compatibility with earlier jdk's.
if (class_name() == vmSymbols::java_lang_ref_Reference()
@@ -3134,7 +3220,7 @@
this_klass->set_method_ordering(method_ordering());
this_klass->set_initial_method_idnum(methods->length());
this_klass->set_name(cp->klass_name_at(this_class_index));
- if (LinkWellKnownClasses) // I am well known to myself
+ if (LinkWellKnownClasses || is_anonymous()) // I am well known to myself
cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
this_klass->set_protection_domain(protection_domain());
this_klass->set_fields_annotations(fields_annotations());