6655638: dynamic languages need method handles

Initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.)

Reviewed-by: kvn, twisti, never
This commit is contained in:
John R Rose 2009-04-08 10:56:49 -07:00
parent 318da3f68c
commit ce0c084720
63 changed files with 5815 additions and 70 deletions

View file

@ -1842,6 +1842,11 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
_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 @@ void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_pt
}
// 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 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
}
}
_host_klass = host_klass;
_cp_patches = cp_patches;
instanceKlassHandle nullHandle;
@ -2808,6 +2889,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
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 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
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());