src/share/vm/oops/constantPoolOop.cpp

changeset 2268
3b2dea75431e
parent 2265
d1896d1dda3e
child 2314
f95d63e2154a
     1.1 --- a/src/share/vm/oops/constantPoolOop.cpp	Sat Oct 30 12:19:07 2010 -0700
     1.2 +++ b/src/share/vm/oops/constantPoolOop.cpp	Sat Oct 30 13:08:23 2010 -0700
     1.3 @@ -267,7 +267,7 @@
     1.4      if (constantPoolCacheOopDesc::is_secondary_index(which)) {
     1.5        // Invokedynamic index.
     1.6        int pool_index = cache()->main_entry_at(which)->constant_pool_index();
     1.7 -      if (tag_at(pool_index).is_invoke_dynamic())
     1.8 +      if (!AllowTransitionalJSR292 || tag_at(pool_index).is_invoke_dynamic())
     1.9          pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
    1.10        assert(tag_at(pool_index).is_name_and_type(), "");
    1.11        return pool_index;
    1.12 @@ -275,11 +275,17 @@
    1.13      // change byte-ordering and go via cache
    1.14      i = remap_instruction_operand_from_cache(which);
    1.15    } else {
    1.16 -    if (tag_at(which).is_name_and_type())
    1.17 +    if (AllowTransitionalJSR292 && tag_at(which).is_name_and_type())
    1.18        // invokedynamic index is a simple name-and-type
    1.19        return which;
    1.20 +    if (tag_at(which).is_invoke_dynamic()) {
    1.21 +      int pool_index = invoke_dynamic_name_and_type_ref_index_at(which);
    1.22 +      assert(tag_at(pool_index).is_name_and_type(), "");
    1.23 +      return pool_index;
    1.24 +    }
    1.25    }
    1.26    assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
    1.27 +  assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above");
    1.28    jint ref_index = *int_at_addr(i);
    1.29    return extract_high_short_from_int(ref_index);
    1.30  }
    1.31 @@ -393,18 +399,61 @@
    1.32    }
    1.33  }
    1.34  
    1.35 +// A resolved constant value in the CP cache is represented as a non-null
    1.36 +// value.  As a special case, this value can be a 'systemObjArray'
    1.37 +// which masks an exception object to throw.
    1.38 +// This allows a MethodHandle constant reference to throw a consistent
    1.39 +// exception every time, if it fails to resolve.
    1.40 +static oop decode_exception_from_f1(oop result_oop, TRAPS) {
    1.41 +  if (result_oop->klass() != Universe::systemObjArrayKlassObj())
    1.42 +    return result_oop;
    1.43 +
    1.44 +  // Special cases here:  Masked null, saved exception.
    1.45 +  objArrayOop sys_array = (objArrayOop) result_oop;
    1.46 +  assert(sys_array->length() == 1, "bad system array");
    1.47 +  if (sys_array->length() == 1) {
    1.48 +    THROW_OOP_(sys_array->obj_at(0), NULL);
    1.49 +  }
    1.50 +  return NULL;
    1.51 +}
    1.52 +
    1.53  oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) {
    1.54    oop result_oop = NULL;
    1.55 +  Handle throw_exception;
    1.56 +
    1.57 +  if (cache_index == _possible_index_sentinel) {
    1.58 +    // It is possible that this constant is one which is cached in the CP cache.
    1.59 +    // We'll do a linear search.  This should be OK because this usage is rare.
    1.60 +    assert(index > 0, "valid index");
    1.61 +    constantPoolCacheOop cache = this_oop()->cache();
    1.62 +    for (int i = 0, len = cache->length(); i < len; i++) {
    1.63 +      ConstantPoolCacheEntry* cpc_entry = cache->entry_at(i);
    1.64 +      if (!cpc_entry->is_secondary_entry() && cpc_entry->constant_pool_index() == index) {
    1.65 +        // Switch the query to use this CPC entry.
    1.66 +        cache_index = i;
    1.67 +        index = _no_index_sentinel;
    1.68 +        break;
    1.69 +      }
    1.70 +    }
    1.71 +    if (cache_index == _possible_index_sentinel)
    1.72 +      cache_index = _no_index_sentinel;  // not found
    1.73 +  }
    1.74 +  assert(cache_index == _no_index_sentinel || cache_index >= 0, "");
    1.75 +  assert(index == _no_index_sentinel || index >= 0, "");
    1.76 +
    1.77    if (cache_index >= 0) {
    1.78 -    assert(index < 0, "only one kind of index at a time");
    1.79 +    assert(index == _no_index_sentinel, "only one kind of index at a time");
    1.80      ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
    1.81      result_oop = cpc_entry->f1();
    1.82      if (result_oop != NULL) {
    1.83 -      return result_oop;  // that was easy...
    1.84 +      return decode_exception_from_f1(result_oop, THREAD);
    1.85 +      // That was easy...
    1.86      }
    1.87      index = cpc_entry->constant_pool_index();
    1.88    }
    1.89  
    1.90 +  jvalue prim_value;  // temp used only in a few cases below
    1.91 +
    1.92    int tag_value = this_oop->tag_at(index).value();
    1.93    switch (tag_value) {
    1.94  
    1.95 @@ -448,9 +497,14 @@
    1.96        KlassHandle klass(THREAD, this_oop->pool_holder());
    1.97        Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
    1.98                                                                     callee, name, signature,
    1.99 -                                                                   CHECK_NULL);
   1.100 +                                                                   THREAD);
   1.101 +      if (HAS_PENDING_EXCEPTION) {
   1.102 +        throw_exception = Handle(THREAD, PENDING_EXCEPTION);
   1.103 +        CLEAR_PENDING_EXCEPTION;
   1.104 +        break;
   1.105 +      }
   1.106        result_oop = value();
   1.107 -      // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error.
   1.108 +      assert(result_oop != NULL, "");
   1.109        break;
   1.110      }
   1.111  
   1.112 @@ -467,20 +521,36 @@
   1.113                                                                 klass,
   1.114                                                                 false,
   1.115                                                                 ignore_is_on_bcp,
   1.116 -                                                               CHECK_NULL);
   1.117 +                                                               THREAD);
   1.118 +      if (HAS_PENDING_EXCEPTION) {
   1.119 +        throw_exception = Handle(THREAD, PENDING_EXCEPTION);
   1.120 +        CLEAR_PENDING_EXCEPTION;
   1.121 +        break;
   1.122 +      }
   1.123        result_oop = value();
   1.124 -      // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error.
   1.125 +      assert(result_oop != NULL, "");
   1.126        break;
   1.127      }
   1.128  
   1.129 -    /* maybe some day
   1.130    case JVM_CONSTANT_Integer:
   1.131 +    prim_value.i = this_oop->int_at(index);
   1.132 +    result_oop = java_lang_boxing_object::create(T_INT, &prim_value, CHECK_NULL);
   1.133 +    break;
   1.134 +
   1.135    case JVM_CONSTANT_Float:
   1.136 +    prim_value.f = this_oop->float_at(index);
   1.137 +    result_oop = java_lang_boxing_object::create(T_FLOAT, &prim_value, CHECK_NULL);
   1.138 +    break;
   1.139 +
   1.140    case JVM_CONSTANT_Long:
   1.141 +    prim_value.j = this_oop->long_at(index);
   1.142 +    result_oop = java_lang_boxing_object::create(T_LONG, &prim_value, CHECK_NULL);
   1.143 +    break;
   1.144 +
   1.145    case JVM_CONSTANT_Double:
   1.146 -    result_oop = java_lang_boxing_object::create(...);
   1.147 +    prim_value.d = this_oop->double_at(index);
   1.148 +    result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL);
   1.149      break;
   1.150 -    */
   1.151  
   1.152    default:
   1.153      DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
   1.154 @@ -491,18 +561,31 @@
   1.155  
   1.156    if (cache_index >= 0) {
   1.157      // Cache the oop here also.
   1.158 -    Handle result(THREAD, result_oop);
   1.159 +    if (throw_exception.not_null()) {
   1.160 +      objArrayOop sys_array = oopFactory::new_system_objArray(1, CHECK_NULL);
   1.161 +      sys_array->obj_at_put(0, throw_exception());
   1.162 +      result_oop = sys_array;
   1.163 +      throw_exception = Handle();  // be tidy
   1.164 +    }
   1.165 +    Handle result_handle(THREAD, result_oop);
   1.166      result_oop = NULL;  // safety
   1.167      ObjectLocker ol(this_oop, THREAD);
   1.168      ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
   1.169 -    oop result_oop2 = cpc_entry->f1();
   1.170 -    if (result_oop2 != NULL) {
   1.171 -      // Race condition:  May already be filled in while we were trying to lock.
   1.172 -      return result_oop2;
   1.173 +    result_oop = cpc_entry->f1();
   1.174 +    // Benign race condition:  f1 may already be filled in while we were trying to lock.
   1.175 +    // The important thing here is that all threads pick up the same result.
   1.176 +    // It doesn't matter which racing thread wins, as long as only one
   1.177 +    // result is used by all threads, and all future queries.
   1.178 +    // That result may be either a resolved constant or a failure exception.
   1.179 +    if (result_oop == NULL) {
   1.180 +      result_oop = result_handle();
   1.181 +      cpc_entry->set_f1(result_oop);
   1.182      }
   1.183 -    cpc_entry->set_f1(result());
   1.184 -    return result();
   1.185 +    return decode_exception_from_f1(result_oop, THREAD);
   1.186    } else {
   1.187 +    if (throw_exception.not_null()) {
   1.188 +      THROW_HANDLE_(throw_exception, NULL);
   1.189 +    }
   1.190      return result_oop;
   1.191    }
   1.192  }
   1.193 @@ -620,6 +703,7 @@
   1.194  
   1.195  void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) {
   1.196    closure->do_oop(tags_addr());
   1.197 +  closure->do_oop(operands_addr());
   1.198  }
   1.199  
   1.200  
   1.201 @@ -837,13 +921,19 @@
   1.202  
   1.203    case JVM_CONSTANT_InvokeDynamic:
   1.204    {
   1.205 -    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
   1.206 -    int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
   1.207 -    if (k1 == k2) {
   1.208 -      int i1 = invoke_dynamic_name_and_type_ref_index_at(index1);
   1.209 -      int i2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
   1.210 -      if (i1 == i2) {
   1.211 -        return true;
   1.212 +    int op_count = multi_operand_count_at(index1);
   1.213 +    if (op_count == cp2->multi_operand_count_at(index2)) {
   1.214 +      bool all_equal = true;
   1.215 +      for (int op_i = 0; op_i < op_count; op_i++) {
   1.216 +        int k1 = multi_operand_ref_at(index1, op_i);
   1.217 +        int k2 = cp2->multi_operand_ref_at(index2, op_i);
   1.218 +        if (k1 != k2) {
   1.219 +          all_equal = false;
   1.220 +          break;
   1.221 +        }
   1.222 +      }
   1.223 +      if (all_equal) {
   1.224 +        return true;           // got through loop; all elements equal
   1.225        }
   1.226      }
   1.227    } break;
   1.228 @@ -880,6 +970,25 @@
   1.229  } // end compare_entry_to()
   1.230  
   1.231  
   1.232 +// Grow this->operands() to the indicated length, unless it is already at least that long.
   1.233 +void constantPoolOopDesc::multi_operand_buffer_grow(int min_length, TRAPS) {
   1.234 +  int old_length = multi_operand_buffer_fill_pointer();
   1.235 +  if (old_length >= min_length)  return;
   1.236 +  int new_length = min_length;
   1.237 +  assert(new_length > _multi_operand_buffer_fill_pointer_offset, "");
   1.238 +  typeArrayHandle new_operands = oopFactory::new_permanent_intArray(new_length, CHECK);
   1.239 +  if (operands() == NULL) {
   1.240 +    new_operands->int_at_put(_multi_operand_buffer_fill_pointer_offset, old_length);
   1.241 +  } else {
   1.242 +    // copy fill pointer and everything else
   1.243 +    for (int i = 0; i < old_length; i++) {
   1.244 +      new_operands->int_at_put(i, operands()->int_at(i));
   1.245 +    }
   1.246 +  }
   1.247 +  set_operands(new_operands());
   1.248 +}
   1.249 +
   1.250 +
   1.251  // Copy this constant pool's entries at start_i to end_i (inclusive)
   1.252  // to the constant pool to_cp's entries starting at to_i. A total of
   1.253  // (end_i - start_i) + 1 entries are copied.
   1.254 @@ -888,6 +997,13 @@
   1.255  
   1.256    int dest_i = to_i;  // leave original alone for debug purposes
   1.257  
   1.258 +  if (operands() != NULL) {
   1.259 +    // pre-grow the target CP's operand buffer
   1.260 +    int nops = this->multi_operand_buffer_fill_pointer();
   1.261 +    nops   += to_cp->multi_operand_buffer_fill_pointer();
   1.262 +    to_cp->multi_operand_buffer_grow(nops, CHECK);
   1.263 +  }
   1.264 +
   1.265    for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
   1.266      copy_entry_to(src_i, to_cp, dest_i, CHECK);
   1.267  
   1.268 @@ -1036,9 +1152,26 @@
   1.269  
   1.270    case JVM_CONSTANT_InvokeDynamic:
   1.271    {
   1.272 +    int op_count = multi_operand_count_at(from_i);
   1.273 +    int fillp = to_cp->multi_operand_buffer_fill_pointer();
   1.274 +    int to_op_base = fillp - _multi_operand_count_offset;  // fillp is count offset; get to base
   1.275 +    to_cp->multi_operand_buffer_grow(to_op_base + op_count, CHECK);
   1.276 +    to_cp->operands()->int_at_put(fillp++, op_count);
   1.277 +    assert(fillp == to_op_base + _multi_operand_base_offset, "just wrote count, will now write args");
   1.278 +    for (int op_i = 0; op_i < op_count; op_i++) {
   1.279 +      int op = multi_operand_ref_at(from_i, op_i);
   1.280 +      to_cp->operands()->int_at_put(fillp++, op);
   1.281 +    }
   1.282 +    assert(fillp <= to_cp->operands()->length(), "oob");
   1.283 +    to_cp->set_multi_operand_buffer_fill_pointer(fillp);
   1.284 +    to_cp->invoke_dynamic_at_put(to_i, to_op_base, op_count);
   1.285 +#ifdef ASSERT
   1.286      int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i);
   1.287      int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i);
   1.288 -    to_cp->invoke_dynamic_at_put(to_i, k1, k2);
   1.289 +    int k3 = invoke_dynamic_argument_count_at(from_i);
   1.290 +    assert(to_cp->check_invoke_dynamic_at(to_i, k1, k2, k3),
   1.291 +           "indy structure is OK");
   1.292 +#endif //ASSERT
   1.293    } break;
   1.294  
   1.295    // Invalid is used as the tag for the second constant pool entry
   1.296 @@ -1256,8 +1389,11 @@
   1.297      case JVM_CONSTANT_Methodref:
   1.298      case JVM_CONSTANT_InterfaceMethodref:
   1.299      case JVM_CONSTANT_NameAndType:
   1.300 +      return 5;
   1.301 +
   1.302      case JVM_CONSTANT_InvokeDynamic:
   1.303 -      return 5;
   1.304 +      // u1 tag, u2 bsm, u2 nt, u2 argc, u2 argv[argc]
   1.305 +      return 7 + 2 * invoke_dynamic_argument_count_at(idx);
   1.306  
   1.307      case JVM_CONSTANT_Long:
   1.308      case JVM_CONSTANT_Double:
   1.309 @@ -1474,9 +1610,15 @@
   1.310          *bytes = JVM_CONSTANT_InvokeDynamic;
   1.311          idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx);
   1.312          idx2 = invoke_dynamic_name_and_type_ref_index_at(idx);
   1.313 +        int argc = invoke_dynamic_argument_count_at(idx);
   1.314          Bytes::put_Java_u2((address) (bytes+1), idx1);
   1.315          Bytes::put_Java_u2((address) (bytes+3), idx2);
   1.316 -        DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2));
   1.317 +        Bytes::put_Java_u2((address) (bytes+5), argc);
   1.318 +        for (int arg_i = 0; arg_i < argc; arg_i++) {
   1.319 +          int arg = invoke_dynamic_argument_index_at(idx, arg_i);
   1.320 +          Bytes::put_Java_u2((address) (bytes+7+2*arg_i), arg);
   1.321 +        }
   1.322 +        DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd [%d]", idx1, idx2, argc));
   1.323          break;
   1.324        }
   1.325      }

mercurial