Mercurial > hg > truffle
diff src/share/vm/classfile/classFileParser.cpp @ 710:e5b0439ef4ae
6655638: dynamic languages need method handles
Summary: initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.)
Reviewed-by: kvn, twisti, never
author | jrose |
---|---|
date | Wed, 08 Apr 2009 10:56:49 -0700 |
parents | 715dceaa89b7 |
children | 75596850f863 6a93908f268f |
line wrap: on
line diff
--- a/src/share/vm/classfile/classFileParser.cpp Wed Apr 08 00:12:59 2009 -0700 +++ b/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());