1.1 --- a/src/share/vm/classfile/classFileParser.cpp Wed Apr 08 00:12:59 2009 -0700 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Apr 08 10:56:49 2009 -0700 1.3 @@ -1842,6 +1842,11 @@ 1.4 _has_vanilla_constructor = true; 1.5 } 1.6 1.7 + if (EnableMethodHandles && m->is_method_handle_invoke()) { 1.8 + THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(), 1.9 + "Method handle invokers must be defined internally to the VM", nullHandle); 1.10 + } 1.11 + 1.12 return m; 1.13 } 1.14 1.15 @@ -2465,9 +2470,84 @@ 1.16 } 1.17 1.18 1.19 +// Force MethodHandle.vmentry to be an unmanaged pointer. 1.20 +// There is no way for a classfile to express this, so we must help it. 1.21 +void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp, 1.22 + typeArrayHandle* fields_ptr, 1.23 + FieldAllocationCount *fac_ptr, 1.24 + TRAPS) { 1.25 + // Add fake fields for java.dyn.MethodHandle instances 1.26 + // 1.27 + // This is not particularly nice, but since there is no way to express 1.28 + // a native wordSize field in Java, we must do it at this level. 1.29 + 1.30 + if (!EnableMethodHandles) return; 1.31 + 1.32 + int word_sig_index = 0; 1.33 + const int cp_size = cp->length(); 1.34 + for (int index = 1; index < cp_size; index++) { 1.35 + if (cp->tag_at(index).is_utf8() && 1.36 + cp->symbol_at(index) == vmSymbols::machine_word_signature()) { 1.37 + word_sig_index = index; 1.38 + break; 1.39 + } 1.40 + } 1.41 + 1.42 + if (word_sig_index == 0) 1.43 + THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), 1.44 + "missing I or J signature (for vmentry) in java.dyn.MethodHandle"); 1.45 + 1.46 + bool found_vmentry = false; 1.47 + 1.48 + const int n = (*fields_ptr)()->length(); 1.49 + for (int i = 0; i < n; i += instanceKlass::next_offset) { 1.50 + int name_index = (*fields_ptr)->ushort_at(i + instanceKlass::name_index_offset); 1.51 + int sig_index = (*fields_ptr)->ushort_at(i + instanceKlass::signature_index_offset); 1.52 + int acc_flags = (*fields_ptr)->ushort_at(i + instanceKlass::access_flags_offset); 1.53 + symbolOop f_name = cp->symbol_at(name_index); 1.54 + symbolOop f_sig = cp->symbol_at(sig_index); 1.55 + if (f_sig == vmSymbols::byte_signature() && 1.56 + f_name == vmSymbols::vmentry_name() && 1.57 + (acc_flags & JVM_ACC_STATIC) == 0) { 1.58 + // Adjust the field type from byte to an unmanaged pointer. 1.59 + assert(fac_ptr->nonstatic_byte_count > 0, ""); 1.60 + fac_ptr->nonstatic_byte_count -= 1; 1.61 + (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, 1.62 + word_sig_index); 1.63 + if (wordSize == jintSize) { 1.64 + fac_ptr->nonstatic_word_count += 1; 1.65 + } else { 1.66 + fac_ptr->nonstatic_double_count += 1; 1.67 + } 1.68 + 1.69 + FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i+4); 1.70 + assert(atype == NONSTATIC_BYTE, ""); 1.71 + FieldAllocationType new_atype = NONSTATIC_WORD; 1.72 + if (wordSize > jintSize) { 1.73 + if (Universe::field_type_should_be_aligned(T_LONG)) { 1.74 + atype = NONSTATIC_ALIGNED_DOUBLE; 1.75 + } else { 1.76 + atype = NONSTATIC_DOUBLE; 1.77 + } 1.78 + } 1.79 + (*fields_ptr)->ushort_at_put(i+4, new_atype); 1.80 + 1.81 + found_vmentry = true; 1.82 + break; 1.83 + } 1.84 + } 1.85 + 1.86 + if (!found_vmentry) 1.87 + THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), 1.88 + "missing vmentry byte field in java.dyn.MethodHandle"); 1.89 + 1.90 +} 1.91 + 1.92 + 1.93 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, 1.94 Handle class_loader, 1.95 Handle protection_domain, 1.96 + KlassHandle host_klass, 1.97 GrowableArray<Handle>* cp_patches, 1.98 symbolHandle& parsed_name, 1.99 TRAPS) { 1.100 @@ -2500,6 +2580,7 @@ 1.101 } 1.102 } 1.103 1.104 + _host_klass = host_klass; 1.105 _cp_patches = cp_patches; 1.106 1.107 instanceKlassHandle nullHandle; 1.108 @@ -2808,6 +2889,11 @@ 1.109 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle)); 1.110 } 1.111 1.112 + // adjust the vmentry field declaration in java.dyn.MethodHandle 1.113 + if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) { 1.114 + java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle)); 1.115 + } 1.116 + 1.117 // Add a fake "discovered" field if it is not present 1.118 // for compatibility with earlier jdk's. 1.119 if (class_name() == vmSymbols::java_lang_ref_Reference() 1.120 @@ -3134,7 +3220,7 @@ 1.121 this_klass->set_method_ordering(method_ordering()); 1.122 this_klass->set_initial_method_idnum(methods->length()); 1.123 this_klass->set_name(cp->klass_name_at(this_class_index)); 1.124 - if (LinkWellKnownClasses) // I am well known to myself 1.125 + if (LinkWellKnownClasses || is_anonymous()) // I am well known to myself 1.126 cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve 1.127 this_klass->set_protection_domain(protection_domain()); 1.128 this_klass->set_fields_annotations(fields_annotations());