mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 06:14:49 +02:00
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:
parent
318da3f68c
commit
ce0c084720
63 changed files with 5815 additions and 70 deletions
|
@ -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());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue