/*
 * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmClasses.hpp"
#include "code/codeCache.hpp"
#include "code/dependencyContext.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/oopMapCache.hpp"
#include "interpreter/linkResolver.hpp"
#include "jvm_io.h"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/reflection.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "sanitizers/leak.hpp"
#include "utilities/exceptions.hpp"


/*
 * JSR 292 reference implementation: method handles
 * The JDK 7 reference implementation represented method handle
 * combinations as chains.  Each link in the chain had a "vmentry"
 * field which pointed at a bit of assembly code which performed
 * one transformation before dispatching to the next link in the chain.
 *
 * The current reference implementation pushes almost all code generation
 * responsibility to (trusted) Java code.  A method handle contains a
 * pointer to its "LambdaForm", which embodies all details of the method
 * handle's behavior.  The LambdaForm is a normal Java object, managed
 * by a runtime coded in Java.
 */

bool MethodHandles::_enabled = false; // set true after successful native linkage
MethodHandlesAdapterBlob* MethodHandles::_adapter_code = nullptr;

/**
 * Generates method handle adapters. Returns 'false' if memory allocation
 * failed and true otherwise.
 */
void MethodHandles::generate_adapters() {
  assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
  assert(_adapter_code == nullptr, "generate only once");

  ResourceMark rm;
  TraceTime timer("MethodHandles adapters generation", TRACETIME_LOG(Info, startuptime));
  // The adapter entry is required to be aligned to CodeEntryAlignment.
  // So we need additional bytes due to alignment.
  int adapter_num = (int)Interpreter::method_handle_invoke_LAST - (int)Interpreter::method_handle_invoke_FIRST + 1;
  int max_aligned_bytes = adapter_num * CodeEntryAlignment;
  _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size + max_aligned_bytes);
  CodeBuffer code(_adapter_code);
  MethodHandlesAdapterGenerator g(&code);
  g.generate();
  code.log_section_sizes("MethodHandlesAdapterBlob");
}

//------------------------------------------------------------------------------
// MethodHandlesAdapterGenerator::generate
//
void MethodHandlesAdapterGenerator::generate() {
  // Generate generic method handle adapters.
  // Generate interpreter entries
  for (Interpreter::MethodKind mk = Interpreter::method_handle_invoke_FIRST;
       mk <= Interpreter::method_handle_invoke_LAST;
       mk = Interpreter::MethodKind(1 + (int)mk)) {
    vmIntrinsics::ID iid = Interpreter::method_handle_intrinsic(mk);
    StubCodeMark mark(this, "MethodHandle::interpreter_entry", vmIntrinsics::name_at(iid));
    address entry = MethodHandles::generate_method_handle_interpreter_entry(_masm, iid);
    if (entry != nullptr) {
      Interpreter::set_entry_for_kind(mk, entry);
    }
    // If the entry is not set, it will throw AbstractMethodError.
  }
}

void MethodHandles::set_enabled(bool z) {
  if (_enabled != z) {
    guarantee(z, "can only enable once");
    _enabled = z;
  }
}

// MemberName support

// import java_lang_invoke_MemberName.*
enum {
  IS_METHOD            = java_lang_invoke_MemberName::MN_IS_METHOD,
  IS_CONSTRUCTOR       = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
  IS_FIELD             = java_lang_invoke_MemberName::MN_IS_FIELD,
  IS_TYPE              = java_lang_invoke_MemberName::MN_IS_TYPE,
  CALLER_SENSITIVE     = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
  TRUSTED_FINAL        = java_lang_invoke_MemberName::MN_TRUSTED_FINAL,
  HIDDEN_MEMBER        = java_lang_invoke_MemberName::MN_HIDDEN_MEMBER,
  REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
  REFERENCE_KIND_MASK  = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
  LM_UNCONDITIONAL     = java_lang_invoke_MemberName::MN_UNCONDITIONAL_MODE,
  LM_MODULE            = java_lang_invoke_MemberName::MN_MODULE_MODE,
  LM_TRUSTED           = java_lang_invoke_MemberName::MN_TRUSTED_MODE,
  ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
};

int MethodHandles::ref_kind_to_flags(int ref_kind) {
  assert(ref_kind_is_valid(ref_kind), "%d", ref_kind);
  int flags = (ref_kind << REFERENCE_KIND_SHIFT);
  if (ref_kind_is_field(ref_kind)) {
    flags |= IS_FIELD;
  } else if (ref_kind_is_method(ref_kind)) {
    flags |= IS_METHOD;
  } else if (ref_kind == JVM_REF_newInvokeSpecial) {
    flags |= IS_CONSTRUCTOR;
  }
  return flags;
}

Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
  Handle empty;
  Handle type(THREAD, java_lang_invoke_MemberName::type(mname()));
  if (!java_lang_String::is_instance(type())) {
    return type; // already resolved
  }
  Symbol* signature = java_lang_String::as_symbol_or_null(type());
  if (signature == nullptr) {
    return empty;  // no such signature exists in the VM
  }
  Handle resolved;
  int flags = java_lang_invoke_MemberName::flags(mname());
  switch (flags & ALL_KINDS) {
    case IS_METHOD:
    case IS_CONSTRUCTOR:
      resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
      break;
    case IS_FIELD:
      resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
      break;
    default:
      THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
  }
  if (resolved.is_null()) {
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MemberName type", empty);
  }
  return resolved;
}

oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
  // This method is used from java.lang.invoke.MemberName constructors.
  // It fills in the new MemberName from a java.lang.reflect.Member.
  oop target_oop = target();
  Klass* target_klass = target_oop->klass();
  if (target_klass == vmClasses::reflect_Field_klass()) {
    oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
    int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
    Klass* k = java_lang_Class::as_Klass(clazz);
    if (k != nullptr && k->is_instance_klass()) {
      fieldDescriptor fd(InstanceKlass::cast(k), slot);
      oop mname2 = init_field_MemberName(mname, fd);
      if (mname2 != nullptr) {
        // Since we have the reified name and type handy, add them to the result.
        if (java_lang_invoke_MemberName::name(mname2) == nullptr)
          java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop));
        if (java_lang_invoke_MemberName::type(mname2) == nullptr)
          java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop));
      }
      return mname2;
    }
  } else if (target_klass == vmClasses::reflect_Method_klass()) {
    oop clazz  = java_lang_reflect_Method::clazz(target_oop);
    int slot   = java_lang_reflect_Method::slot(target_oop);
    Klass* k = java_lang_Class::as_Klass(clazz);
    if (k != nullptr && k->is_instance_klass()) {
      Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
      if (m == nullptr || is_signature_polymorphic(m->intrinsic_id()))
        return nullptr;            // do not resolve unless there is a concrete signature
      CallInfo info(m, k, CHECK_NULL);
      return init_method_MemberName(mname, info);
    }
  } else if (target_klass == vmClasses::reflect_Constructor_klass()) {
    oop clazz  = java_lang_reflect_Constructor::clazz(target_oop);
    int slot   = java_lang_reflect_Constructor::slot(target_oop);
    Klass* k = java_lang_Class::as_Klass(clazz);
    if (k != nullptr && k->is_instance_klass()) {
      Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
      if (m == nullptr)  return nullptr;
      CallInfo info(m, k, CHECK_NULL);
      return init_method_MemberName(mname, info);
    }
  }
  return nullptr;
}

oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
  assert(info.resolved_appendix().is_null(), "only normal methods here");
  methodHandle m(Thread::current(), info.resolved_method());
  assert(m.not_null(), "null method handle");
  InstanceKlass* m_klass = m->method_holder();
  assert(m_klass != nullptr, "null holder for method handle");
  int flags = (m->access_flags().as_method_flags());
  int vmindex = Method::invalid_vtable_index;
  LogTarget(Debug, methodhandles, indy) lt_indy;

  switch (info.call_kind()) {
  case CallInfo::itable_call:
    vmindex = info.itable_index();
    // More importantly, the itable index only works with the method holder.
    assert(m_klass->verify_itable_index(vmindex), "");
    flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
    if (lt_indy.is_enabled()) {
      ResourceMark rm;
      LogStream ls(lt_indy);
      ls.print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:",
                  Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
                  vmindex);
       m->access_flags().print_on(&ls);
       if (!m->is_abstract()) {
         if (!m->is_private()) {
           ls.print("default");
         }
         else {
           ls.print("private-intf");
         }
       }
       ls.cr();
    }
    break;

  case CallInfo::vtable_call:
    vmindex = info.vtable_index();
    flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
    assert(info.resolved_klass()->is_subtype_of(m_klass), "virtual call must be type-safe");
    if (m_klass->is_interface()) {
      // This is a vtable call to an interface method (abstract "miranda method" or default method).
      // The vtable index is meaningless without a class (not interface) receiver type, so get one.
      // (LinkResolver should help us figure this out.)
      assert(info.resolved_klass()->is_instance_klass(), "subtype of interface must be an instance klass");
      InstanceKlass* m_klass_non_interface = InstanceKlass::cast(info.resolved_klass());
      if (m_klass_non_interface->is_interface()) {
        m_klass_non_interface = vmClasses::Object_klass();
#ifdef ASSERT
        { ResourceMark rm;
          Method* m2 = m_klass_non_interface->vtable().method_at(vmindex);
          assert(m->name() == m2->name() && m->signature() == m2->signature(),
                 "at %d, %s != %s", vmindex,
                 m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string());
        }
#endif //ASSERT
      }
      if (!m->is_public()) {
        assert(m->is_public(), "virtual call must be to public interface method");
        return nullptr;  // elicit an error later in product build
      }
      assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface), "virtual call must be type-safe");
      m_klass = m_klass_non_interface;
    }
    if (lt_indy.is_enabled()) {
      ResourceMark rm;
      LogStream ls(lt_indy);
      ls.print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
                  Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
                  m_klass->internal_name(), vmindex);
       m->access_flags().print_on(&ls);
       if (m->is_default_method()) {
         ls.print("default");
       }
       ls.cr();
    }
    break;

  case CallInfo::direct_call:
    vmindex = Method::nonvirtual_vtable_index;
    if (m->is_static()) {
      assert(!m->is_static_initializer(), "Cannot be static initializer");
      flags |= IS_METHOD      | (JVM_REF_invokeStatic  << REFERENCE_KIND_SHIFT);
    } else if (m->is_object_initializer()) {
      flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
    } else {
      // "special" reflects that this is a direct call, not that it
      // necessarily originates from an invokespecial. We can also do
      // direct calls for private and/or final non-static methods.
      flags |= IS_METHOD      | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
    }
    break;

  default:  assert(false, "bad CallInfo");  return nullptr;
  }

  // @CallerSensitive annotation detected
  if (m->caller_sensitive()) {
    flags |= CALLER_SENSITIVE;
  }

  Handle resolved_method = info.resolved_method_name();
  assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m() || m->is_old(),
         "Should not change after link resolution");

  oop mname_oop = mname();
  java_lang_invoke_MemberName::set_flags  (mname_oop, flags);
  java_lang_invoke_MemberName::set_method (mname_oop, resolved_method());
  java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);   // vtable/itable index
  java_lang_invoke_MemberName::set_clazz  (mname_oop, m_klass->java_mirror());
  // Note:  name and type can be lazily computed by resolve_MemberName,
  // if Java code needs them as resolved String and MethodType objects.
  // If relevant, the vtable or itable value is stored as vmindex.
  // This is done eagerly, since it is readily available without
  // constructing any new objects.
  return mname();
}

oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
  InstanceKlass* ik = fd.field_holder();
  int flags = fd.access_flags().as_field_flags();
  flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
  if (fd.is_trusted_final()) flags |= TRUSTED_FINAL;
  if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
  int vmindex        = fd.offset();  // determines the field uniquely when combined with static bit

  oop mname_oop = mname();
  java_lang_invoke_MemberName::set_flags  (mname_oop, flags);
  java_lang_invoke_MemberName::set_method (mname_oop, nullptr);
  java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
  java_lang_invoke_MemberName::set_clazz  (mname_oop, ik->java_mirror());

  oop type = field_signature_type_or_null(fd.signature());
  oop name = field_name_or_null(fd.name());
  if (name != nullptr)
    java_lang_invoke_MemberName::set_name(mname_oop,   name);
  if (type != nullptr)
    java_lang_invoke_MemberName::set_type(mname_oop,   type);
  // Note:  name and type can be lazily computed by resolve_MemberName,
  // if Java code needs them as resolved String and Class objects.
  // Note that the incoming type oop might be pre-resolved (non-null).
  // The base clazz and field offset (vmindex) must be eagerly stored,
  // because they unambiguously identify the field.
  // Although the fieldDescriptor::_index would also identify the field,
  // we do not use it, because it is harder to decode.
  // TO DO: maybe intern mname_oop
  return mname();
}

// JVM 2.9 Special Methods:
// A method is signature polymorphic if and only if all of the following conditions hold :
// * It is declared in the java.lang.invoke.MethodHandle/VarHandle classes.
// * It has a single formal parameter of type Object[].
// * It has a return type of Object for a polymorphic return type, otherwise a fixed return type.
// * It has the ACC_VARARGS and ACC_NATIVE flags set.
bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) {
  if (klass == nullptr)
    return false;
  // The following test will fail spuriously during bootstrap of MethodHandle itself:
  //    if (klass != vmClasses::MethodHandle_klass())
  // Test the name instead:
  if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle() &&
      klass->name() != vmSymbols::java_lang_invoke_VarHandle()) {
    return false;
  }

  // Look up signature polymorphic method with polymorphic return type
  Symbol* poly_sig = vmSymbols::object_array_object_signature();
  InstanceKlass* iklass = InstanceKlass::cast(klass);
  Method* m = iklass->find_method(name, poly_sig);
  if (m != nullptr) {
    int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS;
    int flags = m->access_flags().as_method_flags();
    if ((flags & required) == required) {
      return true;
    }
  }

  // Look up signature polymorphic method with non-polymorphic (non Object) return type
  int me;
  int ms = iklass->find_method_by_name(name, &me);
  if (ms == -1) return false;
  for (; ms < me; ms++) {
    Method* m = iklass->methods()->at(ms);
    int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS;
    int flags = m->access_flags().as_method_flags();
    if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) {
      return true;
    }
  }
  return false;
}


Symbol* MethodHandles::signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid) {
  assert(is_signature_polymorphic_intrinsic(iid), "%d %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid));
  switch (iid) {
  case vmIntrinsics::_invokeBasic:      return vmSymbols::invokeBasic_name();
  case vmIntrinsics::_linkToVirtual:    return vmSymbols::linkToVirtual_name();
  case vmIntrinsics::_linkToStatic:     return vmSymbols::linkToStatic_name();
  case vmIntrinsics::_linkToSpecial:    return vmSymbols::linkToSpecial_name();
  case vmIntrinsics::_linkToInterface:  return vmSymbols::linkToInterface_name();
  case vmIntrinsics::_linkToNative:     return vmSymbols::linkToNative_name();
  default:
    fatal("unexpected intrinsic id: %d %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid));
  }
}

Bytecodes::Code MethodHandles::signature_polymorphic_intrinsic_bytecode(vmIntrinsics::ID id) {
  switch(id) {
    case vmIntrinsics::_linkToVirtual:   return Bytecodes::_invokevirtual;
    case vmIntrinsics::_linkToInterface: return Bytecodes::_invokeinterface;
    case vmIntrinsics::_linkToStatic:    return Bytecodes::_invokestatic;
    case vmIntrinsics::_linkToSpecial:   return Bytecodes::_invokespecial;
    case vmIntrinsics::_invokeBasic:     return Bytecodes::_invokehandle;
    default:
      fatal("unexpected id: (%d) %s", (uint)id, vmIntrinsics::name_at(id));
  }
}

int MethodHandles::signature_polymorphic_intrinsic_ref_kind(vmIntrinsics::ID iid) {
  switch (iid) {
  case vmIntrinsics::_invokeBasic:      return 0;
  case vmIntrinsics::_linkToNative:     return 0;
  case vmIntrinsics::_linkToVirtual:    return JVM_REF_invokeVirtual;
  case vmIntrinsics::_linkToStatic:     return JVM_REF_invokeStatic;
  case vmIntrinsics::_linkToSpecial:    return JVM_REF_invokeSpecial;
  case vmIntrinsics::_linkToInterface:  return JVM_REF_invokeInterface;
  default:
    fatal("unexpected intrinsic id: %d %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid));
  }
}

vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Symbol* name) {
  vmSymbolID name_id = vmSymbols::find_sid(name);
  switch (name_id) {
  // The ID _invokeGeneric stands for all non-static signature-polymorphic methods, except built-ins.
  case VM_SYMBOL_ENUM_NAME(invoke_name):           return vmIntrinsics::_invokeGeneric;
  // The only built-in non-static signature-polymorphic method is MethodHandle.invokeBasic:
  case VM_SYMBOL_ENUM_NAME(invokeBasic_name):      return vmIntrinsics::_invokeBasic;

  // There is one static signature-polymorphic method for each JVM invocation mode.
  case VM_SYMBOL_ENUM_NAME(linkToVirtual_name):    return vmIntrinsics::_linkToVirtual;
  case VM_SYMBOL_ENUM_NAME(linkToStatic_name):     return vmIntrinsics::_linkToStatic;
  case VM_SYMBOL_ENUM_NAME(linkToSpecial_name):    return vmIntrinsics::_linkToSpecial;
  case VM_SYMBOL_ENUM_NAME(linkToInterface_name):  return vmIntrinsics::_linkToInterface;
  case VM_SYMBOL_ENUM_NAME(linkToNative_name):     return vmIntrinsics::_linkToNative;
  default:                                                    break;
  }

  // Cover the case of invokeExact and any future variants of invokeFoo.
  Klass* mh_klass = vmClasses::klass_at(VM_CLASS_ID(MethodHandle_klass));
  if (mh_klass != nullptr && is_method_handle_invoke_name(mh_klass, name)) {
    return vmIntrinsics::_invokeGeneric;
  }

  // Cover the case of methods on VarHandle.
  Klass* vh_klass = vmClasses::klass_at(VM_CLASS_ID(VarHandle_klass));
  if (vh_klass != nullptr && is_method_handle_invoke_name(vh_klass, name)) {
    return vmIntrinsics::_invokeGeneric;
  }

  // Note: The pseudo-intrinsic _compiledLambdaForm is never linked against.
  // Instead it is used to mark lambda forms bound to invokehandle or invokedynamic.
  return vmIntrinsics::_none;
}

vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Klass* klass, Symbol* name) {
  if (klass != nullptr &&
      (klass->name() == vmSymbols::java_lang_invoke_MethodHandle() ||
       klass->name() == vmSymbols::java_lang_invoke_VarHandle())) {
    vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
    if (iid != vmIntrinsics::_none)
      return iid;
    if (is_method_handle_invoke_name(klass, name))
      return vmIntrinsics::_invokeGeneric;
  }
  return vmIntrinsics::_none;
}

// Returns true if method is signature polymorphic and public
bool MethodHandles::is_signature_polymorphic_public_name(Klass* klass, Symbol* name) {
  if (is_signature_polymorphic_name(klass, name)) {
    InstanceKlass* iklass = InstanceKlass::cast(klass);
    int me;
    int ms = iklass->find_method_by_name(name, &me);
    assert(ms != -1, "");
    for (; ms < me; ms++) {
      Method* m = iklass->methods()->at(ms);
      int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS | JVM_ACC_PUBLIC;
      int flags = m->access_flags().as_method_flags();
      if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) {
        return true;
      }
    }
  }
  return false;
}

// convert the external string or reflective type to an internal signature
Symbol* MethodHandles::lookup_signature(oop type_str, bool intern_if_not_found, TRAPS) {
  if (java_lang_invoke_MethodType::is_instance(type_str)) {
    return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found);
  } else if (java_lang_Class::is_instance(type_str)) {
    return java_lang_Class::as_signature(type_str, false);
  } else if (java_lang_String::is_instance(type_str)) {
    if (intern_if_not_found) {
      return java_lang_String::as_symbol(type_str);
    } else {
      return java_lang_String::as_symbol_or_null(type_str);
    }
  } else {
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", nullptr);
  }
}

static const char OBJ_SIG[] = "Ljava/lang/Object;";
enum { OBJ_SIG_LEN = 18 };

bool MethodHandles::is_basic_type_signature(Symbol* sig) {
  assert(vmSymbols::object_signature()->utf8_length() == (int)OBJ_SIG_LEN, "");
  assert(vmSymbols::object_signature()->equals(OBJ_SIG), "");
  for (SignatureStream ss(sig, sig->starts_with(JVM_SIGNATURE_FUNC)); !ss.is_done(); ss.next()) {
    switch (ss.type()) {
    case T_OBJECT:
      // only java/lang/Object is valid here
      if (strncmp((char*) ss.raw_bytes(), OBJ_SIG, OBJ_SIG_LEN) != 0)
        return false;
      break;
    case T_VOID:
    case T_INT:
    case T_LONG:
    case T_FLOAT:
    case T_DOUBLE:
      break;
    default:
      // subword types (T_BYTE etc.), Q-descriptors, arrays
      return false;
    }
  }
  return true;
}

Symbol* MethodHandles::lookup_basic_type_signature(Symbol* sig, bool keep_last_arg) {
  Symbol* bsig = nullptr;
  if (sig == nullptr) {
    return sig;
  } else if (is_basic_type_signature(sig)) {
    sig->increment_refcount();
    return sig;  // that was easy
  } else if (!sig->starts_with(JVM_SIGNATURE_FUNC)) {
    BasicType bt = Signature::basic_type(sig);
    if (is_subword_type(bt)) {
      bsig = vmSymbols::int_signature();
    } else {
      assert(is_reference_type(bt), "is_basic_type_signature was false");
      bsig = vmSymbols::object_signature();
    }
  } else {
    ResourceMark rm;
    stringStream buffer(128);
    buffer.put(JVM_SIGNATURE_FUNC);
    int arg_pos = 0, keep_arg_pos = -1;
    if (keep_last_arg)
      keep_arg_pos = ArgumentCount(sig).size() - 1;
    for (SignatureStream ss(sig); !ss.is_done(); ss.next()) {
      BasicType bt = ss.type();
      size_t this_arg_pos = buffer.size();
      if (ss.at_return_type()) {
        buffer.put(JVM_SIGNATURE_ENDFUNC);
      }
      if (arg_pos == keep_arg_pos) {
        buffer.write((char*) ss.raw_bytes(),
                     (int)   ss.raw_length());
      } else if (is_reference_type(bt)) {
        buffer.write(OBJ_SIG, OBJ_SIG_LEN);
      } else {
        if (is_subword_type(bt))
          bt = T_INT;
        buffer.put(type2char(bt));
      }
      arg_pos++;
    }
    const char* sigstr =       buffer.base();
    int         siglen = (int) buffer.size();
    bsig = SymbolTable::new_symbol(sigstr, siglen);
  }
  assert(is_basic_type_signature(bsig) ||
         // detune assert in case the injected argument is not a basic type:
         keep_last_arg, "");
  return bsig;
}

void MethodHandles::print_as_basic_type_signature_on(outputStream* st,
                                                     Symbol* sig) {
  st = st ? st : tty;
  bool prev_type = false;
  bool is_method = (sig->char_at(0) == JVM_SIGNATURE_FUNC);
  if (is_method)  st->put(JVM_SIGNATURE_FUNC);
  for (SignatureStream ss(sig, is_method); !ss.is_done(); ss.next()) {
    if (ss.at_return_type())
      st->put(JVM_SIGNATURE_ENDFUNC);
    else if (prev_type)
      st->put(',');
    const char* cp = (const char*) ss.raw_bytes();
    if (ss.is_array()) {
      st->put(JVM_SIGNATURE_ARRAY);
      if (ss.array_prefix_length() == 1)
        st->put(cp[1]);
      else
        st->put(JVM_SIGNATURE_CLASS);
    } else {
      st->put(cp[0]);
    }
  }
}



static oop object_java_mirror() {
  return vmClasses::Object_klass()->java_mirror();
}

oop MethodHandles::field_name_or_null(Symbol* s) {
  if (s == nullptr)  return nullptr;
  return StringTable::lookup(s);
}

oop MethodHandles::field_signature_type_or_null(Symbol* s) {
  if (s == nullptr)  return nullptr;
  BasicType bt = Signature::basic_type(s);
  if (is_java_primitive(bt)) {
    assert(s->utf8_length() == 1, "");
    return java_lang_Class::primitive_mirror(bt);
  }
  // Here are some more short cuts for common types.
  // They are optional, since reference types can be resolved lazily.
  if (bt == T_OBJECT) {
    if (s == vmSymbols::object_signature()) {
      return object_java_mirror();
    } else if (s == vmSymbols::class_signature()) {
      return vmClasses::Class_klass()->java_mirror();
    } else if (s == vmSymbols::string_signature()) {
      return vmClasses::String_klass()->java_mirror();
    }
  }
  return nullptr;
}

// An unresolved member name is a mere symbolic reference.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller, int lookup_mode,
                                         bool speculative_resolve, TRAPS) {
  Handle empty;
  assert(java_lang_invoke_MemberName::is_instance(mname()), "");

  if (java_lang_invoke_MemberName::vmtarget(mname()) != nullptr) {
    // Already resolved.
    DEBUG_ONLY(intptr_t vmindex = java_lang_invoke_MemberName::vmindex(mname()));
    assert(vmindex >= Method::nonvirtual_vtable_index, "");
    return mname;
  }

  Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
  Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
  Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
  int    flags    =       java_lang_invoke_MemberName::flags(mname());
  int    ref_kind =       (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
  if (!ref_kind_is_valid(ref_kind)) {
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty);
  }

  DEBUG_ONLY(intptr_t old_vmindex);
  assert((old_vmindex = java_lang_invoke_MemberName::vmindex(mname())) == 0, "clean input");

  if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) {
    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty);
  }

  InstanceKlass* defc = nullptr;
  {
    Klass* defc_klass = java_lang_Class::as_Klass(defc_oop());
    if (defc_klass == nullptr)  return empty;  // a primitive; no resolution possible
    if (!defc_klass->is_instance_klass()) {
      if (!defc_klass->is_array_klass())  return empty;
      defc_klass = vmClasses::Object_klass();
    }
    defc = InstanceKlass::cast(defc_klass);
  }
  if (defc == nullptr) {
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty);
  }
  defc->link_class(CHECK_(empty));  // possible safepoint

  // convert the external string name to an internal symbol
  TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str());
  if (name == nullptr)  return empty;  // no such name
  if (name == vmSymbols::class_initializer_name())
    return empty; // illegal name

  vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none;
  if ((flags & ALL_KINDS) == IS_METHOD &&
      (defc == vmClasses::MethodHandle_klass() || defc == vmClasses::VarHandle_klass()) &&
      (ref_kind == JVM_REF_invokeVirtual ||
       ref_kind == JVM_REF_invokeSpecial ||
       // static invocation mode is required for _linkToVirtual, etc.:
       ref_kind == JVM_REF_invokeStatic)) {
    vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
    if (iid != vmIntrinsics::_none &&
        ((ref_kind == JVM_REF_invokeStatic) == is_signature_polymorphic_static(iid))) {
      // Virtual methods invoke and invokeExact, plus internal invokers like _invokeBasic.
      // For a static reference it could an internal linkage routine like _linkToVirtual, etc.
      mh_invoke_id = iid;
    }
  }

  // convert the external string or reflective type to an internal signature
  TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty));
  if (type == nullptr)  return empty;  // no such signature exists in the VM

  // skip access check if it's trusted lookup
  LinkInfo::AccessCheck access_check = caller != nullptr ?
                                              LinkInfo::AccessCheck::required :
                                              LinkInfo::AccessCheck::skip;
  // skip loader constraints if it's trusted lookup or a public lookup
  LinkInfo::LoaderConstraintCheck loader_constraint_check = (caller != nullptr && (lookup_mode & LM_UNCONDITIONAL) == 0) ?
                                              LinkInfo::LoaderConstraintCheck::required :
                                              LinkInfo::LoaderConstraintCheck::skip;

  // Time to do the lookup.
  switch (flags & ALL_KINDS) {
  case IS_METHOD:
    {
      CallInfo result;
      LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
      {
        assert(!HAS_PENDING_EXCEPTION, "");
        if (ref_kind == JVM_REF_invokeStatic) {
          LinkResolver::resolve_static_call(result,
                        link_info, false, THREAD);
        } else if (ref_kind == JVM_REF_invokeInterface) {
          LinkResolver::resolve_interface_call(result, Handle(), defc,
                        link_info, false, THREAD);
        } else if (mh_invoke_id != vmIntrinsics::_none) {
          assert(!is_signature_polymorphic_static(mh_invoke_id), "");
          LinkResolver::resolve_handle_call(result, link_info, THREAD);
        } else if (ref_kind == JVM_REF_invokeSpecial) {
          LinkResolver::resolve_special_call(result, Handle(),
                        link_info, THREAD);
        } else if (ref_kind == JVM_REF_invokeVirtual) {
          LinkResolver::resolve_virtual_call(result, Handle(), defc,
                        link_info, false, THREAD);
        } else {
          assert(false, "ref_kind=%d", ref_kind);
        }
        if (HAS_PENDING_EXCEPTION) {
          if (speculative_resolve) {
            CLEAR_PENDING_EXCEPTION;
          }
          return empty;
        }
      }
      if (result.resolved_appendix().not_null()) {
        // The resolved MemberName must not be accompanied by an appendix argument,
        // since there is no way to bind this value into the MemberName.
        // Caller is responsible to prevent this from happening.
        THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
      }
      result.set_resolved_method_name(CHECK_(empty));
      oop mname2 = init_method_MemberName(mname, result);
      return Handle(THREAD, mname2);
    }
  case IS_CONSTRUCTOR:
    {
      CallInfo result;
      LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
      {
        assert(!HAS_PENDING_EXCEPTION, "");
        if (name == vmSymbols::object_initializer_name()) {
          LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
        } else {
          break;                // will throw after end of switch
        }
        if (HAS_PENDING_EXCEPTION) {
          if (speculative_resolve) {
            CLEAR_PENDING_EXCEPTION;
          }
          return empty;
        }
      }
      assert(result.is_statically_bound(), "");
      result.set_resolved_method_name(CHECK_(empty));
      oop mname2 = init_method_MemberName(mname, result);
      return Handle(THREAD, mname2);
    }
  case IS_FIELD:
    {
      fieldDescriptor result; // find_field initializes fd if found
      {
        assert(!HAS_PENDING_EXCEPTION, "");
        LinkInfo link_info(defc, name, type, caller, LinkInfo::AccessCheck::skip, loader_constraint_check);
        LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
        if (HAS_PENDING_EXCEPTION) {
          if (speculative_resolve) {
            CLEAR_PENDING_EXCEPTION;
          }
          return empty;
        }
      }
      oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind));
      return Handle(THREAD, mname2);
    }
  default:
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
  }

  return empty;
}

// Conversely, a member name which is only initialized from JVM internals
// may have null defc, name, and type fields.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
  assert(java_lang_invoke_MemberName::is_instance(mname()), "");

  bool have_defc = (java_lang_invoke_MemberName::clazz(mname()) != nullptr);
  bool have_name = (java_lang_invoke_MemberName::name(mname()) != nullptr);
  bool have_type = (java_lang_invoke_MemberName::type(mname()) != nullptr);
  int flags      = java_lang_invoke_MemberName::flags(mname());

  if (suppress != 0) {
    if (suppress & _suppress_defc)  have_defc = true;
    if (suppress & _suppress_name)  have_name = true;
    if (suppress & _suppress_type)  have_type = true;
  }

  if (have_defc && have_name && have_type)  return;  // nothing needed

  switch (flags & ALL_KINDS) {
  case IS_METHOD:
  case IS_CONSTRUCTOR:
    {
      Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
      if (vmtarget == nullptr) {
        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
      }
      methodHandle m(THREAD, vmtarget);
      DEBUG_ONLY(vmtarget = nullptr);  // safety
      if (!have_defc) {
        InstanceKlass* defc = m->method_holder();
        java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror());
      }
      if (!have_name) {
        //not java_lang_String::create_from_symbol; let's intern member names
        oop name = StringTable::intern(m->name(), CHECK);
        java_lang_invoke_MemberName::set_name(mname(), name);
      }
      if (!have_type) {
        Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK);
        java_lang_invoke_MemberName::set_type(mname(), type());
      }
      return;
    }
  case IS_FIELD:
    {
      oop clazz = java_lang_invoke_MemberName::clazz(mname());
      if (clazz == nullptr) {
        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand (as field)");
      }
      InstanceKlass* defc = InstanceKlass::cast(java_lang_Class::as_Klass(clazz));
      DEBUG_ONLY(clazz = nullptr);  // safety
      intptr_t vmindex  = java_lang_invoke_MemberName::vmindex(mname());
      bool is_static = ((flags & JVM_ACC_STATIC) != 0);
      fieldDescriptor fd; // find_field initializes fd if found
      if (!defc->find_field_from_offset(checked_cast<int>(vmindex), is_static, &fd))
        break;                  // cannot expand
      if (!have_name) {
        //not java_lang_String::create_from_symbol; let's intern member names
        oop name = StringTable::intern(fd.name(), CHECK);
        java_lang_invoke_MemberName::set_name(mname(), name);
      }
      if (!have_type) {
        // If it is a primitive field type, don't mess with short strings like "I".
        Handle type (THREAD, field_signature_type_or_null(fd.signature()));
        if (type.is_null()) {
          type = java_lang_String::create_from_symbol(fd.signature(), CHECK);
        }
        java_lang_invoke_MemberName::set_type(mname(), type());
      }
      return;
    }
  }
  THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
}

void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
  assert_lock_strong(CodeCache_lock);
  DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site);
  deps.add_dependent_nmethod(nm);
}

void MethodHandles::clean_dependency_context(oop call_site) {
  DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site);
  deps.clean_unloading_dependents();
}

void MethodHandles::mark_dependent_nmethods(DeoptimizationScope* deopt_scope, Handle call_site, Handle target) {
  assert_lock_strong(Compile_lock);

  CallSiteDepChange changes(call_site, target);
  {
    NoSafepointVerifier nsv;
    MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag);

    DependencyContext deps = java_lang_invoke_CallSite::vmdependencies(call_site());
    deps.mark_dependent_nmethods(deopt_scope, changes);
  }
}

void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
  if (log_is_enabled(Info, methodhandles)) {
    const char* name = vmIntrinsics::name_at(iid);
    if (*name == '_')  name += 1;
    const size_t len = strlen(name) + 50;
    char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal);
    const char* suffix = "";
    if (is_signature_polymorphic(iid)) {
      if (is_signature_polymorphic_static(iid))
        suffix = "/static";
      else
        suffix = "/private";
    }
    jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
    trace_method_handle(_masm, qname);
    // LSan appears unable to keep track of qname, ignore it.
    LSAN_IGNORE_OBJECT(qname);
    // Note:  Don't free the allocated char array because it's used
    // during runtime.
  }
}

//
// Here are the native methods in java.lang.invoke.MethodHandleNatives
// They are the private interface between this JVM and the HotSpot-specific
// Java code that implements JSR 292 method handles.
//
// Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
// that intrinsic (non-JNI) native methods are defined in HotSpot.
//

#ifndef PRODUCT
#define EACH_NAMED_CON(template, requirement) \
    template(java_lang_invoke_MemberName,MN_IS_METHOD) \
    template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
    template(java_lang_invoke_MemberName,MN_IS_FIELD) \
    template(java_lang_invoke_MemberName,MN_IS_TYPE) \
    template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
    template(java_lang_invoke_MemberName,MN_TRUSTED_FINAL) \
    template(java_lang_invoke_MemberName,MN_HIDDEN_MEMBER) \
    template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
    template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
    template(java_lang_invoke_MemberName,MN_NESTMATE_CLASS) \
    template(java_lang_invoke_MemberName,MN_HIDDEN_CLASS) \
    template(java_lang_invoke_MemberName,MN_STRONG_LOADER_LINK) \
    template(java_lang_invoke_MemberName,MN_ACCESS_VM_ANNOTATIONS) \
    template(java_lang_invoke_MemberName,MN_MODULE_MODE) \
    template(java_lang_invoke_MemberName,MN_UNCONDITIONAL_MODE) \
    template(java_lang_invoke_MemberName,MN_TRUSTED_MODE) \
    /*end*/

#define IGNORE_REQ(req_expr) /* req_expr */
#define ONE_PLUS(scope,value) 1+
static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
#define VALUE_COMMA(scope,value) scope::value,
static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };
#define STRING_NULL(scope,value) #value "\0"
static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) };

static bool advertise_con_value(int which) {
  if (which < 0)  return false;
  bool ok = true;
  int count = 0;
#define INC_COUNT(scope,value) \
  ++count;
#define CHECK_REQ(req_expr) \
  if (which < count)  return ok; \
  ok = (req_expr);
  EACH_NAMED_CON(INC_COUNT, CHECK_REQ);
#undef INC_COUNT
#undef CHECK_REQ
  assert(count == con_value_count, "");
  if (which < count)  return ok;
  return false;
}

#undef ONE_PLUS
#undef VALUE_COMMA
#undef STRING_NULL
#undef EACH_NAMED_CON
#endif // PRODUCT

JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
#ifndef PRODUCT
  if (advertise_con_value(which)) {
    assert(which >= 0 && which < con_value_count, "");
    int con = con_values[which];
    objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
    if (box.not_null() && box->klass() == Universe::objectArrayKlass() && box->length() > 0) {
      const char* str = &con_names[0];
      for (int i = 0; i < which; i++)
        str += strlen(str) + 1;   // skip name and null
      oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
      box->obj_at_put(0, name);
    }
    return con;
  }
#endif
  return 0;
}
JVM_END

// void init(MemberName self, AccessibleObject ref)
JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
  if (mname_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
  if (target_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  MethodHandles::init_MemberName(mname, target, CHECK);
}
JVM_END

// void expand(MemberName self)
JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  if (mname_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  MethodHandles::expand_MemberName(mname, 0, CHECK);
}
JVM_END

// void resolve(MemberName self, Class<?> caller)
JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh,
    jint lookup_mode, jboolean speculative_resolve)) {
  if (mname_jh == nullptr) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));

  // The trusted Java code that calls this method should already have performed
  // access checks on behalf of the given caller.  But, we can verify this.
  // This only verifies from the context of the lookup class.  It does not
  // verify the lookup context for a Lookup object teleported from one module
  // to another. Such Lookup object can only access the intersection of the set
  // of accessible classes from both lookup class and previous lookup class.
  if (VerifyMethodHandles && (lookup_mode & LM_TRUSTED) == LM_TRUSTED && caller_jh != nullptr &&
      java_lang_invoke_MemberName::clazz(mname()) != nullptr) {
    Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
    if (reference_klass != nullptr && reference_klass->is_objArray_klass()) {
      reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass();
    }

    // Reflection::verify_class_access can only handle instance classes.
    if (reference_klass != nullptr && reference_klass->is_instance_klass()) {
      // Emulate LinkResolver::check_klass_accessability.
      Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
      // access check on behalf of the caller if this is not a public lookup
      // i.e. lookup mode is not UNCONDITIONAL
      if ((lookup_mode & LM_UNCONDITIONAL) == 0
          && Reflection::verify_class_access(caller,
                                             InstanceKlass::cast(reference_klass),
                                             true) != Reflection::ACCESS_OK) {
        ResourceMark rm(THREAD);
        stringStream ss;
        ss.print("caller %s tried to access %s", caller->class_in_module_of_loader(),
                 reference_klass->class_in_module_of_loader());
        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), ss.as_string());
      }
    }
  }

  Klass* caller = caller_jh == nullptr ? nullptr :
                     java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
  Handle resolved = MethodHandles::resolve_MemberName(mname, caller, lookup_mode,
                                                      speculative_resolve == JNI_TRUE,
                                                      CHECK_NULL);

  if (resolved.is_null()) {
    int flags = java_lang_invoke_MemberName::flags(mname());
    int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
    if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format");
    }
    if (speculative_resolve) {
      assert(!HAS_PENDING_EXCEPTION, "No exceptions expected when resolving speculatively");
      return nullptr;
    }
    if ((flags & ALL_KINDS) == IS_FIELD) {
      THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
    } else if ((flags & ALL_KINDS) == IS_METHOD ||
               (flags & ALL_KINDS) == IS_CONSTRUCTOR) {
      THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
    } else {
      THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
    }
  }

  return JNIHandles::make_local(THREAD, resolved());
}
JVM_END

static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
  if (mname == nullptr ||
      java_lang_invoke_MemberName::clazz(mname) == nullptr) {
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
  } else {
    int flags = java_lang_invoke_MemberName::flags(mname);
    if ((flags & IS_FIELD) != 0 &&
        (must_be_static
         ? (flags & JVM_ACC_STATIC) != 0
         : (flags & JVM_ACC_STATIC) == 0)) {
      intptr_t vmindex = java_lang_invoke_MemberName::vmindex(mname);
      return (jlong) vmindex;
    }
  }
  const char* msg = (must_be_static ? "static field required" : "non-static field required");
  THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg);
  return 0;
}

JVM_ENTRY(jlong, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD);
}
JVM_END

JVM_ENTRY(jlong, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD);
}
JVM_END

JVM_ENTRY(jobject, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  // use the other function to perform sanity checks:
  jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL);
  oop clazz = java_lang_invoke_MemberName::clazz(JNIHandles::resolve_non_null(mname_jh));
  return JNIHandles::make_local(THREAD, clazz);
}
JVM_END

JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  if (mname_jh == nullptr)  return nullptr;
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  intptr_t vmindex  = java_lang_invoke_MemberName::vmindex(mname());
  objArrayHandle result = oopFactory::new_objArray_handle(vmClasses::Object_klass(), 2, CHECK_NULL);
  jvalue vmindex_value; vmindex_value.j = (long)vmindex;
  oop x = java_lang_boxing_object::create(T_LONG, &vmindex_value, CHECK_NULL);
  result->obj_at_put(0, x);

  int flags = java_lang_invoke_MemberName::flags(mname());
  if ((flags & IS_FIELD) != 0) {
    x = java_lang_invoke_MemberName::clazz(mname());
  } else {
    Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
    assert(vmtarget != nullptr && vmtarget->is_method(), "vmtarget is only method");
    x = mname();
  }
  result->obj_at_put(1, x);
  return JNIHandles::make_local(THREAD, result());
}
JVM_END

JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
  Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
  Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
  DeoptimizationScope deopt_scope;
  {
    // Walk all nmethods depending on this call site.
    MutexLocker mu(thread, Compile_lock);
    MethodHandles::mark_dependent_nmethods(&deopt_scope, call_site, target);
    java_lang_invoke_CallSite::set_target(call_site(), target());
    // This is assumed to be an 'atomic' operation by verification.
    // So keep it under lock for now.
    deopt_scope.deoptimize_marked();
  }
}
JVM_END

JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
  Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
  Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
  DeoptimizationScope deopt_scope;
  {
    // Walk all nmethods depending on this call site.
    MutexLocker mu(thread, Compile_lock);
    MethodHandles::mark_dependent_nmethods(&deopt_scope, call_site, target);
    java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
    // This is assumed to be an 'atomic' operation by verification.
    // So keep it under lock for now.
    deopt_scope.deoptimize_marked();
  }
}
JVM_END

JVM_ENTRY(void, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
                                              jobject caller_jh, jintArray index_info_jh,
                                              jint start, jint end,
                                              jobjectArray buf_jh, jint pos,
                                              jboolean resolve, jobject ifna_jh)) {
  // caller->constants->copy_bootstrap_arguments_at performs a runtime
  // range check, but let's assert earlier as well.
  assert(start < end && start >= 0, "invariant");
  Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller_jh));
  if (caller_k == nullptr || !caller_k->is_instance_klass()) {
      THROW_MSG(vmSymbols::java_lang_InternalError(), "bad caller");
  }
  InstanceKlass* caller = InstanceKlass::cast(caller_k);
  typeArrayOop index_info_oop = (typeArrayOop) JNIHandles::resolve(index_info_jh);
  if (index_info_oop == nullptr ||
      index_info_oop->klass() != Universe::intArrayKlass() ||
      typeArrayOop(index_info_oop)->length() < 2) {
      THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (0)");
  }
  typeArrayHandle index_info(THREAD, index_info_oop);
  int bss_index_in_pool = index_info->int_at(1);
  // While we are here, take a quick look at the index info:
  if (bss_index_in_pool <= 0 ||
      bss_index_in_pool >= caller->constants()->length() ||
      index_info->int_at(0)
      != caller->constants()->bootstrap_argument_count_at(bss_index_in_pool)) {
      THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (1)");
  }

  objArrayHandle buf(THREAD, (objArrayOop)JNIHandles::resolve(buf_jh));

  Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
  caller->constants()->
    copy_bootstrap_arguments_at(bss_index_in_pool,
                                start, end, buf, pos,
                                (resolve == JNI_TRUE), ifna, CHECK);
}
JVM_END

/**
 * Throws a java/lang/UnsupportedOperationException unconditionally.
 * This is required by the specification of MethodHandle.invoke if
 * invoked directly.
 */
JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
  THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
  return nullptr;
}
JVM_END

/**
 * Throws a java/lang/UnsupportedOperationException unconditionally.
 * This is required by the specification of MethodHandle.invokeExact if
 * invoked directly.
 */
JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
  THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
  return nullptr;
}
JVM_END

/**
 * Throws a java/lang/UnsupportedOperationException unconditionally.
 * This is required by the specification of VarHandle.{access-mode} if
 * invoked directly.
 */
JVM_ENTRY(jobject, VH_UOE(JNIEnv* env, jobject vh, jobjectArray args)) {
  THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "VarHandle access mode methods cannot be invoked reflectively");
  return nullptr;
}
JVM_END


/// JVM_RegisterMethodHandleMethods

#define LANG "Ljava/lang/"
#define JLINV "Ljava/lang/invoke/"

#define OBJ   LANG "Object;"
#define CLS   LANG "Class;"
#define STRG  LANG "String;"
#define CS    JLINV "CallSite;"
#define MT    JLINV "MethodType;"
#define MH    JLINV "MethodHandle;"
#define MEM   JLINV "MemberName;"

#define CC (char*)  /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)

// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod MHN_methods[] = {
  {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
  {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
  {CC "resolve",                   CC "(" MEM "" CLS "IZ)" MEM,              FN_PTR(MHN_resolve_Mem)},
  //  static native int getNamedCon(int which, Object[] name)
  {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
  {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
  {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
  {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
  {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
  {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
  {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
  {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                       FN_PTR(MHN_getMemberVMInfo)}
};

static JNINativeMethod MH_methods[] = {
  // UnsupportedOperationException throwers
  {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
  {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
};
static JNINativeMethod VH_methods[] = {
  // UnsupportedOperationException throwers
  {CC "get",                        CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "set",                        CC "([" OBJ ")V",       FN_PTR(VH_UOE)},
  {CC "getVolatile",                CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "setVolatile",                CC "([" OBJ ")V",       FN_PTR(VH_UOE)},
  {CC "getAcquire",                 CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "setRelease",                 CC "([" OBJ ")V",       FN_PTR(VH_UOE)},
  {CC "getOpaque",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "setOpaque",                  CC "([" OBJ ")V",       FN_PTR(VH_UOE)},
  {CC "compareAndSet",              CC "([" OBJ ")Z",       FN_PTR(VH_UOE)},
  {CC "compareAndExchange",         CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "compareAndExchangeAcquire",  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "compareAndExchangeRelease",  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "weakCompareAndSetPlain",     CC "([" OBJ ")Z",       FN_PTR(VH_UOE)},
  {CC "weakCompareAndSet",          CC "([" OBJ ")Z",       FN_PTR(VH_UOE)},
  {CC "weakCompareAndSetAcquire",   CC "([" OBJ ")Z",       FN_PTR(VH_UOE)},
  {CC "weakCompareAndSetRelease",   CC "([" OBJ ")Z",       FN_PTR(VH_UOE)},
  {CC "getAndSet",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndSetAcquire",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndSetRelease",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndAdd",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndAddAcquire",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndAddRelease",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseOr",            CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseOrAcquire",     CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseOrRelease",     CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseAnd",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseAndAcquire",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseAndRelease",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseXor",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseXorAcquire",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
  {CC "getAndBitwiseXorRelease",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)}
};

/**
 * This one function is exported, used by NativeLookup.
 */
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
  assert(!MethodHandles::enabled(), "must not be enabled");
  assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
  assert(vmClasses::VarHandle_klass() != nullptr, "should be present");

  oop mh_mirror = vmClasses::MethodHandle_klass()->java_mirror();
  oop vh_mirror = vmClasses::VarHandle_klass()->java_mirror();
  jclass MH_class = (jclass) JNIHandles::make_local(THREAD, mh_mirror);
  jclass VH_class = (jclass) JNIHandles::make_local(THREAD, vh_mirror);

  {
    ThreadToNativeFromVM ttnfv(thread);

    int status = env->RegisterNatives(MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
    guarantee(status == JNI_OK && !env->ExceptionCheck(),
              "register java.lang.invoke.MethodHandleNative natives");

    status = env->RegisterNatives(MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
    guarantee(status == JNI_OK && !env->ExceptionCheck(),
              "register java.lang.invoke.MethodHandle natives");

    status = env->RegisterNatives(VH_class, VH_methods, sizeof(VH_methods)/sizeof(JNINativeMethod));
    guarantee(status == JNI_OK && !env->ExceptionCheck(),
              "register java.lang.invoke.VarHandle natives");
  }

  log_debug(methodhandles, indy)("MethodHandle support loaded (using LambdaForms)");

  MethodHandles::set_enabled(true);
}
JVM_END
