src/share/vm/classfile/classFileParser.cpp

changeset 1145
e5b0439ef4ae
parent 1092
715dceaa89b7
child 1291
75596850f863
child 1310
6a93908f268f
     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());

mercurial