void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
  address p = bcp + offset;
  assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode");
  if (!reverse) {
    int cp_index = Bytes::get_Java_u2(p);
    int cpc  = maybe_add_cp_cache_entry(cp_index);  // add lazily
    int cpc2 = add_secondary_cp_cache_entry(cpc);
    // The second secondary entry is required to store the MethodType and
    // must be the next entry.
    int cpc3 = add_secondary_cp_cache_entry(cpc);
    assert(cpc2 + 1 == cpc3, err_msg_res("must be consecutive: %d + 1 == %d", cpc2, cpc3));

    // Replace the trailing four bytes with a CPC index for the dynamic
    // call site.  Unlike other CPC entries, there is one per bytecode,
    // not just one per distinct CP entry.  In other words, the
    // CPC-to-CP relation is many-to-one for invokedynamic entries.
    // This means we must use a larger index size than u2 to address
    // all these entries.  That is the main reason invokedynamic
    // must have a five-byte instruction format.  (Of course, other JVM
    // implementations can use the bytes for other purposes.)
    Bytes::put_native_u4(p, constantPoolCacheOopDesc::encode_secondary_index(cpc2));
    // Note: We use native_u4 format exclusively for 4-byte indexes.
  } else {
    int cache_index = constantPoolCacheOopDesc::decode_secondary_index(
                        Bytes::get_native_u4(p));
    int secondary_index = cp_cache_secondary_entry_main_index(cache_index);
    int pool_index = cp_cache_entry_pool_index(secondary_index);
    assert(_pool->tag_at(pool_index).is_invoke_dynamic(), "wrong index");
    // zero out 4 bytes
    Bytes::put_Java_u4(p, 0);
    Bytes::put_Java_u2(p, pool_index);
  }
}
Exemplo n.º 2
0
void Rewriter::rewrite_invokedynamic(address bcp, int offset, int delete_me) {
  address p = bcp + offset;
  assert(p[-1] == Bytecodes::_invokedynamic, "");
  int cp_index = Bytes::get_Java_u2(p);
  int cpc  = maybe_add_cp_cache_entry(cp_index);  // add lazily
  int cpc2 = add_secondary_cp_cache_entry(cpc);

  // Replace the trailing four bytes with a CPC index for the dynamic
  // call site.  Unlike other CPC entries, there is one per bytecode,
  // not just one per distinct CP entry.  In other words, the
  // CPC-to-CP relation is many-to-one for invokedynamic entries.
  // This means we must use a larger index size than u2 to address
  // all these entries.  That is the main reason invokedynamic
  // must have a five-byte instruction format.  (Of course, other JVM
  // implementations can use the bytes for other purposes.)
  Bytes::put_native_u4(p, constantPoolCacheOopDesc::encode_secondary_index(cpc2));
  // Note: We use native_u4 format exclusively for 4-byte indexes.
}
// Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)
void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, bool reverse) {
  if (!reverse) {
    if ((*opc) == (u1)Bytecodes::_invokevirtual ||
        // allow invokespecial as an alias, although it would be very odd:
        (*opc) == (u1)Bytecodes::_invokespecial) {
      assert(_pool->tag_at(cp_index).is_method(), "wrong index");
      // Determine whether this is a signature-polymorphic method.
      if (cp_index >= _method_handle_invokers.length())  return;
      int status = _method_handle_invokers[cp_index];
      assert(status >= -1 && status <= 1, "oob tri-state");
      if (status == 0) {
        if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
            MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(),
                                                         _pool->name_ref_at(cp_index))) {
          assert(has_cp_cache(cp_index), "should already have an entry");
          int cpc  = maybe_add_cp_cache_entry(cp_index);  // should already have an entry
          int cpc2 = add_secondary_cp_cache_entry(cpc);
          status = +1;
        } else {
          status = -1;
        }
        _method_handle_invokers[cp_index] = status;
      }
      // We use a special internal bytecode for such methods (if non-static).
      // The basic reason for this is that such methods need an extra "appendix" argument
      // to transmit the call site's intended call type.
      if (status > 0) {
        (*opc) = (u1)Bytecodes::_invokehandle;
      }
    }
  } else {
    // Do not need to look at cp_index.
    if ((*opc) == (u1)Bytecodes::_invokehandle) {
      (*opc) = (u1)Bytecodes::_invokevirtual;
      // Ignore corner case of original _invokespecial instruction.
      // This is safe because (a) the signature polymorphic method was final, and
      // (b) the implementation of MethodHandle will not call invokespecial on it.
    }
  }
}