diff src/share/vm/classfile/javaClasses.hpp @ 6266:1d7922586cf6

7023639: JSR 292 method handle invocation needs a fast path for compiled code 6984705: JSR 292 method handle creation should not go through JNI Summary: remove assembly code for JDK 7 chained method handles Reviewed-by: jrose, twisti, kvn, mhaupt Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author twisti
date Tue, 24 Jul 2012 10:51:00 -0700
parents 58ad5f22317e
children 957c266d8bc5 da91efe96a93
line wrap: on
line diff
--- a/src/share/vm/classfile/javaClasses.hpp	Mon Jul 23 13:04:59 2012 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp	Tue Jul 24 10:51:00 2012 -0700
@@ -883,19 +883,14 @@
 
 // Interface to java.lang.invoke.MethodHandle objects
 
-#define METHODHANDLE_INJECTED_FIELDS(macro)                               \
-  macro(java_lang_invoke_MethodHandle, vmentry,  intptr_signature, false) \
-  macro(java_lang_invoke_MethodHandle, vmtarget, object_signature, true)
-
 class MethodHandleEntry;
 
 class java_lang_invoke_MethodHandle: AllStatic {
   friend class JavaClasses;
 
  private:
-  static int _vmentry_offset;            // assembly code trampoline for MH
-  static int _vmtarget_offset;           // class-specific target reference
-  static int _type_offset;              // the MethodType of this MH
+  static int _type_offset;               // the MethodType of this MH
+  static int _form_offset;               // the LambdaForm of this MH
 
   static void compute_offsets();
 
@@ -904,13 +899,8 @@
   static oop            type(oop mh);
   static void       set_type(oop mh, oop mtype);
 
-  static oop            vmtarget(oop mh);
-  static void       set_vmtarget(oop mh, oop target);
-
-  static MethodHandleEntry* vmentry(oop mh);
-  static void       set_vmentry(oop mh, MethodHandleEntry* data);
-
-  static int            vmslots(oop mh);
+  static oop            form(oop mh);
+  static void       set_form(oop mh, oop lform);
 
   // Testers
   static bool is_subclass(klassOop klass) {
@@ -922,149 +912,45 @@
 
   // Accessors for code generation:
   static int type_offset_in_bytes()             { return _type_offset; }
-  static int vmtarget_offset_in_bytes()         { return _vmtarget_offset; }
-  static int vmentry_offset_in_bytes()          { return _vmentry_offset; }
+  static int form_offset_in_bytes()             { return _form_offset; }
 };
 
-#define DIRECTMETHODHANDLE_INJECTED_FIELDS(macro)                          \
-  macro(java_lang_invoke_DirectMethodHandle, vmindex, int_signature, true)
+// Interface to java.lang.invoke.LambdaForm objects
+// (These are a private interface for managing adapter code generation.)
 
-class java_lang_invoke_DirectMethodHandle: public java_lang_invoke_MethodHandle {
+class java_lang_invoke_LambdaForm: AllStatic {
   friend class JavaClasses;
 
  private:
-  static int _vmindex_offset;           // negative or vtable idx or itable idx
+  static int _vmentry_offset;  // type is MemberName
+
   static void compute_offsets();
 
  public:
   // Accessors
-  static int            vmindex(oop mh);
-  static void       set_vmindex(oop mh, int index);
+  static oop            vmentry(oop lform);
+  static void       set_vmentry(oop lform, oop invoker);
 
   // Testers
   static bool is_subclass(klassOop klass) {
-    return Klass::cast(klass)->is_subclass_of(SystemDictionary::DirectMethodHandle_klass());
+    return SystemDictionary::LambdaForm_klass() != NULL &&
+      Klass::cast(klass)->is_subclass_of(SystemDictionary::LambdaForm_klass());
   }
   static bool is_instance(oop obj) {
     return obj != NULL && is_subclass(obj->klass());
   }
 
   // Accessors for code generation:
-  static int vmindex_offset_in_bytes()          { return _vmindex_offset; }
-};
-
-class java_lang_invoke_BoundMethodHandle: public java_lang_invoke_MethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _argument_offset;          // argument value bound into this MH
-  static int _vmargslot_offset;         // relevant argument slot (<= vmslots)
-  static void compute_offsets();
-
-public:
-  static oop            argument(oop mh);
-  static void       set_argument(oop mh, oop ref);
-
-  static jint           vmargslot(oop mh);
-  static void       set_vmargslot(oop mh, jint slot);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return Klass::cast(klass)->is_subclass_of(SystemDictionary::BoundMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  static int argument_offset_in_bytes()         { return _argument_offset; }
-  static int vmargslot_offset_in_bytes()        { return _vmargslot_offset; }
+  static int vmentry_offset_in_bytes()          { return _vmentry_offset; }
 };
 
-class java_lang_invoke_AdapterMethodHandle: public java_lang_invoke_BoundMethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _conversion_offset;        // type of conversion to apply
-  static void compute_offsets();
-
- public:
-  static int            conversion(oop mh);
-  static void       set_conversion(oop mh, int conv);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return Klass::cast(klass)->is_subclass_of(SystemDictionary::AdapterMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
-  enum {
-    OP_RETYPE_ONLY   = 0x0, // no argument changes; straight retype
-    OP_RETYPE_RAW    = 0x1, // straight retype, trusted (void->int, Object->T)
-    OP_CHECK_CAST    = 0x2, // ref-to-ref conversion; requires a Class argument
-    OP_PRIM_TO_PRIM  = 0x3, // converts from one primitive to another
-    OP_REF_TO_PRIM   = 0x4, // unboxes a wrapper to produce a primitive
-    OP_PRIM_TO_REF   = 0x5, // boxes a primitive into a wrapper
-    OP_SWAP_ARGS     = 0x6, // swap arguments (vminfo is 2nd arg)
-    OP_ROT_ARGS      = 0x7, // rotate arguments (vminfo is displaced arg)
-    OP_DUP_ARGS      = 0x8, // duplicates one or more arguments (at TOS)
-    OP_DROP_ARGS     = 0x9, // remove one or more argument slots
-    OP_COLLECT_ARGS  = 0xA, // combine arguments using an auxiliary function
-    OP_SPREAD_ARGS   = 0xB, // expand in place a varargs array (of known size)
-    OP_FOLD_ARGS     = 0xC, // combine but do not remove arguments; prepend result
-    //OP_UNUSED_13   = 0xD, // unused code, perhaps for reified argument lists
-    CONV_OP_LIMIT    = 0xE, // limit of CONV_OP enumeration
-
-    CONV_OP_MASK     = 0xF00, // this nybble contains the conversion op field
-    CONV_TYPE_MASK   = 0x0F,  // fits T_ADDRESS and below
-    CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
-    CONV_VMINFO_SHIFT     =  0, // position of bits in CONV_VMINFO_MASK
-    CONV_OP_SHIFT         =  8, // position of bits in CONV_OP_MASK
-    CONV_DEST_TYPE_SHIFT  = 12, // byte 2 has the adapter BasicType (if needed)
-    CONV_SRC_TYPE_SHIFT   = 16, // byte 2 has the source BasicType (if needed)
-    CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
-    CONV_STACK_MOVE_MASK  = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1
-  };
-
-  static int conversion_offset_in_bytes()       { return _conversion_offset; }
-};
-
-
-// A simple class that maintains an invocation count
-class java_lang_invoke_CountingMethodHandle: public java_lang_invoke_MethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _vmcount_offset;
-  static void compute_offsets();
-
- public:
-  // Accessors
-  static int            vmcount(oop mh);
-  static void       set_vmcount(oop mh, int count);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return SystemDictionary::CountingMethodHandle_klass() != NULL &&
-      Klass::cast(klass)->is_subclass_of(SystemDictionary::CountingMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  // Accessors for code generation:
-  static int vmcount_offset_in_bytes()          { return _vmcount_offset; }
-};
-
-
 
 // Interface to java.lang.invoke.MemberName objects
 // (These are a private interface for Java code to query the class hierarchy.)
 
-#define MEMBERNAME_INJECTED_FIELDS(macro)                              \
-  macro(java_lang_invoke_MemberName, vmtarget, object_signature, true)
+#define MEMBERNAME_INJECTED_FIELDS(macro)                               \
+  macro(java_lang_invoke_MemberName, vmindex,  intptr_signature, false) \
+  macro(java_lang_invoke_MemberName, vmtarget, object_signature, false)
 
 class java_lang_invoke_MemberName: AllStatic {
   friend class JavaClasses;
@@ -1076,7 +962,7 @@
   //    private Object     type;        // may be null if not yet materialized
   //    private int        flags;       // modifier bits; see reflect.Modifier
   //    private Object     vmtarget;    // VM-specific target value
-  //    private int        vmindex;     // method index within class or interface
+  //    private intptr_t   vmindex;     // member index within class or interface
   static int _clazz_offset;
   static int _name_offset;
   static int _type_offset;
@@ -1100,15 +986,11 @@
   static int            flags(oop mname);
   static void       set_flags(oop mname, int flags);
 
-  static int            modifiers(oop mname) { return (u2) flags(mname); }
-  static void       set_modifiers(oop mname, int mods)
-                                { set_flags(mname, (flags(mname) &~ (u2)-1) | (u2)mods); }
-
   static oop            vmtarget(oop mname);
   static void       set_vmtarget(oop mname, oop target);
 
-  static int            vmindex(oop mname);
-  static void       set_vmindex(oop mname, int index);
+  static intptr_t       vmindex(oop mname);
+  static void       set_vmindex(oop mname, intptr_t index);
 
   // Testers
   static bool is_subclass(klassOop klass) {
@@ -1124,9 +1006,11 @@
     MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
     MN_IS_FIELD            = 0x00040000, // field
     MN_IS_TYPE             = 0x00080000, // nested type
-    MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
-    MN_SEARCH_INTERFACES   = 0x00200000, // for MHN.getMembers
-    VM_INDEX_UNINITIALIZED = -99
+    MN_REFERENCE_KIND_SHIFT = 24, // refKind
+    MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+    // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+    MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes
+    MN_SEARCH_INTERFACES   = 0x00200000  // walk implemented interfaces
   };
 
   // Accessors for code generation:
@@ -1147,7 +1031,6 @@
  private:
   static int _rtype_offset;
   static int _ptypes_offset;
-  static int _form_offset;
 
   static void compute_offsets();
 
@@ -1155,11 +1038,13 @@
   // Accessors
   static oop            rtype(oop mt);
   static objArrayOop    ptypes(oop mt);
-  static oop            form(oop mt);
 
   static oop            ptype(oop mt, int index);
   static int            ptype_count(oop mt);
 
+  static int            ptype_slot_count(oop mt);  // extra counts for long/double
+  static int            rtype_slot_count(oop mt);  // extra counts for long/double
+
   static Symbol*        as_signature(oop mt, bool intern_if_not_found, TRAPS);
   static void           print_signature(oop mt, outputStream* st);
 
@@ -1172,40 +1057,6 @@
   // Accessors for code generation:
   static int rtype_offset_in_bytes()            { return _rtype_offset; }
   static int ptypes_offset_in_bytes()           { return _ptypes_offset; }
-  static int form_offset_in_bytes()             { return _form_offset; }
-};
-
-#define METHODTYPEFORM_INJECTED_FIELDS(macro)                              \
-  macro(java_lang_invoke_MethodTypeForm, vmslots,  int_signature,    true) \
-  macro(java_lang_invoke_MethodTypeForm, vmlayout, object_signature, true)
-
-class java_lang_invoke_MethodTypeForm: AllStatic {
-  friend class JavaClasses;
-
- private:
-  static int _vmslots_offset;           // number of argument slots needed
-  static int _vmlayout_offset;          // object describing internal calling sequence
-  static int _erasedType_offset;        // erasedType = canonical MethodType
-  static int _genericInvoker_offset;    // genericInvoker = adapter for invokeGeneric
-
-  static void compute_offsets();
-
- public:
-  // Accessors
-  static int            vmslots(oop mtform);
-  static void       set_vmslots(oop mtform, int vmslots);
-
-  static oop            erasedType(oop mtform);
-  static oop            genericInvoker(oop mtform);
-
-  static oop            vmlayout(oop mtform);
-  static oop       init_vmlayout(oop mtform, oop cookie);
-
-  // Accessors for code generation:
-  static int vmslots_offset_in_bytes()          { return _vmslots_offset; }
-  static int vmlayout_offset_in_bytes()         { return _vmlayout_offset; }
-  static int erasedType_offset_in_bytes()       { return _erasedType_offset; }
-  static int genericInvoker_offset_in_bytes()   { return _genericInvoker_offset; }
 };
 
 
@@ -1275,6 +1126,7 @@
 
  public:
   static oop parent(oop loader);
+  static bool isAncestor(oop loader, oop cl);
 
   // Support for parallelCapable field
   static bool parallelCapable(oop the_class_mirror);
@@ -1284,6 +1136,14 @@
   // Fix for 4474172
   static oop  non_reflection_class_loader(oop loader);
 
+  // Testers
+  static bool is_subclass(klassOop klass) {
+    return Klass::cast(klass)->is_subclass_of(SystemDictionary::ClassLoader_klass());
+  }
+  static bool is_instance(oop obj) {
+    return obj != NULL && is_subclass(obj->klass());
+  }
+
   // Debugging
   friend class JavaClasses;
 };
@@ -1425,10 +1285,7 @@
 
 #define ALL_INJECTED_FIELDS(macro)          \
   CLASS_INJECTED_FIELDS(macro)              \
-  METHODHANDLE_INJECTED_FIELDS(macro)       \
-  DIRECTMETHODHANDLE_INJECTED_FIELDS(macro) \
-  MEMBERNAME_INJECTED_FIELDS(macro)         \
-  METHODTYPEFORM_INJECTED_FIELDS(macro)
+  MEMBERNAME_INJECTED_FIELDS(macro)
 
 // Interface to hard-coded offset checking