< prev index next >

src/hotspot/share/oops/constantPool.hpp

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP

@@ -244,20 +244,26 @@
 
 
   // The invokedynamic points at a CP cache entry.  This entry points back
   // at the original CP entry (CONSTANT_InvokeDynamic) and also (via f2) at an entry
   // in the resolved_references array (which provides the appendix argument).
-  int invokedynamic_cp_cache_index(int index) const {
-    assert (is_invokedynamic_index(index), "should be a invokedynamic index");
-    int cache_index = decode_invokedynamic_index(index);
+  int invokedynamic_cp_cache_index(int indy_index) const {
+    assert(is_invokedynamic_index(indy_index), "should be a invokedynamic index");
+    int cache_index = decode_invokedynamic_index(indy_index);
     return cache_index;
   }
-  ConstantPoolCacheEntry* invokedynamic_cp_cache_entry_at(int index) const {
+  ConstantPoolCacheEntry* invokedynamic_cp_cache_entry_at(int indy_index) const {
     // decode index that invokedynamic points to.
-    int cp_cache_index = invokedynamic_cp_cache_index(index);
+    int cp_cache_index = invokedynamic_cp_cache_index(indy_index);
     return cache()->entry_at(cp_cache_index);
   }
+  // Given the per-instruction index of an indy instruction, report the
+  // main constant pool entry for its bootstrap specifier.
+  // From there, uncached_name/signature_ref_at will get the name/type.
+  int invokedynamic_bootstrap_ref_index_at(int indy_index) const {
+    return invokedynamic_cp_cache_entry_at(indy_index)->constant_pool_index();
+  }
 
   // Assembly code support
   static int tags_offset_in_bytes()         { return offset_of(ConstantPool, _tags); }
   static int cache_offset_in_bytes()        { return offset_of(ConstantPool, _cache); }
   static int pool_holder_offset_in_bytes()  { return offset_of(ConstantPool, _pool_holder); }

@@ -292,18 +298,18 @@
   void method_type_index_at_put(int which, int ref_index) {
     tag_at_put(which, JVM_CONSTANT_MethodType);
     *int_at_addr(which) = ref_index;
   }
 
-  void dynamic_constant_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) {
+  void dynamic_constant_at_put(int which, int bsms_attribute_index, int name_and_type_index) {
     tag_at_put(which, JVM_CONSTANT_Dynamic);
-    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index;
+    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bsms_attribute_index;
   }
 
-  void invoke_dynamic_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) {
+  void invoke_dynamic_at_put(int which, int bsms_attribute_index, int name_and_type_index) {
     tag_at_put(which, JVM_CONSTANT_InvokeDynamic);
-    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index;
+    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bsms_attribute_index;
   }
 
   void unresolved_string_at_put(int which, Symbol* s) {
     release_tag_at_put(which, JVM_CONSTANT_String);
     slot_at_put(which, CPSlot(s));

@@ -532,30 +538,26 @@
   Symbol* method_type_signature_at(int which) {
     int sym = method_type_index_at(which);
     return symbol_at(sym);
   }
 
-  int invoke_dynamic_name_and_type_ref_index_at(int which) {
-    assert(tag_at(which).is_invoke_dynamic() ||
-           tag_at(which).is_dynamic_constant() ||
-           tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool");
+  int bootstrap_name_and_type_ref_index_at(int which) {
+    assert(tag_at(which).has_bootstrap(), "Corrupted constant pool");
     return extract_high_short_from_int(*int_at_addr(which));
   }
-  int invoke_dynamic_bootstrap_specifier_index(int which) {
-    assert(tag_at(which).is_invoke_dynamic() ||
-           tag_at(which).is_dynamic_constant() ||
-           tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool");
+  int bootstrap_methods_attribute_index(int which) {
+    assert(tag_at(which).has_bootstrap(), "Corrupted constant pool");
     return extract_low_short_from_int(*int_at_addr(which));
   }
-  int invoke_dynamic_operand_base(int which) {
-    int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which);
-    return operand_offset_at(operands(), bootstrap_specifier_index);
+  int bootstrap_operand_base(int which) {
+    int bsms_attribute_index = bootstrap_methods_attribute_index(which);
+    return operand_offset_at(operands(), bsms_attribute_index);
   }
   // The first part of the operands array consists of an index into the second part.
   // Extract a 32-bit index value from the first part.
-  static int operand_offset_at(Array<u2>* operands, int bootstrap_specifier_index) {
-    int n = (bootstrap_specifier_index * 2);
+  static int operand_offset_at(Array<u2>* operands, int bsms_attribute_index) {
+    int n = (bsms_attribute_index * 2);
     assert(n >= 0 && n+2 <= operands->length(), "oob");
     // The first 32-bit index points to the beginning of the second part
     // of the operands array.  Make sure this index is in the first part.
     DEBUG_ONLY(int second_part = build_int_from_shorts(operands->at(0),
                                                        operands->at(1)));

@@ -564,12 +566,12 @@
                                        operands->at(n+1));
     // The offset itself must point into the second part of the array.
     assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)");
     return offset;
   }
-  static void operand_offset_at_put(Array<u2>* operands, int bootstrap_specifier_index, int offset) {
-    int n = bootstrap_specifier_index * 2;
+  static void operand_offset_at_put(Array<u2>* operands, int bsms_attribute_index, int offset) {
+    int n = bsms_attribute_index * 2;
     assert(n >= 0 && n+2 <= operands->length(), "oob");
     operands->at_put(n+0, extract_low_short_from_int(offset));
     operands->at_put(n+1, extract_high_short_from_int(offset));
   }
   static int operand_array_length(Array<u2>* operands) {

@@ -578,89 +580,88 @@
     return (second_part / 2);
   }
 
 #ifdef ASSERT
   // operand tuples fit together exactly, end to end
-  static int operand_limit_at(Array<u2>* operands, int bootstrap_specifier_index) {
-    int nextidx = bootstrap_specifier_index + 1;
+  static int operand_limit_at(Array<u2>* operands, int bsms_attribute_index) {
+    int nextidx = bsms_attribute_index + 1;
     if (nextidx == operand_array_length(operands))
       return operands->length();
     else
       return operand_offset_at(operands, nextidx);
   }
-  int invoke_dynamic_operand_limit(int which) {
-    int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which);
-    return operand_limit_at(operands(), bootstrap_specifier_index);
+  int bootstrap_operand_limit(int which) {
+    int bsms_attribute_index = bootstrap_methods_attribute_index(which);
+    return operand_limit_at(operands(), bsms_attribute_index);
   }
 #endif //ASSERT
 
-  // layout of InvokeDynamic and Dynamic bootstrap method specifier (in second part of operands array):
+  // Layout of InvokeDynamic and Dynamic bootstrap method specifier
+  // data in second part of operands array.  This encodes one record in
+  // the BootstrapMethods attribute.  The whole specifier also includes
+  // the name and type information from the main constant pool entry.
   enum {
          _indy_bsm_offset  = 0,  // CONSTANT_MethodHandle bsm
          _indy_argc_offset = 1,  // u2 argc
          _indy_argv_offset = 2   // u2 argv[argc]
   };
 
   // These functions are used in RedefineClasses for CP merge
 
-  int operand_offset_at(int bootstrap_specifier_index) {
-    assert(0 <= bootstrap_specifier_index &&
-           bootstrap_specifier_index < operand_array_length(operands()),
+  int operand_offset_at(int bsms_attribute_index) {
+    assert(0 <= bsms_attribute_index &&
+           bsms_attribute_index < operand_array_length(operands()),
            "Corrupted CP operands");
-    return operand_offset_at(operands(), bootstrap_specifier_index);
+    return operand_offset_at(operands(), bsms_attribute_index);
   }
-  int operand_bootstrap_method_ref_index_at(int bootstrap_specifier_index) {
-    int offset = operand_offset_at(bootstrap_specifier_index);
+  int operand_bootstrap_method_ref_index_at(int bsms_attribute_index) {
+    int offset = operand_offset_at(bsms_attribute_index);
     return operands()->at(offset + _indy_bsm_offset);
   }
-  int operand_argument_count_at(int bootstrap_specifier_index) {
-    int offset = operand_offset_at(bootstrap_specifier_index);
+  int operand_argument_count_at(int bsms_attribute_index) {
+    int offset = operand_offset_at(bsms_attribute_index);
     int argc = operands()->at(offset + _indy_argc_offset);
     return argc;
   }
-  int operand_argument_index_at(int bootstrap_specifier_index, int j) {
-    int offset = operand_offset_at(bootstrap_specifier_index);
+  int operand_argument_index_at(int bsms_attribute_index, int j) {
+    int offset = operand_offset_at(bsms_attribute_index);
     return operands()->at(offset + _indy_argv_offset + j);
   }
-  int operand_next_offset_at(int bootstrap_specifier_index) {
-    int offset = operand_offset_at(bootstrap_specifier_index) + _indy_argv_offset
-                   + operand_argument_count_at(bootstrap_specifier_index);
+  int operand_next_offset_at(int bsms_attribute_index) {
+    int offset = operand_offset_at(bsms_attribute_index) + _indy_argv_offset
+                   + operand_argument_count_at(bsms_attribute_index);
     return offset;
   }
-  // Compare a bootsrap specifier in the operands arrays
-  bool compare_operand_to(int bootstrap_specifier_index1, const constantPoolHandle& cp2,
-                          int bootstrap_specifier_index2, TRAPS);
-  // Find a bootsrap specifier in the operands array
-  int find_matching_operand(int bootstrap_specifier_index, const constantPoolHandle& search_cp,
+  // Compare a bootstrap specifier data in the operands arrays
+  bool compare_operand_to(int bsms_attribute_index1, const constantPoolHandle& cp2,
+                          int bsms_attribute_index2, TRAPS);
+  // Find a bootstrap specifier data in the operands array
+  int find_matching_operand(int bsms_attribute_index, const constantPoolHandle& search_cp,
                             int operands_cur_len, TRAPS);
   // Resize the operands array with delta_len and delta_size
   void resize_operands(int delta_len, int delta_size, TRAPS);
   // Extend the operands array with the length and size of the ext_cp operands
   void extend_operands(const constantPoolHandle& ext_cp, TRAPS);
   // Shrink the operands array to a smaller array with new_len length
   void shrink_operands(int new_len, TRAPS);
 
-  int invoke_dynamic_bootstrap_method_ref_index_at(int which) {
-    assert(tag_at(which).is_invoke_dynamic() ||
-           tag_at(which).is_dynamic_constant() ||
-           tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool");
-    int op_base = invoke_dynamic_operand_base(which);
+  int bootstrap_method_ref_index_at(int which) {
+    assert(tag_at(which).has_bootstrap(), "Corrupted constant pool");
+    int op_base = bootstrap_operand_base(which);
     return operands()->at(op_base + _indy_bsm_offset);
   }
-  int invoke_dynamic_argument_count_at(int which) {
-    assert(tag_at(which).is_invoke_dynamic() ||
-           tag_at(which).is_dynamic_constant() ||
-           tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool");
-    int op_base = invoke_dynamic_operand_base(which);
+  int bootstrap_argument_count_at(int which) {
+    assert(tag_at(which).has_bootstrap(), "Corrupted constant pool");
+    int op_base = bootstrap_operand_base(which);
     int argc = operands()->at(op_base + _indy_argc_offset);
     DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc;
-               int next_offset = invoke_dynamic_operand_limit(which));
+               int next_offset = bootstrap_operand_limit(which));
     assert(end_offset == next_offset, "matched ending");
     return argc;
   }
-  int invoke_dynamic_argument_index_at(int which, int j) {
-    int op_base = invoke_dynamic_operand_base(which);
+  int bootstrap_argument_index_at(int which, int j) {
+    int op_base = bootstrap_operand_base(which);
     DEBUG_ONLY(int argc = operands()->at(op_base + _indy_argc_offset));
     assert((uint)j < (uint)argc, "oob");
     return operands()->at(op_base + _indy_argv_offset + j);
   }
 

@@ -743,22 +744,25 @@
   oop find_cached_constant_at(int pool_index, bool& found_it, TRAPS) {
     constantPoolHandle h_this(THREAD, this);
     return resolve_constant_at_impl(h_this, pool_index, _possible_index_sentinel, &found_it, THREAD);
   }
 
-  oop resolve_bootstrap_specifier_at(int index, TRAPS) {
-    constantPoolHandle h_this(THREAD, this);
-    return resolve_bootstrap_specifier_at_impl(h_this, index, THREAD);
-  }
+  enum BootstrapArgumentReferenceMode { R_IFPRESENT = 0, R_FORCE = 1, R_SYMREF = 2 };
 
   void copy_bootstrap_arguments_at(int index,
                                    int start_arg, int end_arg,
-                                   objArrayHandle info, int pos,
-                                   bool must_resolve, Handle if_not_available, TRAPS) {
+                                   arrayHandle buf, int pos,
+                                   BootstrapArgumentReferenceMode resolving,
+                                   Handle if_not_available, Handle if_null_constant,
+                                   bool skip_non_null,  // don't overwrite previous stuff in buf
+                                   bool skip_recursion, // don't resolve CONSTANT_Dynamic args
+                                   TRAPS) {
     constantPoolHandle h_this(THREAD, this);
     copy_bootstrap_arguments_at_impl(h_this, index, start_arg, end_arg,
-                                     info, pos, must_resolve, if_not_available, THREAD);
+                                     buf, pos,
+                                     resolving, if_not_available, if_null_constant,
+                                     skip_non_null, skip_recursion, THREAD);
   }
 
   // Klass name matches name at offset
   bool klass_name_at_matches(const InstanceKlass* k, int which);
 

@@ -794,12 +798,11 @@
 
   // Used by compiler to prevent classloading.
   static Method*          method_at_if_loaded      (const constantPoolHandle& this_cp, int which);
   static bool       has_appendix_at_if_loaded      (const constantPoolHandle& this_cp, int which);
   static oop            appendix_at_if_loaded      (const constantPoolHandle& this_cp, int which);
-  static bool    has_method_type_at_if_loaded      (const constantPoolHandle& this_cp, int which);
-  static oop         method_type_at_if_loaded      (const constantPoolHandle& this_cp, int which);
+  static bool has_local_signature_at_if_loaded     (const constantPoolHandle& this_cp, int which);
   static Klass*            klass_at_if_loaded      (const constantPoolHandle& this_cp, int which);
 
   // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
   // future by other Java code. These take constant pool indices rather than
   // constant pool cache indices as do the peer methods above.

@@ -869,15 +872,19 @@
   // Resolve string constants (to prevent allocation during compilation)
   static void resolve_string_constants_impl(const constantPoolHandle& this_cp, TRAPS);
 
   static oop resolve_constant_at_impl(const constantPoolHandle& this_cp, int index, int cache_index,
                                       bool* status_return, TRAPS);
-  static oop resolve_bootstrap_specifier_at_impl(const constantPoolHandle& this_cp, int index, TRAPS);
   static void copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int index,
                                                int start_arg, int end_arg,
-                                               objArrayHandle info, int pos,
-                                               bool must_resolve, Handle if_not_available, TRAPS);
+                                               arrayHandle buf, int pos,
+                                               BootstrapArgumentReferenceMode resolving,
+                                               Handle if_not_available,
+                                               Handle if_null_constant,
+                                               bool skip_non_null,
+                                               bool skip_recursion,
+                                               TRAPS);
 
   // Exception handling
   static Symbol* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception);
   static void save_and_throw_exception(const constantPoolHandle& this_cp, int which, constantTag tag, TRAPS);
 
< prev index next >