hotspot/src/share/vm/prims/methodHandles.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 4094 1f424b2b2171
child 4429 d7eb4e2099aa
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     1
/*
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     2
 * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     4
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     7
 * published by the Free Software Foundation.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     8
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    13
 * accompanied this code).
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    14
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    18
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    21
 * have any questions.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    22
 *
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    23
 */
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    24
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    25
/*
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    26
 * JSR 292 reference implementation: method handles
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    27
 */
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    28
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    29
#include "incls/_precompiled.incl"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    30
#include "incls/_methodHandles.cpp.incl"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    31
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    32
bool MethodHandles::_enabled = false; // set true after successful native linkage
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    33
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    34
MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL};
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    35
const char*        MethodHandles::_entry_names[_EK_LIMIT+1] = {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
    36
  "raise_exception",
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    37
  "invokestatic",               // how a MH emulates invokestatic
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    38
  "invokespecial",              // ditto for the other invokes...
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    39
  "invokevirtual",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    40
  "invokeinterface",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    41
  "bound_ref",                  // these are for BMH...
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    42
  "bound_int",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    43
  "bound_long",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    44
  "bound_ref_direct",           // (direct versions have a direct methodOop)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    45
  "bound_int_direct",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    46
  "bound_long_direct",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    47
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    48
  // starting at _adapter_mh_first:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    49
  "adapter_retype_only",       // these are for AMH...
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
    50
  "adapter_retype_raw",
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    51
  "adapter_check_cast",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    52
  "adapter_prim_to_prim",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    53
  "adapter_ref_to_prim",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    54
  "adapter_prim_to_ref",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    55
  "adapter_swap_args",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    56
  "adapter_rot_args",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    57
  "adapter_dup_args",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    58
  "adapter_drop_args",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    59
  "adapter_collect_args",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    60
  "adapter_spread_args",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    61
  "adapter_flyby",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    62
  "adapter_ricochet",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    63
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    64
  // optimized adapter types:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    65
  "adapter_swap_args/1",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    66
  "adapter_swap_args/2",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    67
  "adapter_rot_args/1,up",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    68
  "adapter_rot_args/1,down",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    69
  "adapter_rot_args/2,up",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    70
  "adapter_rot_args/2,down",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    71
  "adapter_prim_to_prim/i2i",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    72
  "adapter_prim_to_prim/l2i",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    73
  "adapter_prim_to_prim/d2f",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    74
  "adapter_prim_to_prim/i2l",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    75
  "adapter_prim_to_prim/f2d",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    76
  "adapter_ref_to_prim/unboxi",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    77
  "adapter_ref_to_prim/unboxl",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    78
  "adapter_spread_args/0",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    79
  "adapter_spread_args/1",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    80
  "adapter_spread_args/more",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    81
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    82
  NULL
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    83
};
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    84
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
    85
jobject MethodHandles::_raise_exception_method;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
    86
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    87
#ifdef ASSERT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    88
bool MethodHandles::spot_check_entry_names() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    89
  assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    90
  assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    91
  assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    92
  assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    93
  assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    94
  return true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    95
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    96
#endif
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    97
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    98
void MethodHandles::set_enabled(bool z) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
    99
  if (_enabled != z) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   100
    guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   101
    _enabled = z;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   102
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   103
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   104
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   105
// Note: A method which does not have a TRAPS argument cannot block in the GC
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   106
// or throw exceptions.  Such methods are used in this file to do something quick
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   107
// and local, like parse a data structure.  For speed, such methods work on plain
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   108
// oops, not handles.  Trapping methods uniformly operate on handles.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   109
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   110
methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   111
                                         klassOop& receiver_limit_result, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   112
  if (vmtarget == NULL)  return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   113
  assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   114
  if (vmindex < 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   115
    // this DMH performs no dispatch; it is directly bound to a methodOop
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   116
    // A MemberName may either be directly bound to a methodOop,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   117
    // or it may use the klass/index form; both forms mean the same thing.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   118
    methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   119
    if ((decode_flags_result & _dmf_has_receiver) != 0
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   120
        && java_dyn_MethodType::is_instance(mtype)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   121
      // Extract receiver type restriction from mtype.ptypes[0].
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   122
      objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   123
      oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   124
      if (java_lang_Class::is_instance(ptype0))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   125
        receiver_limit_result = java_lang_Class::as_klassOop(ptype0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   126
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   127
    if (vmindex == methodOopDesc::nonvirtual_vtable_index) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   128
      // this DMH can be an "invokespecial" version
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   129
      decode_flags_result &= ~_dmf_does_dispatch;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   130
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   131
      assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   132
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   133
    return m;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   134
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   135
    decode_flags_result |= MethodHandles::_dmf_does_dispatch;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   136
    assert(vmtarget->is_klass(), "must be class or interface");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   137
    receiver_limit_result = (klassOop)vmtarget;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   138
    Klass* tk = Klass::cast((klassOop)vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   139
    if (tk->is_interface()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   140
      // an itable linkage is <interface, itable index>
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   141
      decode_flags_result |= MethodHandles::_dmf_from_interface;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   142
      return klassItable::method_for_itable_index((klassOop)vmtarget, vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   143
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   144
      if (!tk->oop_is_instance())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   145
        tk = instanceKlass::cast(SystemDictionary::object_klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   146
      return ((instanceKlass*)tk)->method_at_vtable(vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   147
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   148
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   149
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   150
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   151
// MemberName and DirectMethodHandle have the same linkage to the JVM internals.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   152
// (MemberName is the non-operational name used for queries and setup.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   153
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   154
methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   155
  oop vmtarget = sun_dyn_DirectMethodHandle::vmtarget(mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   156
  int vmindex  = sun_dyn_DirectMethodHandle::vmindex(mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   157
  oop mtype    = sun_dyn_DirectMethodHandle::type(mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   158
  return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   159
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   160
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   161
methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   162
  assert(sun_dyn_BoundMethodHandle::is_instance(mh), "");
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   163
  assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   164
  for (oop bmh = mh;;) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   165
    // Bound MHs can be stacked to bind several arguments.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   166
    oop target = java_dyn_MethodHandle::vmtarget(bmh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   167
    if (target == NULL)  return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   168
    decode_flags_result |= MethodHandles::_dmf_binds_argument;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   169
    klassOop tk = target->klass();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   170
    if (tk == SystemDictionary::BoundMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   171
      bmh = target;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   172
      continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   173
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   174
      if (java_dyn_MethodHandle::is_subclass(tk)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   175
        //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   176
        return decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   177
      } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   178
        // Optimized case:  binding a receiver to a non-dispatched DMH
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   179
        // short-circuits directly to the methodOop.
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   180
        // (It might be another argument besides a receiver also.)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   181
        assert(target->is_method(), "must be a simple method");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   182
        methodOop m = (methodOop) target;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   183
        decode_flags_result |= MethodHandles::_dmf_binds_method;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   184
        return m;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   185
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   186
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   187
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   188
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   189
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   190
methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   191
  assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   192
  for (oop amh = mh;;) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   193
    // Adapter MHs can be stacked to convert several arguments.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   194
    int conv_op = adapter_conversion_op(sun_dyn_AdapterMethodHandle::conversion(amh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   195
    decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   196
    oop target = java_dyn_MethodHandle::vmtarget(amh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   197
    if (target == NULL)  return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   198
    klassOop tk = target->klass();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   199
    if (tk == SystemDictionary::AdapterMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   200
      amh = target;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   201
      continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   202
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   203
      // must be a BMH (which will bind some more arguments) or a DMH (for the final call)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   204
      return MethodHandles::decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   205
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   206
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   207
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   208
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   209
methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   210
  if (mh == NULL)  return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   211
  klassOop mhk = mh->klass();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   212
  assert(java_dyn_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   213
  if (mhk == SystemDictionary::DirectMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   214
    return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   215
  } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   216
    return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   217
  } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   218
    return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result);
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   219
  } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   220
    // could be a JavaMethodHandle (but not an adapter MH)
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   221
    return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   222
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   223
    assert(false, "cannot parse this MH");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   224
    return NULL;              // random MH?
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   225
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   226
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   227
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   228
methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   229
  assert(m->is_method(), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   230
  if (m->is_static()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   231
    // check that signature begins '(L' or '([' (not '(I', '()', etc.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   232
    symbolOop sig = m->signature();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   233
    BasicType recv_bt = char2type(sig->byte_at(1));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   234
    // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')'
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   235
    assert(sig->byte_at(0) == '(', "must be method sig");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   236
    if (recv_bt == T_OBJECT || recv_bt == T_ARRAY)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   237
      decode_flags_result |= _dmf_has_receiver;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   238
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   239
    // non-static method
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   240
    decode_flags_result |= _dmf_has_receiver;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   241
    if (!m->can_be_statically_bound() && !m->is_initializer()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   242
      decode_flags_result |= _dmf_does_dispatch;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   243
      if (Klass::cast(m->method_holder())->is_interface())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   244
        decode_flags_result |= _dmf_from_interface;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   245
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   246
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   247
  return m;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   248
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   249
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   250
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   251
// A trusted party is handing us a cookie to determine a method.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   252
// Let's boil it down to the method oop they really want.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   253
methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   254
  decode_flags_result = 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   255
  receiver_limit_result = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   256
  klassOop xk = x->klass();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   257
  if (xk == Universe::methodKlassObj()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   258
    return decode_methodOop((methodOop) x, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   259
  } else if (xk == SystemDictionary::MemberName_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   260
    // Note: This only works if the MemberName has already been resolved.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   261
    return decode_MemberName(x, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   262
  } else if (java_dyn_MethodHandle::is_subclass(xk)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   263
    return decode_MethodHandle(x, receiver_limit_result, decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   264
  } else if (xk == SystemDictionary::reflect_method_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   265
    oop clazz  = java_lang_reflect_Method::clazz(x);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   266
    int slot   = java_lang_reflect_Method::slot(x);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   267
    klassOop k = java_lang_Class::as_klassOop(clazz);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   268
    if (k != NULL && Klass::cast(k)->oop_is_instance())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   269
      return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   270
                              decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   271
  } else if (xk == SystemDictionary::reflect_constructor_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   272
    oop clazz  = java_lang_reflect_Constructor::clazz(x);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   273
    int slot   = java_lang_reflect_Constructor::slot(x);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   274
    klassOop k = java_lang_Class::as_klassOop(clazz);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   275
    if (k != NULL && Klass::cast(k)->oop_is_instance())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   276
      return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   277
                              decode_flags_result);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   278
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   279
    // unrecognized object
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   280
    assert(!x->is_method(), "already checked");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   281
    assert(!sun_dyn_MemberName::is_instance(x), "already checked");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   282
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   283
  return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   284
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   285
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   286
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   287
int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   288
  if (mh->klass() == SystemDictionary::DirectMethodHandle_klass())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   289
    return 0;                   // no push/pop
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   290
  int this_vmslots = java_dyn_MethodHandle::vmslots(mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   291
  int last_vmslots = 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   292
  oop last_mh = mh;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   293
  for (;;) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   294
    oop target = java_dyn_MethodHandle::vmtarget(last_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   295
    if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   296
      last_vmslots = java_dyn_MethodHandle::vmslots(target);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   297
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   298
    } else if (!java_dyn_MethodHandle::is_instance(target)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   299
      // might be klass or method
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   300
      assert(target->is_method(), "must get here with a direct ref to method");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   301
      last_vmslots = methodOop(target)->size_of_parameters();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   302
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   303
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   304
    last_mh = target;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   305
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   306
  // If I am called with fewer VM slots than my ultimate callee,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   307
  // it must be that I push the additionally needed slots.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   308
  // Likewise if am called with more VM slots, I will pop them.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   309
  return (last_vmslots - this_vmslots);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   310
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   311
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   312
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   313
// MemberName support
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   314
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   315
// import sun_dyn_MemberName.*
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   316
enum {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   317
  IS_METHOD      = sun_dyn_MemberName::MN_IS_METHOD,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   318
  IS_CONSTRUCTOR = sun_dyn_MemberName::MN_IS_CONSTRUCTOR,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   319
  IS_FIELD       = sun_dyn_MemberName::MN_IS_FIELD,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   320
  IS_TYPE        = sun_dyn_MemberName::MN_IS_TYPE,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   321
  SEARCH_SUPERCLASSES = sun_dyn_MemberName::MN_SEARCH_SUPERCLASSES,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   322
  SEARCH_INTERFACES   = sun_dyn_MemberName::MN_SEARCH_INTERFACES,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   323
  ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   324
  VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   325
};
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   326
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   327
void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   328
  if (target_oop->klass() == SystemDictionary::reflect_field_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   329
    oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   330
    int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   331
    int mods  = java_lang_reflect_Field::modifiers(target_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   332
    klassOop k = java_lang_Class::as_klassOop(clazz);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   333
    int offset = instanceKlass::cast(k)->offset_from_fields(slot);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   334
    init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   335
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   336
    int decode_flags = 0; klassOop receiver_limit = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   337
    methodOop m = MethodHandles::decode_method(target_oop,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   338
                                               receiver_limit, decode_flags);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   339
    bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   340
    init_MemberName(mname_oop, m, do_dispatch);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   341
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   342
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   343
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   344
void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   345
  int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   346
               | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   347
  oop vmtarget = m;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   348
  int vmindex  = methodOopDesc::invalid_vtable_index;  // implies no info yet
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   349
  if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   350
    vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   351
  assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   352
  sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   353
  sun_dyn_MemberName::set_vmindex(mname_oop,  vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   354
  sun_dyn_MemberName::set_flags(mname_oop,    flags);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   355
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   356
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   357
void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   358
  int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   359
  oop vmtarget = field_holder;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   360
  int vmindex  = offset;  // implies no info yet
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   361
  assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   362
  sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   363
  sun_dyn_MemberName::set_vmindex(mname_oop,  vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   364
  sun_dyn_MemberName::set_flags(mname_oop,    flags);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   365
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   366
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   367
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   368
methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   369
  int flags  = sun_dyn_MemberName::flags(mname);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   370
  if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0)  return NULL;  // not invocable
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   371
  oop vmtarget = sun_dyn_MemberName::vmtarget(mname);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   372
  int vmindex  = sun_dyn_MemberName::vmindex(mname);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   373
  if (vmindex == VM_INDEX_UNINITIALIZED)  return NULL; // not resolved
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   374
  methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   375
  oop clazz = sun_dyn_MemberName::clazz(mname);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   376
  if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   377
    klassOop klass = java_lang_Class::as_klassOop(clazz);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   378
    if (klass != NULL)  receiver_limit_result = klass;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   379
  }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   380
  return m;
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   381
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   382
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   383
// An unresolved member name is a mere symbolic reference.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   384
// Resolving it plants a vmtarget/vmindex in it,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   385
// which refers dirctly to JVM internals.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   386
void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   387
  assert(sun_dyn_MemberName::is_instance(mname()), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   388
#ifdef ASSERT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   389
  // If this assert throws, renegotiate the sentinel value used by the Java code,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   390
  // so that it is distinct from any valid vtable index value, and any special
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   391
  // values defined in methodOopDesc::VtableIndexFlag.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   392
  // The point of the slop is to give the Java code and the JVM some room
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   393
  // to independently specify sentinel values.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   394
  const int sentinel_slop  = 10;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   395
  const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   396
  assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   397
#endif
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   398
  if (sun_dyn_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   399
    return;  // already resolved
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   400
  oop defc_oop = sun_dyn_MemberName::clazz(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   401
  oop name_str = sun_dyn_MemberName::name(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   402
  oop type_str = sun_dyn_MemberName::type(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   403
  int flags    = sun_dyn_MemberName::flags(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   404
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   405
  if (defc_oop == NULL || name_str == NULL || type_str == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   406
    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   407
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   408
  klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   409
  defc_oop = NULL;  // safety
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   410
  if (defc_klassOop == NULL)  return;  // a primitive; no resolution possible
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   411
  if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   412
    if (!Klass::cast(defc_klassOop)->oop_is_array())  return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   413
    defc_klassOop = SystemDictionary::object_klass();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   414
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   415
  instanceKlassHandle defc(THREAD, defc_klassOop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   416
  defc_klassOop = NULL;  // safety
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   417
  if (defc.is_null()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   418
    THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   419
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   420
  defc->link_class(CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   421
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   422
  // convert the external string name to an internal symbol
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   423
  symbolHandle name(THREAD, java_lang_String::as_symbol_or_null(name_str));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   424
  if (name.is_null())  return;  // no such name
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   425
  name_str = NULL;  // safety
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   426
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   427
  // convert the external string or reflective type to an internal signature
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   428
  bool force_signature = (name() == vmSymbols::invoke_name());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   429
  symbolHandle type; {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   430
    symbolOop type_sym = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   431
    if (java_dyn_MethodType::is_instance(type_str)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   432
      type_sym = java_dyn_MethodType::as_signature(type_str, force_signature, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   433
    } else if (java_lang_Class::is_instance(type_str)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   434
      type_sym = java_lang_Class::as_signature(type_str, force_signature, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   435
    } else if (java_lang_String::is_instance(type_str)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   436
      if (force_signature) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   437
        type     = java_lang_String::as_symbol(type_str, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   438
      } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   439
        type_sym = java_lang_String::as_symbol_or_null(type_str);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   440
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   441
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   442
      THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized type");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   443
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   444
    if (type_sym != NULL)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   445
      type = symbolHandle(THREAD, type_sym);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   446
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   447
  if (type.is_null())  return;  // no such signature exists in the VM
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   448
  type_str = NULL; // safety
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   449
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   450
  // Time to do the lookup.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   451
  switch (flags & ALL_KINDS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   452
  case IS_METHOD:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   453
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   454
      CallInfo result;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   455
      {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   456
        EXCEPTION_MARK;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   457
        if ((flags & JVM_ACC_STATIC) != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   458
          LinkResolver::resolve_static_call(result,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   459
                        defc, name, type, KlassHandle(), false, false, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   460
        } else if (defc->is_interface()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   461
          LinkResolver::resolve_interface_call(result, Handle(), defc,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   462
                        defc, name, type, KlassHandle(), false, false, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   463
        } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   464
          LinkResolver::resolve_virtual_call(result, Handle(), defc,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   465
                        defc, name, type, KlassHandle(), false, false, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   466
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   467
        if (HAS_PENDING_EXCEPTION) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   468
          CLEAR_PENDING_EXCEPTION;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   469
          return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   470
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   471
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   472
      methodHandle m = result.resolved_method();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   473
      oop vmtarget = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   474
      int vmindex = methodOopDesc::nonvirtual_vtable_index;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   475
      if (defc->is_interface()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   476
        vmindex = klassItable::compute_itable_index(m());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   477
        assert(vmindex >= 0, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   478
      } else if (result.has_vtable_index()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   479
        vmindex = result.vtable_index();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   480
        assert(vmindex >= 0, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   481
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   482
      assert(vmindex != VM_INDEX_UNINITIALIZED, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   483
      if (vmindex < 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   484
        assert(result.is_statically_bound(), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   485
        vmtarget = m();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   486
      } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   487
        vmtarget = result.resolved_klass()->as_klassOop();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   488
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   489
      int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   490
      sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   491
      sun_dyn_MemberName::set_vmindex(mname(),  vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   492
      sun_dyn_MemberName::set_modifiers(mname(), mods);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   493
      DEBUG_ONLY(int junk; klassOop junk2);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   494
      assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   495
             "properly stored for later decoding");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   496
      return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   497
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   498
  case IS_CONSTRUCTOR:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   499
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   500
      CallInfo result;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   501
      {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   502
        EXCEPTION_MARK;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   503
        if (name() == vmSymbols::object_initializer_name()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   504
          LinkResolver::resolve_special_call(result,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   505
                        defc, name, type, KlassHandle(), false, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   506
        } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   507
          break;                // will throw after end of switch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   508
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   509
        if (HAS_PENDING_EXCEPTION) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   510
          CLEAR_PENDING_EXCEPTION;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   511
          return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   512
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   513
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   514
      assert(result.is_statically_bound(), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   515
      methodHandle m = result.resolved_method();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   516
      oop vmtarget = m();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   517
      int vmindex  = methodOopDesc::nonvirtual_vtable_index;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   518
      int mods     = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   519
      sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   520
      sun_dyn_MemberName::set_vmindex(mname(),  vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   521
      sun_dyn_MemberName::set_modifiers(mname(), mods);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   522
      DEBUG_ONLY(int junk; klassOop junk2);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   523
      assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   524
             "properly stored for later decoding");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   525
      return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   526
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   527
  case IS_FIELD:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   528
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   529
      // This is taken from LinkResolver::resolve_field, sans access checks.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   530
      fieldDescriptor fd; // find_field initializes fd if found
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   531
      KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name(), type(), &fd));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   532
      // check if field exists; i.e., if a klass containing the field def has been selected
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   533
      if (sel_klass.is_null())  return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   534
      oop vmtarget = sel_klass->as_klassOop();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   535
      int vmindex  = fd.offset();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   536
      int mods     = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   537
      if (vmindex == VM_INDEX_UNINITIALIZED)  break;  // should not happen
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   538
      sun_dyn_MemberName::set_vmtarget(mname(),  vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   539
      sun_dyn_MemberName::set_vmindex(mname(),   vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   540
      sun_dyn_MemberName::set_modifiers(mname(), mods);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   541
      return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   542
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   543
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   544
  THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   545
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   546
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   547
// Conversely, a member name which is only initialized from JVM internals
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   548
// may have null defc, name, and type fields.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   549
// Resolving it plants a vmtarget/vmindex in it,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   550
// which refers directly to JVM internals.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   551
void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   552
  assert(sun_dyn_MemberName::is_instance(mname()), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   553
  oop vmtarget = sun_dyn_MemberName::vmtarget(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   554
  int vmindex  = sun_dyn_MemberName::vmindex(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   555
  if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   556
    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   557
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   558
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   559
  bool have_defc = (sun_dyn_MemberName::clazz(mname()) != NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   560
  bool have_name = (sun_dyn_MemberName::name(mname()) != NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   561
  bool have_type = (sun_dyn_MemberName::type(mname()) != NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   562
  int flags      = sun_dyn_MemberName::flags(mname());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   563
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   564
  if (suppress != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   565
    if (suppress & _suppress_defc)  have_defc = true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   566
    if (suppress & _suppress_name)  have_name = true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   567
    if (suppress & _suppress_type)  have_type = true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   568
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   569
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   570
  if (have_defc && have_name && have_type)  return;  // nothing needed
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   571
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   572
  switch (flags & ALL_KINDS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   573
  case IS_METHOD:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   574
  case IS_CONSTRUCTOR:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   575
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   576
      klassOop receiver_limit = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   577
      int      decode_flags   = 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   578
      methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   579
                                             receiver_limit, decode_flags));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   580
      if (m.is_null())  break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   581
      if (!have_defc) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   582
        klassOop defc = m->method_holder();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   583
        if (receiver_limit != NULL && receiver_limit != defc
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   584
            && Klass::cast(receiver_limit)->is_subtype_of(defc))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   585
          defc = receiver_limit;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   586
        sun_dyn_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   587
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   588
      if (!have_name) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   589
        //not java_lang_String::create_from_symbol; let's intern member names
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   590
        Handle name = StringTable::intern(m->name(), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   591
        sun_dyn_MemberName::set_name(mname(), name());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   592
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   593
      if (!have_type) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   594
        Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   595
        sun_dyn_MemberName::set_type(mname(), type());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   596
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   597
      return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   598
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   599
  case IS_FIELD:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   600
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   601
      // This is taken from LinkResolver::resolve_field, sans access checks.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   602
      if (!vmtarget->is_klass())  break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   603
      if (!Klass::cast((klassOop) vmtarget)->oop_is_instance())  break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   604
      instanceKlassHandle defc(THREAD, (klassOop) vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   605
      bool is_static = ((flags & JVM_ACC_STATIC) != 0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   606
      fieldDescriptor fd; // find_field initializes fd if found
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   607
      if (!defc->find_field_from_offset(vmindex, is_static, &fd))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   608
        break;                  // cannot expand
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   609
      if (!have_defc) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   610
        sun_dyn_MemberName::set_clazz(mname(), defc->java_mirror());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   611
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   612
      if (!have_name) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   613
        //not java_lang_String::create_from_symbol; let's intern member names
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   614
        Handle name = StringTable::intern(fd.name(), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   615
        sun_dyn_MemberName::set_name(mname(), name());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   616
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   617
      if (!have_type) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   618
        Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   619
        sun_dyn_MemberName::set_type(mname(), type());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   620
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   621
      return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   622
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   623
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   624
  THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   625
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   626
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   627
int MethodHandles::find_MemberNames(klassOop k,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   628
                                    symbolOop name, symbolOop sig,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   629
                                    int mflags, klassOop caller,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   630
                                    int skip, objArrayOop results) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   631
  DEBUG_ONLY(No_Safepoint_Verifier nsv);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   632
  // this code contains no safepoints!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   633
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   634
  // %%% take caller into account!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   635
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   636
  if (k == NULL || !Klass::cast(k)->oop_is_instance())  return -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   637
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   638
  int rfill = 0, rlimit = results->length(), rskip = skip;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   639
  // overflow measurement:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   640
  int overflow = 0, overflow_limit = MAX2(1000, rlimit);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   641
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   642
  int match_flags = mflags;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   643
  bool search_superc = ((match_flags & SEARCH_SUPERCLASSES) != 0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   644
  bool search_intfc  = ((match_flags & SEARCH_INTERFACES)   != 0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   645
  bool local_only = !(search_superc | search_intfc);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   646
  bool classes_only = false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   647
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   648
  if (name != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   649
    if (name->utf8_length() == 0)  return 0; // a match is not possible
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   650
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   651
  if (sig != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   652
    if (sig->utf8_length() == 0)  return 0; // a match is not possible
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   653
    if (sig->byte_at(0) == '(')
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   654
      match_flags &= ~(IS_FIELD | IS_TYPE);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   655
    else
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   656
      match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   657
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   658
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   659
  if ((match_flags & IS_TYPE) != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   660
    // NYI, and Core Reflection works quite well for this query
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   661
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   662
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   663
  if ((match_flags & IS_FIELD) != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   664
    for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   665
      if (name != NULL && st.name() != name)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   666
          continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   667
      if (sig != NULL && st.signature() != sig)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   668
        continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   669
      // passed the filters
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   670
      if (rskip > 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   671
        --rskip;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   672
      } else if (rfill < rlimit) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   673
        oop result = results->obj_at(rfill++);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   674
        if (!sun_dyn_MemberName::is_instance(result))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   675
          return -99;  // caller bug!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   676
        MethodHandles::init_MemberName(result, st.klass()->as_klassOop(), st.access_flags(), st.offset());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   677
      } else if (++overflow >= overflow_limit) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   678
        match_flags = 0; break; // got tired of looking at overflow
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   679
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   680
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   681
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   682
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   683
  if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   684
    // watch out for these guys:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   685
    symbolOop init_name   = vmSymbols::object_initializer_name();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   686
    symbolOop clinit_name = vmSymbols::class_initializer_name();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   687
    if (name == clinit_name)  clinit_name = NULL; // hack for exposing <clinit>
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   688
    bool negate_name_test = false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   689
    // fix name so that it captures the intention of IS_CONSTRUCTOR
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   690
    if (!(match_flags & IS_METHOD)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   691
      // constructors only
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   692
      if (name == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   693
        name = init_name;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   694
      } else if (name != init_name) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   695
        return 0;               // no constructors of this method name
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   696
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   697
    } else if (!(match_flags & IS_CONSTRUCTOR)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   698
      // methods only
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   699
      if (name == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   700
        name = init_name;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   701
        negate_name_test = true; // if we see the name, we *omit* the entry
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   702
      } else if (name == init_name) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   703
        return 0;               // no methods of this constructor name
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   704
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   705
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   706
      // caller will accept either sort; no need to adjust name
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   707
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   708
    for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   709
      methodOop m = st.method();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   710
      symbolOop m_name = m->name();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   711
      if (m_name == clinit_name)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   712
        continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   713
      if (name != NULL && ((m_name != name) ^ negate_name_test))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   714
          continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   715
      if (sig != NULL && m->signature() != sig)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   716
        continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   717
      // passed the filters
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   718
      if (rskip > 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   719
        --rskip;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   720
      } else if (rfill < rlimit) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   721
        oop result = results->obj_at(rfill++);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   722
        if (!sun_dyn_MemberName::is_instance(result))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   723
          return -99;  // caller bug!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   724
        MethodHandles::init_MemberName(result, m, true);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   725
      } else if (++overflow >= overflow_limit) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   726
        match_flags = 0; break; // got tired of looking at overflow
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   727
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   728
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   729
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   730
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   731
  // return number of elements we at leasted wanted to initialize
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   732
  return rfill + overflow;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   733
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   734
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   735
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   736
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   737
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   738
// Decode the vmtarget field of a method handle.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   739
// Sanitize out methodOops, klassOops, and any other non-Java data.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   740
// This is for debugging and reflection.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   741
oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   742
  assert(java_dyn_MethodHandle::is_instance(mh()), "must be a MH");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   743
  if (format == ETF_HANDLE_OR_METHOD_NAME) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   744
    oop target = java_dyn_MethodHandle::vmtarget(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   745
    if (target == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   746
      return NULL;                // unformed MH
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   747
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   748
    klassOop tklass = target->klass();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   749
    if (Klass::cast(tklass)->is_subclass_of(SystemDictionary::object_klass())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   750
      return target;              // target is another MH (or something else?)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   751
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   752
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   753
  if (format == ETF_DIRECT_HANDLE) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   754
    oop target = mh();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   755
    for (;;) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   756
      if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   757
        return target;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   758
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   759
      if (!java_dyn_MethodHandle::is_instance(target)){
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   760
        return NULL;                // unformed MH
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   761
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   762
      target = java_dyn_MethodHandle::vmtarget(target);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   763
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   764
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   765
  // cases of metadata in MH.vmtarget:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   766
  // - AMH can have methodOop for static invoke with bound receiver
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   767
  // - DMH can have methodOop for static invoke (on variable receiver)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   768
  // - DMH can have klassOop for dispatched (non-static) invoke
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   769
  klassOop receiver_limit = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   770
  int decode_flags = 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   771
  methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   772
  if (m == NULL)  return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   773
  switch (format) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   774
  case ETF_REFLECT_METHOD:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   775
    // same as jni_ToReflectedMethod:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   776
    if (m->is_initializer()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   777
      return Reflection::new_constructor(m, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   778
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   779
      return Reflection::new_method(m, UseNewReflection, false, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   780
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   781
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   782
  case ETF_HANDLE_OR_METHOD_NAME:   // method, not handle
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   783
  case ETF_METHOD_NAME:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   784
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   785
      if (SystemDictionary::MemberName_klass() == NULL)  break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   786
      instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   787
      mname_klass->initialize(CHECK_NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   788
      Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   789
      sun_dyn_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   790
      bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   791
      init_MemberName(mname(), m, do_dispatch);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   792
      expand_MemberName(mname, 0, CHECK_NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   793
      return mname();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   794
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   795
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   796
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   797
  // Unknown format code.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   798
  char msg[50];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   799
  jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   800
  THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   801
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   802
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   803
static const char* always_null_names[] = {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   804
  "java/lang/Void",
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   805
  "java/lang/Null",
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   806
  //"java/lang/Nothing",
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   807
  "sun/dyn/empty/Empty",
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   808
  NULL
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   809
};
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   810
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   811
static bool is_always_null_type(klassOop klass) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   812
  if (!Klass::cast(klass)->oop_is_instance())  return false;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   813
  instanceKlass* ik = instanceKlass::cast(klass);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   814
  // Must be on the boot class path:
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   815
  if (ik->class_loader() != NULL)  return false;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   816
  // Check the name.
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   817
  symbolOop name = ik->name();
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   818
  for (int i = 0; ; i++) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   819
    const char* test_name = always_null_names[i];
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   820
    if (test_name == NULL)  break;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   821
    if (name->equals(test_name, (int) strlen(test_name)))
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   822
      return true;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   823
  }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   824
  return false;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   825
}
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   826
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   827
bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   828
  if (src == dst || dst == SystemDictionary::object_klass())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   829
    return false;                               // quickest checks
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   830
  Klass* srck = Klass::cast(src);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   831
  Klass* dstk = Klass::cast(dst);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   832
  if (dstk->is_interface()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   833
    // interface receivers can safely be viewed as untyped,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   834
    // because interface calls always include a dynamic check
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   835
    //dstk = Klass::cast(SystemDictionary::object_klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   836
    return false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   837
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   838
  if (srck->is_interface()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   839
    // interface arguments must be viewed as untyped
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   840
    //srck = Klass::cast(SystemDictionary::object_klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   841
    return true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   842
  }
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   843
  if (is_always_null_type(src)) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   844
    // some source types are known to be never instantiated;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   845
    // they represent references which are always null
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   846
    // such null references never fail to convert safely
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   847
    return false;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   848
  }
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   849
  return !srck->is_subclass_of(dstk->as_klassOop());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   850
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   851
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   852
static oop object_java_mirror() {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   853
  return Klass::cast(SystemDictionary::object_klass())->java_mirror();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   854
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   855
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   856
bool MethodHandles::same_basic_type_for_arguments(BasicType src,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   857
                                                  BasicType dst,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   858
                                                  bool raw,
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   859
                                                  bool for_return) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   860
  if (for_return) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   861
    // return values can always be forgotten:
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   862
    if (dst == T_VOID)  return true;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   863
    if (src == T_VOID)  return raw && (dst == T_INT);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   864
    // We allow caller to receive a garbage int, which is harmless.
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   865
    // This trick is pulled by trusted code (see VerifyType.canPassRaw).
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   866
  }
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   867
  assert(src != T_VOID && dst != T_VOID, "should not be here");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   868
  if (src == dst)  return true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   869
  if (type2size[src] != type2size[dst])  return false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   870
  // allow reinterpretation casts for integral widening
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   871
  if (is_subword_type(src)) { // subwords can fit in int or other subwords
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   872
    if (dst == T_INT)         // any subword fits in an int
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   873
      return true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   874
    if (src == T_BOOLEAN)     // boolean fits in any subword
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   875
      return is_subword_type(dst);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   876
    if (src == T_BYTE && dst == T_SHORT)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   877
      return true;            // remaining case: byte fits in short
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   878
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   879
  // allow float/fixed reinterpretation casts
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   880
  if (src == T_FLOAT)   return dst == T_INT;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   881
  if (src == T_INT)     return dst == T_FLOAT;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   882
  if (src == T_DOUBLE)  return dst == T_LONG;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   883
  if (src == T_LONG)    return dst == T_DOUBLE;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   884
  return false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   885
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   886
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   887
const char* MethodHandles::check_method_receiver(methodOop m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   888
                                                 klassOop passed_recv_type) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   889
  assert(!m->is_static(), "caller resp.");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   890
  if (passed_recv_type == NULL)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   891
    return "receiver type is primitive";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   892
  if (class_cast_needed(passed_recv_type, m->method_holder())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   893
    Klass* formal = Klass::cast(m->method_holder());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   894
    return SharedRuntime::generate_class_cast_message("receiver type",
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   895
                                                      formal->external_name());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   896
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   897
  return NULL;                  // checks passed
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   898
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   899
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   900
// Verify that m's signature can be called type-safely by a method handle
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   901
// of the given method type 'mtype'.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   902
// It takes a TRAPS argument because it must perform symbol lookups.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   903
void MethodHandles::verify_method_signature(methodHandle m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   904
                                            Handle mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   905
                                            int first_ptype_pos,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   906
                                            KlassHandle insert_ptype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   907
                                            TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   908
  objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   909
  int pnum = first_ptype_pos;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   910
  int pmax = ptypes->length();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   911
  int mnum = 0;                 // method argument
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   912
  const char* err = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   913
  for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   914
    oop ptype_oop = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   915
    if (ss.at_return_type()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   916
      if (pnum != pmax)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   917
        { err = "too many arguments"; break; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   918
      ptype_oop = java_dyn_MethodType::rtype(mtype());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   919
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   920
      if (pnum >= pmax)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   921
        { err = "not enough arguments"; break; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   922
      if (pnum >= 0)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   923
        ptype_oop = ptypes->obj_at(pnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   924
      else if (insert_ptype.is_null())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   925
        ptype_oop = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   926
      else
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   927
        ptype_oop = insert_ptype->java_mirror();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   928
      pnum += 1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   929
      mnum += 1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   930
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   931
    klassOop  mklass = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   932
    BasicType mtype  = ss.type();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   933
    if (mtype == T_ARRAY)  mtype = T_OBJECT; // fold all refs to T_OBJECT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   934
    if (mtype == T_OBJECT) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   935
      if (ptype_oop == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   936
        // null matches any reference
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   937
        continue;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   938
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   939
      // If we fail to resolve types at this point, we will throw an error.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   940
      symbolOop    name_oop = ss.as_symbol(CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   941
      symbolHandle name(THREAD, name_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   942
      instanceKlass* mk = instanceKlass::cast(m->method_holder());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   943
      Handle loader(THREAD, mk->class_loader());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   944
      Handle domain(THREAD, mk->protection_domain());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   945
      mklass = SystemDictionary::resolve_or_fail(name, loader, domain,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   946
                                                 true, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   947
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   948
    if (ptype_oop == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   949
      // null does not match any non-reference; use Object to report the error
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   950
      ptype_oop = object_java_mirror();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   951
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   952
    klassOop  pklass = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   953
    BasicType ptype  = java_lang_Class::as_BasicType(ptype_oop, &pklass);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   954
    if (!ss.at_return_type()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   955
      err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   956
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   957
      err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   958
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   959
    if (err != NULL)  break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   960
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   961
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   962
  if (err != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   963
    THROW_MSG(vmSymbols::java_lang_InternalError(), err);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   964
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   965
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   966
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   967
// Main routine for verifying the MethodHandle.type of a proposed
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   968
// direct or bound-direct method handle.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   969
void MethodHandles::verify_method_type(methodHandle m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   970
                                       Handle mtype,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   971
                                       bool has_bound_recv,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   972
                                       KlassHandle bound_recv_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   973
                                       TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   974
  bool m_needs_receiver = !m->is_static();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   975
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   976
  const char* err = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   977
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   978
  int first_ptype_pos = m_needs_receiver ? 1 : 0;
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   979
  if (has_bound_recv) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   980
    first_ptype_pos -= 1;  // ptypes do not include the bound argument; start earlier in them
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   981
    if (m_needs_receiver && bound_recv_type.is_null())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   982
      { err = "bound receiver is not an object"; goto die; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   983
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   984
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   985
  if (m_needs_receiver && err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   986
    objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   987
    if (ptypes->length() < first_ptype_pos)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   988
      { err = "receiver argument is missing"; goto die; }
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   989
    if (has_bound_recv)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   990
      err = check_method_receiver(m(), bound_recv_type->as_klassOop());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   991
    else
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
   992
      err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1)));
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   993
    if (err != NULL)  goto die;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   994
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   995
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   996
  // Check the other arguments for mistypes.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   997
  verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   998
  return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
   999
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1000
 die:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1001
  THROW_MSG(vmSymbols::java_lang_InternalError(), err);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1002
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1003
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1004
void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1005
  // Verify vmslots.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1006
  int check_slots = argument_slot_count(java_dyn_MethodHandle::type(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1007
  if (java_dyn_MethodHandle::vmslots(mh()) != check_slots) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1008
    THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1009
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1010
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1011
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1012
void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1013
  // Verify that argslot points at the given argnum.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1014
  int check_slot = argument_slot(java_dyn_MethodHandle::type(mh()), argnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1015
  if (argslot != check_slot || argslot < 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1016
    const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1017
    size_t msglen = strlen(fmt) + 3*11 + 1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1018
    char* msg = NEW_RESOURCE_ARRAY(char, msglen);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1019
    jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1020
    THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1021
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1022
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1023
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1024
// Verify the correspondence between two method types.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1025
// Apart from the advertised changes, caller method type X must
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1026
// be able to invoke the callee method Y type with no violations
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1027
// of type integrity.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1028
// Return NULL if all is well, else a short error message.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1029
const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1030
                                                    int insert_argnum, oop insert_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1031
                                                    int change_argnum, oop change_type,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1032
                                                    int delete_argnum,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1033
                                                    oop dst_mtype, int dst_beg, int dst_end,
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1034
                                                    bool raw) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1035
  objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1036
  objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1037
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1038
  int src_max = src_ptypes->length();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1039
  int dst_max = dst_ptypes->length();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1040
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1041
  if (src_end == -1)  src_end = src_max;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1042
  if (dst_end == -1)  dst_end = dst_max;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1043
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1044
  assert(0 <= src_beg && src_beg <= src_end && src_end <= src_max, "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1045
  assert(0 <= dst_beg && dst_beg <= dst_end && dst_end <= dst_max, "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1046
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1047
  // pending actions; set to -1 when done:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1048
  int ins_idx = insert_argnum, chg_idx = change_argnum, del_idx = delete_argnum;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1049
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1050
  const char* err = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1051
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1052
  // Walk along each array of parameter types, including a virtual
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1053
  // NULL end marker at the end of each.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1054
  for (int src_idx = src_beg, dst_idx = dst_beg;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1055
       (src_idx <= src_end && dst_idx <= dst_end);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1056
       src_idx++, dst_idx++) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1057
    oop src_type = (src_idx == src_end) ? oop(NULL) : src_ptypes->obj_at(src_idx);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1058
    oop dst_type = (dst_idx == dst_end) ? oop(NULL) : dst_ptypes->obj_at(dst_idx);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1059
    bool fix_null_src_type = false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1060
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1061
    // Perform requested edits.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1062
    if (ins_idx == src_idx) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1063
      // note that the inserted guy is never affected by a change or deletion
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1064
      ins_idx = -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1065
      src_type = insert_type;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1066
      fix_null_src_type = true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1067
      --src_idx;                // back up to process src type on next loop
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1068
      src_idx = src_end;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1069
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1070
      // note that the changed guy can be immediately deleted
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1071
      if (chg_idx == src_idx) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1072
        chg_idx = -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1073
        assert(src_idx < src_end, "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1074
        src_type = change_type;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1075
        fix_null_src_type = true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1076
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1077
      if (del_idx == src_idx) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1078
        del_idx = -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1079
        assert(src_idx < src_end, "oob");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1080
        --dst_idx;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1081
        continue;               // rerun loop after skipping this position
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1082
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1083
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1084
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1085
    if (src_type == NULL && fix_null_src_type)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1086
      // explicit null in this case matches any dest reference
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1087
      src_type = (java_lang_Class::is_primitive(dst_type) ? object_java_mirror() : dst_type);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1088
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1089
    // Compare the two argument types.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1090
    if (src_type != dst_type) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1091
      if (src_type == NULL)  return "not enough arguments";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1092
      if (dst_type == NULL)  return "too many arguments";
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1093
      err = check_argument_type_change(src_type, dst_type, dst_idx, raw);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1094
      if (err != NULL)  return err;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1095
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1096
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1097
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1098
  // Now compare return types also.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1099
  oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1100
  oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1101
  if (src_rtype != dst_rtype) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1102
    err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal!
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1103
    if (err != NULL)  return err;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1104
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1105
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1106
  assert(err == NULL, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1107
  return NULL;  // all is well
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1108
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1109
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1110
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1111
const char* MethodHandles::check_argument_type_change(BasicType src_type,
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1112
                                                      klassOop src_klass,
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1113
                                                      BasicType dst_type,
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1114
                                                      klassOop dst_klass,
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1115
                                                      int argnum,
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1116
                                                      bool raw) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1117
  const char* err = NULL;
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1118
  bool for_return = (argnum < 0);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1119
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1120
  // just in case:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1121
  if (src_type == T_ARRAY)  src_type = T_OBJECT;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1122
  if (dst_type == T_ARRAY)  dst_type = T_OBJECT;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1123
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1124
  // Produce some nice messages if VerifyMethodHandles is turned on:
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1125
  if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1126
    if (src_type == T_OBJECT) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1127
      if (raw && dst_type == T_INT && is_always_null_type(src_klass))
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1128
        return NULL;    // OK to convert a null pointer to a garbage int
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1129
      err = ((argnum >= 0)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1130
             ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1131
             : "type mismatch: returning a %s, but caller expects primitive %s");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1132
    } else if (dst_type == T_OBJECT) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1133
      err = ((argnum >= 0)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1134
             ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1135
             : "type mismatch: returning a primitive %s, but caller expects %s");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1136
    } else {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1137
      err = ((argnum >= 0)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1138
             ? "type mismatch: passing a %s for method argument #%d, which expects %s"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1139
             : "type mismatch: returning a %s, but caller expects %s");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1140
    }
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1141
  } else if (src_type == T_OBJECT && dst_type == T_OBJECT &&
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1142
             class_cast_needed(src_klass, dst_klass)) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1143
    if (!class_cast_needed(dst_klass, src_klass)) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1144
      if (raw)
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1145
        return NULL;    // reverse cast is OK; the MH target is trusted to enforce it
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1146
      err = ((argnum >= 0)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1147
             ? "cast required: passing a %s for method argument #%d, which expects %s"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1148
             : "cast required: returning a %s, but caller expects %s");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1149
    } else {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1150
      err = ((argnum >= 0)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1151
             ? "reference mismatch: passing a %s for method argument #%d, which expects %s"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1152
             : "reference mismatch: returning a %s, but caller expects %s");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1153
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1154
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1155
    // passed the obstacle course
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1156
    return NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1157
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1158
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1159
  // format, format, format
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1160
  const char* src_name = type2name(src_type);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1161
  const char* dst_name = type2name(dst_type);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1162
  if (src_type == T_OBJECT)  src_name = Klass::cast(src_klass)->external_name();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1163
  if (dst_type == T_OBJECT)  dst_name = Klass::cast(dst_klass)->external_name();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1164
  if (src_name == NULL)  src_name = "unknown type";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1165
  if (dst_name == NULL)  dst_name = "unknown type";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1166
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1167
  size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1168
  char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1169
  if (argnum >= 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1170
    assert(strstr(err, "%d") != NULL, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1171
    jio_snprintf(msg, msglen, err, src_name, argnum, dst_name);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1172
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1173
    assert(strstr(err, "%d") == NULL, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1174
    jio_snprintf(msg, msglen, err, src_name,         dst_name);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1175
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1176
  return msg;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1177
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1178
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1179
// Compute the depth within the stack of the given argument, i.e.,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1180
// the combined size of arguments to the right of the given argument.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1181
// For the last argument (ptypes.length-1) this will be zero.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1182
// For the first argument (0) this will be the size of all
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1183
// arguments but that one.  For the special number -1, this
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1184
// will be the size of all arguments, including the first.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1185
// If the argument is neither -1 nor a valid argument index,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1186
// then return a negative number.  Otherwise, the result
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1187
// is in the range [0..vmslots] inclusive.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1188
int MethodHandles::argument_slot(oop method_type, int arg) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1189
  objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1190
  int argslot = 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1191
  int len = ptypes->length();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1192
  if (arg < -1 || arg >= len)  return -99;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1193
  for (int i = len-1; i > arg; i--) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1194
    BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1195
    argslot += type2size[bt];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1196
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1197
  assert(argument_slot_to_argnum(method_type, argslot) == arg, "inverse works");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1198
  return argslot;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1199
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1200
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1201
// Given a slot number, return the argument number.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1202
int MethodHandles::argument_slot_to_argnum(oop method_type, int query_argslot) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1203
  objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1204
  int argslot = 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1205
  int len = ptypes->length();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1206
  for (int i = len-1; i >= 0; i--) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1207
    if (query_argslot == argslot)  return i;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1208
    BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1209
    argslot += type2size[bt];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1210
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1211
  // return pseudo-arg deepest in stack:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1212
  if (query_argslot == argslot)  return -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1213
  return -99;                   // oob slot, or splitting a double-slot arg
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1214
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1215
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1216
methodHandle MethodHandles::dispatch_decoded_method(methodHandle m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1217
                                                    KlassHandle receiver_limit,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1218
                                                    int decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1219
                                                    KlassHandle receiver_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1220
                                                    TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1221
  assert((decode_flags & ~_DMF_DIRECT_MASK) == 0, "must be direct method reference");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1222
  assert((decode_flags & _dmf_has_receiver) != 0, "must have a receiver or first reference argument");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1223
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1224
  if (!m->is_static() &&
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1225
      (receiver_klass.is_null() || !receiver_klass->is_subtype_of(m->method_holder())))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1226
    // given type does not match class of method, or receiver is null!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1227
    // caller should have checked this, but let's be extra careful...
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1228
    return methodHandle();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1229
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1230
  if (receiver_limit.not_null() &&
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1231
      (receiver_klass.not_null() && !receiver_klass->is_subtype_of(receiver_limit())))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1232
    // given type is not limited to the receiver type
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1233
    // note that a null receiver can match any reference value, for a static method
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1234
    return methodHandle();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1235
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1236
  if (!(decode_flags & MethodHandles::_dmf_does_dispatch)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1237
    // pre-dispatched or static method (null receiver is OK for static)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1238
    return m;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1239
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1240
  } else if (receiver_klass.is_null()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1241
    // null receiver value; cannot dispatch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1242
    return methodHandle();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1243
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1244
  } else if (!(decode_flags & MethodHandles::_dmf_from_interface)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1245
    // perform virtual dispatch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1246
    int vtable_index = m->vtable_index();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1247
    guarantee(vtable_index >= 0, "valid vtable index");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1248
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1249
    // receiver_klass might be an arrayKlassOop but all vtables start at
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1250
    // the same place. The cast is to avoid virtual call and assertion.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1251
    // See also LinkResolver::runtime_resolve_virtual_method.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1252
    instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1253
    DEBUG_ONLY(inst->verify_vtable_index(vtable_index));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1254
    methodOop m_oop = inst->method_at_vtable(vtable_index);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1255
    return methodHandle(THREAD, m_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1256
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1257
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1258
    // perform interface dispatch
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1259
    int itable_index = klassItable::compute_itable_index(m());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1260
    guarantee(itable_index >= 0, "valid itable index");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1261
    instanceKlass* inst = instanceKlass::cast(receiver_klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1262
    methodOop m_oop = inst->method_at_itable(m->method_holder(), itable_index, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1263
    return methodHandle(THREAD, m_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1264
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1265
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1266
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1267
void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1268
  // Verify type.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1269
  Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1270
  verify_method_type(m, mtype, false, KlassHandle(), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1271
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1272
  // Verify vmslots.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1273
  if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1274
    THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1275
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1276
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1277
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1278
void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1279
  // Check arguments.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1280
  if (mh.is_null() || m.is_null() ||
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1281
      (!do_dispatch && m->is_abstract())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1282
    THROW(vmSymbols::java_lang_InternalError());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1283
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1284
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1285
  java_dyn_MethodHandle::init_vmslots(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1286
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1287
  if (VerifyMethodHandles) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1288
    // The privileged code which invokes this routine should not make
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1289
    // a mistake about types, but it's better to verify.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1290
    verify_DirectMethodHandle(mh, m, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1291
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1292
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1293
  // Finally, after safety checks are done, link to the target method.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1294
  // We will follow the same path as the latter part of
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1295
  // InterpreterRuntime::resolve_invoke(), which first finds the method
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1296
  // and then decides how to populate the constant pool cache entry
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1297
  // that links the interpreter calls to the method.  We need the same
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1298
  // bits, and will use the same calling sequence code.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1299
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1300
  int vmindex = methodOopDesc::garbage_vtable_index;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1301
  oop vmtarget = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1302
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1303
  instanceKlass::cast(m->method_holder())->link_class(CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1304
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1305
  MethodHandleEntry* me = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1306
  if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1307
    // We are simulating an invokeinterface instruction.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1308
    // (We might also be simulating an invokevirtual on a miranda method,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1309
    // but it is safe to treat it as an invokeinterface.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1310
    assert(!m->can_be_statically_bound(), "no final methods on interfaces");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1311
    vmindex = klassItable::compute_itable_index(m());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1312
    assert(vmindex >= 0, "(>=0) == do_dispatch");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1313
    // Set up same bits as ConstantPoolCacheEntry::set_interface_call().
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1314
    vmtarget = m->method_holder(); // the interface
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1315
    me = MethodHandles::entry(MethodHandles::_invokeinterface_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1316
  } else if (!do_dispatch || m->can_be_statically_bound()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1317
    // We are simulating an invokestatic or invokespecial instruction.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1318
    // Set up the method pointer, just like ConstantPoolCacheEntry::set_method().
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1319
    vmtarget = m();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1320
    // this does not help dispatch, but it will make it possible to parse this MH:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1321
    vmindex  = methodOopDesc::nonvirtual_vtable_index;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1322
    assert(vmindex < 0, "(>=0) == do_dispatch");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1323
    if (!m->is_static()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1324
      me = MethodHandles::entry(MethodHandles::_invokespecial_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1325
    } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1326
      me = MethodHandles::entry(MethodHandles::_invokestatic_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1327
      // Part of the semantics of a static call is an initialization barrier.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1328
      // For a DMH, it is done now, when the handle is created.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1329
      Klass* k = Klass::cast(m->method_holder());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1330
      if (k->should_be_initialized()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1331
        k->initialize(CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1332
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1333
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1334
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1335
    // We are simulating an invokevirtual instruction.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1336
    // Set up the vtable index, just like ConstantPoolCacheEntry::set_method().
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1337
    // The key logic is LinkResolver::runtime_resolve_virtual_method.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1338
    vmindex  = m->vtable_index();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1339
    vmtarget = m->method_holder();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1340
    me = MethodHandles::entry(MethodHandles::_invokevirtual_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1341
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1342
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1343
  if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1344
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1345
  sun_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1346
  sun_dyn_DirectMethodHandle::set_vmindex(mh(),  vmindex);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1347
  DEBUG_ONLY(int flags; klassOop rlimit);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1348
  assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1349
         "properly stored for later decoding");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1350
  DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1351
  assert(!(actual_do_dispatch && !do_dispatch),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1352
         "do not perform dispatch if !do_dispatch specified");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1353
  assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1354
  assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1355
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1356
  // Done!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1357
  java_dyn_MethodHandle::set_vmentry(mh(), me);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1358
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1359
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1360
void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1361
                                                           methodHandle m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1362
                                                           TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1363
  // Verify type.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1364
  oop receiver = sun_dyn_BoundMethodHandle::argument(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1365
  Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1366
  KlassHandle bound_recv_type;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1367
  if (receiver != NULL)  bound_recv_type = KlassHandle(THREAD, receiver->klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1368
  verify_method_type(m, mtype, true, bound_recv_type, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1369
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1370
  int receiver_pos = m->size_of_parameters() - 1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1371
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1372
  // Verify MH.vmargslot, which should point at the bound receiver.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1373
  verify_vmargslot(mh, -1, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1374
  //verify_vmslots(mh, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1375
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1376
  // Verify vmslots.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1377
  if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1378
    THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1379
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1380
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1381
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1382
// Initialize a BMH with a receiver bound directly to a methodOop.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1383
void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1384
                                                         methodHandle original_m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1385
                                                         KlassHandle receiver_limit,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1386
                                                         int decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1387
                                                         TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1388
  // Check arguments.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1389
  if (mh.is_null() || original_m.is_null()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1390
    THROW(vmSymbols::java_lang_InternalError());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1391
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1392
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1393
  KlassHandle receiver_klass;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1394
  {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1395
    oop receiver_oop = sun_dyn_BoundMethodHandle::argument(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1396
    if (receiver_oop != NULL)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1397
      receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1398
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1399
  methodHandle m = dispatch_decoded_method(original_m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1400
                                           receiver_limit, decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1401
                                           receiver_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1402
                                           CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1403
  if (m.is_null())      { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1404
  if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1405
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1406
  java_dyn_MethodHandle::init_vmslots(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1407
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1408
  if (VerifyMethodHandles) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1409
    verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1410
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1411
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1412
  sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1413
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1414
  DEBUG_ONLY(int junk; klassOop junk2);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1415
  assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1416
  assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1417
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1418
  // Done!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1419
  java_dyn_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1420
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1421
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1422
void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1423
                                             bool direct_to_method, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1424
  Handle ptype_handle(THREAD,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1425
                           java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1426
  KlassHandle ptype_klass;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1427
  BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1428
  int slots_pushed = type2size[ptype];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1429
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1430
  oop argument = sun_dyn_BoundMethodHandle::argument(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1431
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1432
  const char* err = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1433
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1434
  switch (ptype) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1435
  case T_OBJECT:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1436
    if (argument != NULL)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1437
      // we must implicitly convert from the arg type to the outgoing ptype
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1438
      err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1439
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1440
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1441
  case T_ARRAY: case T_VOID:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1442
    assert(false, "array, void do not appear here");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1443
  default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1444
    if (ptype != T_INT && !is_subword_type(ptype)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1445
      err = "unexpected parameter type";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1446
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1447
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1448
    // check subrange of Integer.value, if necessary
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1449
    if (argument == NULL || argument->klass() != SystemDictionary::int_klass()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1450
      err = "bound integer argument must be of type java.lang.Integer";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1451
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1452
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1453
    if (ptype != T_INT) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1454
      int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1455
      jint value = argument->int_field(value_offset);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1456
      int vminfo = adapter_subword_vminfo(ptype);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1457
      jint subword = truncate_subword_from_vminfo(value, vminfo);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1458
      if (value != subword) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1459
        err = "bound subword value does not fit into the subword type";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1460
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1461
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1462
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1463
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1464
  case T_FLOAT:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1465
  case T_DOUBLE:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1466
  case T_LONG:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1467
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1468
      // we must implicitly convert from the unboxed arg type to the outgoing ptype
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1469
      BasicType argbox = java_lang_boxing_object::basic_type(argument);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1470
      if (argbox != ptype) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1471
        err = check_argument_type_change(T_OBJECT, (argument == NULL
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1472
                                                    ? SystemDictionary::object_klass()
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1473
                                                    : argument->klass()),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1474
                                         ptype, ptype_klass(), argnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1475
        assert(err != NULL, "this must be an error");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1476
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1477
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1478
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1479
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1480
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1481
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1482
    DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1483
    if (direct_to_method) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1484
      assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1485
      assert(slots_pushed <= MethodHandlePushLimit, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1486
    } else {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1487
      int target_pushes = decode_MethodHandle_stack_pushes(target());
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1488
      assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct");
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1489
      // do not blow the stack; use a Java-based adapter if this limit is exceeded
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1490
      if (slots_pushed + target_pushes > MethodHandlePushLimit)
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1491
        err = "too many bound parameters";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1492
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1493
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1494
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1495
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1496
    // Verify the rest of the method type.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1497
    err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1498
                                      argnum, ptype_handle(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1499
                                      java_dyn_MethodHandle::type(target()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1500
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1501
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1502
  if (err != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1503
    THROW_MSG(vmSymbols::java_lang_InternalError(), err);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1504
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1505
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1506
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1507
void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1508
  // Check arguments.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1509
  if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1510
    THROW(vmSymbols::java_lang_InternalError());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1511
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1512
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1513
  java_dyn_MethodHandle::init_vmslots(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1514
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1515
  if (VerifyMethodHandles) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1516
    int insert_after = argnum - 1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1517
    verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1518
    verify_vmslots(mh, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1519
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1520
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1521
  // If (a) the target is a direct non-dispatched method handle,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1522
  // or (b) the target is a dispatched direct method handle and we
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1523
  // are binding the receiver, cut out the middle-man.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1524
  // Do this by decoding the DMH and using its methodOop directly as vmtarget.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1525
  bool direct_to_method = false;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1526
  if (OptimizeMethodHandles &&
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1527
      target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1528
      (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1529
    int decode_flags = 0; klassOop receiver_limit_oop = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1530
    methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1531
    if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1532
    DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - 1); // pos. of 1st arg.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1533
    assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1534
    if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1535
      KlassHandle receiver_limit(THREAD, receiver_limit_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1536
      init_BoundMethodHandle_with_receiver(mh, m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1537
                                           receiver_limit, decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1538
                                           CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1539
      return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1540
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1541
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1542
    // Even if it is not a bound receiver, we still might be able
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1543
    // to bind another argument and still invoke the methodOop directly.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1544
    if (!(decode_flags & _dmf_does_dispatch)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1545
      direct_to_method = true;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1546
      sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1547
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1548
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1549
  if (!direct_to_method)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1550
    sun_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1551
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1552
  if (VerifyMethodHandles) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1553
    verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1554
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1555
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1556
  // Next question:  Is this a ref, int, or long bound value?
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1557
  oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1558
  BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1559
  int slots_pushed = type2size[ptype];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1560
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1561
  MethodHandleEntry* me = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1562
  if (ptype == T_OBJECT) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1563
    if (direct_to_method)  me = MethodHandles::entry(_bound_ref_direct_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1564
    else                   me = MethodHandles::entry(_bound_ref_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1565
  } else if (slots_pushed == 2) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1566
    if (direct_to_method)  me = MethodHandles::entry(_bound_long_direct_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1567
    else                   me = MethodHandles::entry(_bound_long_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1568
  } else if (slots_pushed == 1) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1569
    if (direct_to_method)  me = MethodHandles::entry(_bound_int_direct_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1570
    else                   me = MethodHandles::entry(_bound_int_mh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1571
  } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1572
    assert(false, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1573
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1574
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1575
  // Done!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1576
  java_dyn_MethodHandle::set_vmentry(mh(), me);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1577
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1578
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1579
static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1580
  char msg[200];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1581
  jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1582
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1583
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1584
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1585
void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1586
  jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1587
  int  argslot    = sun_dyn_AdapterMethodHandle::vmargslot(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1588
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1589
  verify_vmargslot(mh, argnum, argslot, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1590
  verify_vmslots(mh, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1591
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1592
  jint conv_op    = adapter_conversion_op(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1593
  if (!conv_op_valid(conv_op)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1594
    throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1595
    return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1596
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1597
  EntryKind ek = adapter_entry_kind(conv_op);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1598
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1599
  int stack_move = adapter_conversion_stack_move(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1600
  BasicType src  = adapter_conversion_src_type(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1601
  BasicType dest = adapter_conversion_dest_type(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1602
  int vminfo     = adapter_conversion_vminfo(conversion); // should be zero
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1603
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1604
  Handle argument(THREAD,  sun_dyn_AdapterMethodHandle::argument(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1605
  Handle target(THREAD,    sun_dyn_AdapterMethodHandle::vmtarget(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1606
  Handle src_mtype(THREAD, java_dyn_MethodHandle::type(mh()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1607
  Handle dst_mtype(THREAD, java_dyn_MethodHandle::type(target()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1608
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1609
  const char* err = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1610
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1611
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1612
    // Check that the correct argument is supplied, but only if it is required.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1613
    switch (ek) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1614
    case _adapter_check_cast:     // target type of cast
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1615
    case _adapter_ref_to_prim:    // wrapper type from which to unbox
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1616
    case _adapter_prim_to_ref:    // wrapper type to box into
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1617
    case _adapter_collect_args:   // array type to collect into
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1618
    case _adapter_spread_args:    // array type to spread from
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1619
      if (!java_lang_Class::is_instance(argument())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1620
          || java_lang_Class::is_primitive(argument()))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1621
        { err = "adapter requires argument of type java.lang.Class"; break; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1622
      if (ek == _adapter_collect_args ||
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1623
          ek == _adapter_spread_args) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1624
        // Make sure it is a suitable collection type.  (Array, for now.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1625
        Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument()));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1626
        if (!ak->oop_is_objArray()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1627
          { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1628
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1629
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1630
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1631
    case _adapter_flyby:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1632
    case _adapter_ricochet:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1633
      if (!java_dyn_MethodHandle::is_instance(argument()))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1634
        { err = "MethodHandle adapter argument required"; break; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1635
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1636
    default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1637
      if (argument.not_null())
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1638
        { err = "adapter has spurious argument"; break; }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1639
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1640
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1641
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1642
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1643
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1644
    // Check that the src/dest types are supplied if needed.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1645
    switch (ek) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1646
    case _adapter_check_cast:
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1647
      if (src != T_OBJECT || dest != T_OBJECT) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1648
        err = "adapter requires object src/dest conversion subfields";
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1649
      }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1650
      break;
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1651
    case _adapter_prim_to_prim:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1652
      if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1653
        err = "adapter requires primitive src/dest conversion subfields"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1654
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1655
      if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1656
          !(src == T_FLOAT || src == T_DOUBLE) &&  (dest == T_FLOAT || dest == T_DOUBLE)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1657
        err = "adapter cannot convert beween floating and fixed-point"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1658
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1659
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1660
    case _adapter_ref_to_prim:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1661
      if (src != T_OBJECT || !is_java_primitive(dest)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1662
          || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1663
        err = "adapter requires primitive dest conversion subfield"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1664
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1665
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1666
    case _adapter_prim_to_ref:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1667
      if (!is_java_primitive(src) || dest != T_OBJECT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1668
          || argument() != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1669
        err = "adapter requires primitive src conversion subfield"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1670
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1671
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1672
    case _adapter_swap_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1673
    case _adapter_rot_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1674
      {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1675
        if (!src || src != dest) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1676
          err = "adapter requires src/dest conversion subfields for swap"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1677
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1678
        int swap_size = type2size[src];
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1679
        oop src_mtype  = sun_dyn_AdapterMethodHandle::type(mh());
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1680
        oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target());
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1681
        int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target());
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1682
        int src_slot   = argslot;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1683
        int dest_slot  = vminfo;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1684
        bool rotate_up = (src_slot > dest_slot); // upward rotation
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1685
        int src_arg    = argnum;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1686
        int dest_arg   = argument_slot_to_argnum(dest_mtype, dest_slot);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1687
        verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1688
        if (!(dest_slot >= src_slot + swap_size) &&
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1689
            !(src_slot >= dest_slot + swap_size)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1690
          err = "source, destination slots must be distinct";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1691
        } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1692
          err = "source of swap must be deeper in stack";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1693
        } else if (ek == _adapter_swap_args) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1694
          err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1695
                                           java_dyn_MethodType::ptype(dest_mtype, src_arg),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1696
                                           dest_arg);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1697
        } else if (ek == _adapter_rot_args) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1698
          if (rotate_up) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1699
            assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1700
            // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1701
            // that is:   [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1702
            for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1703
              err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1704
                                               java_dyn_MethodType::ptype(dest_mtype, i-1),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1705
                                               i);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1706
            }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1707
          } else { // rotate down
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1708
            assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1709
            // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1710
            // that is:     [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1711
            for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1712
              err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1713
                                               java_dyn_MethodType::ptype(dest_mtype, i+1),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1714
                                               i);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1715
            }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1716
          }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1717
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1718
        if (err == NULL)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1719
          err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1720
                                           java_dyn_MethodType::ptype(dest_mtype, dest_arg),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1721
                                           src_arg);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1722
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1723
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1724
    case _adapter_collect_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1725
    case _adapter_spread_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1726
      {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1727
        BasicType coll_type = (ek == _adapter_collect_args) ? dest : src;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1728
        BasicType elem_type = (ek == _adapter_collect_args) ? src : dest;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1729
        if (coll_type != T_OBJECT || elem_type != T_OBJECT) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1730
          err = "adapter requires src/dest subfields"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1731
          // later:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1732
          // - consider making coll be a primitive array
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1733
          // - consider making coll be a heterogeneous collection
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1734
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1735
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1736
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1737
    default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1738
      if (src != 0 || dest != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1739
        err = "adapter has spurious src/dest conversion subfields"; break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1740
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1741
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1742
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1743
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1744
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1745
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1746
    // Check the stack_move subfield.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1747
    // It must always report the net change in stack size, positive or negative.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1748
    int slots_pushed = stack_move / stack_move_unit();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1749
    switch (ek) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1750
    case _adapter_prim_to_prim:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1751
    case _adapter_ref_to_prim:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1752
    case _adapter_prim_to_ref:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1753
      if (slots_pushed != type2size[dest] - type2size[src]) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1754
        err = "wrong stack motion for primitive conversion";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1755
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1756
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1757
    case _adapter_dup_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1758
      if (slots_pushed <= 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1759
        err = "adapter requires conversion subfield slots_pushed > 0";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1760
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1761
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1762
    case _adapter_drop_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1763
      if (slots_pushed >= 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1764
        err = "adapter requires conversion subfield slots_pushed < 0";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1765
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1766
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1767
    case _adapter_collect_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1768
      if (slots_pushed > 1) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1769
        err = "adapter requires conversion subfield slots_pushed <= 1";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1770
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1771
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1772
    case _adapter_spread_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1773
      if (slots_pushed < -1) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1774
        err = "adapter requires conversion subfield slots_pushed >= -1";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1775
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1776
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1777
    default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1778
      if (stack_move != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1779
        err = "adapter has spurious stack_move conversion subfield";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1780
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1781
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1782
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1783
    if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1784
      err = "stack_move conversion subfield must be multiple of stack_move_unit";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1785
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1786
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1787
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1788
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1789
    // Make sure this adapter does not push too deeply.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1790
    int slots_pushed = stack_move / stack_move_unit();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1791
    int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1792
    int target_vmslots = java_dyn_MethodHandle::vmslots(target());
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1793
    if (slots_pushed != (target_vmslots - this_vmslots)) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1794
      err = "stack_move inconsistent with previous and current MethodType vmslots";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1795
    } else if (slots_pushed > 0)  {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1796
      // verify stack_move against MethodHandlePushLimit
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1797
      int target_pushes = decode_MethodHandle_stack_pushes(target());
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1798
      // do not blow the stack; use a Java-based adapter if this limit is exceeded
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1799
      if (slots_pushed + target_pushes > MethodHandlePushLimit) {
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1800
        err = "adapter pushes too many parameters";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1801
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1802
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1803
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1804
    // While we're at it, check that the stack motion decoder works:
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1805
    DEBUG_ONLY(int target_pushes = decode_MethodHandle_stack_pushes(target()));
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1806
    DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1807
    assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct");
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1808
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1809
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1810
  if (err == NULL && vminfo != 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1811
    switch (ek) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1812
      case _adapter_swap_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1813
      case _adapter_rot_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1814
        break;                // OK
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1815
    default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1816
      err = "vminfo subfield is reserved to the JVM";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1817
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1818
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1819
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1820
  // Do additional ad hoc checks.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1821
  if (err == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1822
    switch (ek) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1823
    case _adapter_retype_only:
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1824
      err = check_method_type_passthrough(src_mtype(), dst_mtype(), false);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1825
      break;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1826
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1827
    case _adapter_retype_raw:
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1828
      err = check_method_type_passthrough(src_mtype(), dst_mtype(), true);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1829
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1830
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1831
    case _adapter_check_cast:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1832
      {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1833
        // The actual value being checked must be a reference:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1834
        err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1835
                                         object_java_mirror(), argnum);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1836
        if (err != NULL)  break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1837
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1838
        // The output of the cast must fit with the destination argument:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1839
        Handle cast_class = argument;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1840
        err = check_method_type_conversion(src_mtype(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1841
                                           argnum, cast_class(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1842
                                           dst_mtype());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1843
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1844
      break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1845
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1846
      // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1847
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1848
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1849
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1850
  if (err != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1851
    throw_InternalError_for_bad_conversion(conversion, err, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1852
    return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1853
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1854
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1855
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1856
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1857
void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1858
  oop  argument   = sun_dyn_AdapterMethodHandle::argument(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1859
  int  argslot    = sun_dyn_AdapterMethodHandle::vmargslot(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1860
  jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1861
  jint conv_op    = adapter_conversion_op(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1862
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1863
  // adjust the adapter code to the internal EntryKind enumeration:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1864
  EntryKind ek_orig = adapter_entry_kind(conv_op);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1865
  EntryKind ek_opt  = ek_orig;  // may be optimized
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1866
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1867
  // Finalize the vmtarget field (Java initialized it to null).
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1868
  if (!java_dyn_MethodHandle::is_instance(target())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1869
    throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1870
    return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1871
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1872
  sun_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1873
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1874
  if (VerifyMethodHandles) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1875
    verify_AdapterMethodHandle(mh, argnum, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1876
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1877
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1878
  int stack_move = adapter_conversion_stack_move(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1879
  BasicType src  = adapter_conversion_src_type(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1880
  BasicType dest = adapter_conversion_dest_type(conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1881
  int vminfo     = adapter_conversion_vminfo(conversion); // should be zero
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1882
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1883
  const char* err = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1884
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1885
  // Now it's time to finish the case analysis and pick a MethodHandleEntry.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1886
  switch (ek_orig) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1887
  case _adapter_retype_only:
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1888
  case _adapter_retype_raw:
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1889
  case _adapter_check_cast:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1890
  case _adapter_dup_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1891
  case _adapter_drop_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1892
    // these work fine via general case code
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1893
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1894
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1895
  case _adapter_prim_to_prim:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1896
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1897
      // Non-subword cases are {int,float,long,double} -> {int,float,long,double}.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1898
      // And, the {float,double} -> {int,long} cases must be handled by Java.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1899
      switch (type2size[src] *4+ type2size[dest]) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1900
      case 1 *4+ 1:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1901
        assert(src == T_INT || is_subword_type(src), "source is not float");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1902
        // Subword-related cases are int -> {boolean,byte,char,short}.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1903
        ek_opt = _adapter_opt_i2i;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1904
        vminfo = adapter_subword_vminfo(dest);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1905
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1906
      case 2 *4+ 1:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1907
        if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1908
          ek_opt = _adapter_opt_l2i;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1909
          vminfo = adapter_subword_vminfo(dest);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1910
        } else if (src == T_DOUBLE && dest == T_FLOAT) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1911
          ek_opt = _adapter_opt_d2f;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1912
        } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1913
          assert(false, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1914
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1915
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1916
      case 1 *4+ 2:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1917
        if (src == T_INT && dest == T_LONG) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1918
          ek_opt = _adapter_opt_i2l;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1919
        } else if (src == T_FLOAT && dest == T_DOUBLE) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1920
          ek_opt = _adapter_opt_f2d;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1921
        } else {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1922
          assert(false, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1923
        }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1924
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1925
      default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1926
        assert(false, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1927
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1928
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1929
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1930
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1931
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1932
  case _adapter_ref_to_prim:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1933
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1934
      switch (type2size[dest]) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1935
      case 1:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1936
        ek_opt = _adapter_opt_unboxi;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1937
        vminfo = adapter_subword_vminfo(dest);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1938
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1939
      case 2:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1940
        ek_opt = _adapter_opt_unboxl;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1941
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1942
      default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1943
        assert(false, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1944
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1945
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1946
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1947
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1948
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1949
  case _adapter_prim_to_ref:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1950
    goto throw_not_impl;        // allocates, hence could block
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1951
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1952
  case _adapter_swap_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1953
  case _adapter_rot_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1954
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1955
      int swap_slots = type2size[src];
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  1956
      int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mh());
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1957
      int src_slot   = argslot;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1958
      int dest_slot  = vminfo;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1959
      int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1960
      switch (swap_slots) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1961
      case 1:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1962
        ek_opt = (!rotate    ? _adapter_opt_swap_1 :
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1963
                  rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1964
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1965
      case 2:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1966
        ek_opt = (!rotate    ? _adapter_opt_swap_2 :
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1967
                  rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1968
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1969
      default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1970
        assert(false, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1971
        break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1972
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1973
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1974
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1975
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1976
  case _adapter_collect_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1977
    goto throw_not_impl;        // allocates, hence could block
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1978
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1979
  case _adapter_spread_args:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1980
    {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1981
      // vminfo will be the required length of the array
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1982
      int slots_pushed = stack_move / stack_move_unit();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1983
      int array_size   = slots_pushed + 1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1984
      assert(array_size >= 0, "");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1985
      vminfo = array_size;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1986
      switch (array_size) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1987
      case 0:   ek_opt = _adapter_opt_spread_0;       break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1988
      case 1:   ek_opt = _adapter_opt_spread_1;       break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1989
      default:  ek_opt = _adapter_opt_spread_more;    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1990
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1991
      if ((vminfo & CONV_VMINFO_MASK) != vminfo)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1992
        goto throw_not_impl;    // overflow
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1993
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1994
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1995
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1996
  case _adapter_flyby:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1997
  case _adapter_ricochet:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1998
    goto throw_not_impl;        // runs Java code, hence could block
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  1999
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2000
  default:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2001
    // should have failed much earlier; must be a missing case here
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2002
    assert(false, "incomplete switch");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2003
    // and fall through:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2004
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2005
  throw_not_impl:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2006
    // FIXME: these adapters are NYI
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2007
    err = "adapter not yet implemented in the JVM";
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2008
    break;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2009
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2010
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2011
  if (err != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2012
    throw_InternalError_for_bad_conversion(conversion, err, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2013
    return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2014
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2015
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2016
  // Rebuild the conversion value; maybe parts of it were changed.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2017
  jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2018
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2019
  // Finalize the conversion field.  (Note that it is final to Java code.)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2020
  sun_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2021
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2022
  // Done!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2023
  java_dyn_MethodHandle::set_vmentry(mh(), entry(ek_opt));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2024
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2025
  // There should be enough memory barriers on exit from native methods
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2026
  // to ensure that the MH is fully initialized to all threads before
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2027
  // Java code can publish it in global data structures.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2028
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2029
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2030
//
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2031
// Here are the native methods on sun.dyn.MethodHandleImpl.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2032
// They are the private interface between this JVM and the HotSpot-specific
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2033
// Java code that implements JSR 292 method handles.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2034
//
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2035
// Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2036
// that intrinsic (non-JNI) native methods are defined in HotSpot.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2037
//
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2038
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2039
// direct method handles for invokestatic or invokespecial
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2040
// void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2041
JVM_ENTRY(void, MHI_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2042
                             jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2043
  ResourceMark rm;              // for error messages
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2044
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2045
  // This is the guy we are initializing:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2046
  if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2047
  Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2048
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2049
  // Early returns out of this method leave the DMH in an unfinished state.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2050
  assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2051
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2052
  // which method are we really talking about?
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2053
  if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2054
  oop target_oop = JNIHandles::resolve_non_null(target_jh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2055
  if (sun_dyn_MemberName::is_instance(target_oop) &&
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2056
      sun_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2057
    Handle mname(THREAD, target_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2058
    MethodHandles::resolve_MemberName(mname, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2059
    target_oop = mname(); // in case of GC
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2060
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2061
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2062
  int decode_flags = 0; klassOop receiver_limit = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2063
  methodHandle m(THREAD,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2064
                 MethodHandles::decode_method(target_oop,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2065
                                              receiver_limit, decode_flags));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2066
  if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2067
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2068
  // The trusted Java code that calls this method should already have performed
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2069
  // access checks on behalf of the given caller.  But, we can verify this.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2070
  if (VerifyMethodHandles && caller_jh != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2071
    KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2072
    // If this were a bytecode, the first access check would be against
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2073
    // the "reference class" mentioned in the CONSTANT_Methodref.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2074
    // For that class, we use the defining class of m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2075
    // or a more specific receiver limit if available.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2076
    klassOop reference_klass = m->method_holder();  // OK approximation
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2077
    if (receiver_limit != NULL && receiver_limit != reference_klass) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2078
      if (!Klass::cast(receiver_limit)->is_subtype_of(reference_klass))
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2079
        THROW_MSG(vmSymbols::java_lang_InternalError(), "receiver limit out of bounds");  // Java code bug
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2080
      reference_klass = receiver_limit;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2081
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2082
    // Emulate LinkResolver::check_klass_accessability.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2083
    if (!Reflection::verify_class_access(caller->as_klassOop(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2084
                                         reference_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2085
                                         true)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2086
      THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(m->method_holder())->external_name());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2087
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2088
    // If there were a bytecode, the next step would be to lookup the method
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2089
    // in the reference class, then then check the method's access bits.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2090
    // Emulate LinkResolver::check_method_accessability.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2091
    klassOop resolved_klass = m->method_holder();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2092
    if (!Reflection::verify_field_access(caller->as_klassOop(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2093
                                         resolved_klass, reference_klass,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2094
                                         m->access_flags(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2095
                                         true)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2096
      // %%% following cutout belongs in Reflection::verify_field_access?
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2097
      bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2098
                                                        reference_klass, THREAD);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2099
      if (!same_pm) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2100
        THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2101
      }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2102
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2103
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2104
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2105
  MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2106
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2107
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2108
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2109
// bound method handles
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2110
JVM_ENTRY(void, MHI_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2111
                             jobject target_jh, int argnum)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2112
  ResourceMark rm;              // for error messages
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2113
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2114
  // This is the guy we are initializing:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2115
  if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2116
  Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2117
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2118
  // Early returns out of this method leave the BMH in an unfinished state.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2119
  assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2120
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2121
  if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2122
  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2123
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2124
  if (!java_dyn_MethodHandle::is_instance(target())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2125
    // Target object is a reflective method.  (%%% Do we need this alternate path?)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2126
    Untested("init_BMH of non-MH");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2127
    if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2128
    int decode_flags = 0; klassOop receiver_limit_oop = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2129
    methodHandle m(THREAD,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2130
                   MethodHandles::decode_method(target(),
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2131
                                                receiver_limit_oop,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2132
                                                decode_flags));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2133
    KlassHandle receiver_limit(THREAD, receiver_limit_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2134
    MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2135
                                                       receiver_limit,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2136
                                                       decode_flags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2137
                                                       CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2138
    return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2139
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2140
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2141
  // Build a BMH on top of a DMH or another BMH:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2142
  MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2143
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2144
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2145
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2146
// adapter method handles
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2147
JVM_ENTRY(void, MHI_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2148
                             jobject target_jh, int argnum)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2149
  // This is the guy we are initializing:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2150
  if (mh_jh == NULL || target_jh == NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2151
    THROW(vmSymbols::java_lang_InternalError());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2152
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2153
  Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2154
  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2155
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2156
  // Early returns out of this method leave the AMH in an unfinished state.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2157
  assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2158
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2159
  MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2160
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2161
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2162
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2163
// method type forms
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2164
JVM_ENTRY(void, MHI_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2165
  if (erased_jh == NULL)  return;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2166
  if (TraceMethodHandles) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2167
    tty->print("creating MethodType form ");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2168
    if (WizardMode || Verbose) {   // Warning: this calls Java code on the MH!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2169
      // call Object.toString()
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2170
      symbolOop name = vmSymbols::toString_name(), sig = vmSymbols::void_string_signature();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2171
      JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh)));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2172
      JavaValue result(T_OBJECT);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2173
      JavaCalls::call_virtual(&result, SystemDictionary::object_klass(), name, sig,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2174
                              &args, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2175
      Handle str(THREAD, (oop)result.get_jobject());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2176
      java_lang_String::print(str, tty);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2177
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2178
    tty->cr();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2179
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2180
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2181
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2182
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2183
// debugging and reflection
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2184
JVM_ENTRY(jobject, MHI_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2185
  Handle mh(THREAD, JNIHandles::resolve(mh_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2186
  if (!java_dyn_MethodHandle::is_instance(mh())) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2187
    THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2188
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2189
  oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2190
  return JNIHandles::make_local(THREAD, target);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2191
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2192
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2193
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2194
JVM_ENTRY(jint, MHI_getConstant(JNIEnv *env, jobject igcls, jint which)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2195
  switch (which) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2196
  case MethodHandles::GC_JVM_PUSH_LIMIT:
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2197
    guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2198
              "MethodHandlePushLimit parameter must be in valid range");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2199
    return MethodHandlePushLimit;
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2200
  case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2201
    // return number of words per slot, signed according to stack direction
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2202
    return MethodHandles::stack_move_unit();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2203
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2204
  return 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2205
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2206
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2207
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2208
#ifndef PRODUCT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2209
#define EACH_NAMED_CON(template) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2210
    template(MethodHandles,GC_JVM_PUSH_LIMIT) \
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2211
    template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2212
    template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2213
    template(MethodHandles,ETF_DIRECT_HANDLE) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2214
    template(MethodHandles,ETF_METHOD_NAME) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2215
    template(MethodHandles,ETF_REFLECT_METHOD) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2216
    template(sun_dyn_MemberName,MN_IS_METHOD) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2217
    template(sun_dyn_MemberName,MN_IS_CONSTRUCTOR) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2218
    template(sun_dyn_MemberName,MN_IS_FIELD) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2219
    template(sun_dyn_MemberName,MN_IS_TYPE) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2220
    template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2221
    template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2222
    template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2223
    template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2224
    template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2225
    template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2226
    template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2227
    template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2228
    template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2229
    template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2230
    template(sun_dyn_AdapterMethodHandle,OP_ROT_ARGS) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2231
    template(sun_dyn_AdapterMethodHandle,OP_DUP_ARGS) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2232
    template(sun_dyn_AdapterMethodHandle,OP_DROP_ARGS) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2233
    template(sun_dyn_AdapterMethodHandle,OP_COLLECT_ARGS) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2234
    template(sun_dyn_AdapterMethodHandle,OP_SPREAD_ARGS) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2235
    template(sun_dyn_AdapterMethodHandle,OP_FLYBY) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2236
    template(sun_dyn_AdapterMethodHandle,OP_RICOCHET) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2237
    template(sun_dyn_AdapterMethodHandle,CONV_OP_LIMIT) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2238
    template(sun_dyn_AdapterMethodHandle,CONV_OP_MASK) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2239
    template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2240
    template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2241
    template(sun_dyn_AdapterMethodHandle,CONV_OP_SHIFT) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2242
    template(sun_dyn_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2243
    template(sun_dyn_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2244
    template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2245
    template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2246
    /*end*/
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2247
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2248
#define ONE_PLUS(scope,value) 1+
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2249
static const int con_value_count = EACH_NAMED_CON(ONE_PLUS) 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2250
#define VALUE_COMMA(scope,value) scope::value,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2251
static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA) 0 };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2252
#define STRING_NULL(scope,value) #value "\0"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2253
static const char con_names[] = { EACH_NAMED_CON(STRING_NULL) };
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2254
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2255
#undef ONE_PLUS
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2256
#undef VALUE_COMMA
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2257
#undef STRING_NULL
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2258
#undef EACH_NAMED_CON
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2259
#endif
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2260
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2261
JVM_ENTRY(jint, MHI_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2262
#ifndef PRODUCT
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2263
  if (which >= 0 && which < con_value_count) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2264
    int con = con_values[which];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2265
    objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2266
    if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2267
      const char* str = &con_names[0];
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2268
      for (int i = 0; i < which; i++)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2269
        str += strlen(str) + 1;   // skip name and null
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2270
      oop name = java_lang_String::create_oop_from_str(str, CHECK_0);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2271
      box->obj_at_put(0, name);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2272
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2273
    return con;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2274
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2275
#endif
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2276
  return 0;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2277
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2278
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2279
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2280
// void init(MemberName self, AccessibleObject ref)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2281
JVM_ENTRY(void, MHI_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2282
  if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2283
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2284
  oop target_oop = JNIHandles::resolve_non_null(target_jh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2285
  MethodHandles::init_MemberName(mname(), target_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2286
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2287
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2288
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2289
// void expand(MemberName self)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2290
JVM_ENTRY(void, MHI_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2291
  if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2292
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2293
  MethodHandles::expand_MemberName(mname, 0, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2294
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2295
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2296
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2297
// void resolve(MemberName self, Class<?> caller)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2298
JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2299
  if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2300
  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2301
  // %%% take caller into account!
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2302
  MethodHandles::resolve_MemberName(mname, CHECK);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2303
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2304
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2305
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2306
//  static native int getMembers(Class<?> defc, String matchName, String matchSig,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2307
//          int matchFlags, Class<?> caller, int skip, MemberName[] results);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2308
JVM_ENTRY(jint, MHI_getMembers(JNIEnv *env, jobject igcls,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2309
                               jclass clazz_jh, jstring name_jh, jstring sig_jh,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2310
                               int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2311
  if (clazz_jh == NULL || results_jh == NULL)  return -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2312
  klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2313
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2314
  objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2315
  if (results == NULL || !results->is_objArray())       return -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2316
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2317
  symbolOop name = NULL, sig = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2318
  if (name_jh != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2319
    name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2320
    if (name == NULL)  return 0; // a match is not possible
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2321
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2322
  if (sig_jh != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2323
    sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2324
    if (sig == NULL)  return 0; // a match is not possible
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2325
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2326
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2327
  klassOop caller = NULL;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2328
  if (caller_jh != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2329
    oop caller_oop = JNIHandles::resolve_non_null(caller_jh);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2330
    if (!java_lang_Class::is_instance(caller_oop))  return -1;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2331
    caller = java_lang_Class::as_klassOop(caller_oop);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2332
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2333
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2334
  if (name != NULL && sig != NULL && results != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2335
    // try a direct resolve
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2336
    // %%% TO DO
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2337
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2338
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2339
  int res = MethodHandles::find_MemberNames(k_oop, name, sig, mflags,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2340
                                            caller, skip, results);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2341
  // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2342
  return res;
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2343
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2344
JVM_END
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2345
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2346
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2347
JVM_ENTRY(void, MH_linkCallSite(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2348
  // No special action required, yet.
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2349
  oop site_oop = JNIHandles::resolve(site_jh);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2350
  if (site_oop == NULL || site_oop->klass() != SystemDictionary::CallSiteImpl_klass())
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2351
    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "call site");
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2352
  sun_dyn_CallSiteImpl::set_target(site_oop, JNIHandles::resolve(target_jh));
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2353
}
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2354
JVM_END
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2355
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2356
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2357
/// JVM_RegisterMethodHandleMethods
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2358
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2359
#define ADR "J"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2360
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2361
#define LANG "Ljava/lang/"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2362
#define JDYN "Ljava/dyn/"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2363
#define IDYN "Lsun/dyn/"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2364
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2365
#define OBJ   LANG"Object;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2366
#define CLS   LANG"Class;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2367
#define STRG  LANG"String;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2368
#define MT    JDYN"MethodType;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2369
#define MH    JDYN"MethodHandle;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2370
#define MHI   IDYN"MethodHandleImpl;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2371
#define MEM   IDYN"MemberName;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2372
#define AMH   IDYN"AdapterMethodHandle;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2373
#define BMH   IDYN"BoundMethodHandle;"
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2374
#define DMH   IDYN"DirectMethodHandle;"
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2375
#define CSTI  IDYN"CallSiteImpl;"
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2376
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2377
#define CC (char*)  /*cast a literal from (const char*)*/
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2378
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2379
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2380
// These are the native methods on sun.dyn.MethodHandleNatives.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2381
static JNINativeMethod methods[] = {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2382
  // void init(MemberName self, AccessibleObject ref)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2383
  {CC"init",                    CC"("AMH""MH"I)V",              FN_PTR(MHI_init_AMH)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2384
  {CC"init",                    CC"("BMH""OBJ"I)V",             FN_PTR(MHI_init_BMH)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2385
  {CC"init",                    CC"("DMH""OBJ"Z"CLS")V",        FN_PTR(MHI_init_DMH)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2386
  {CC"init",                    CC"("MT")V",                    FN_PTR(MHI_init_MT)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2387
  {CC"init",                    CC"("MEM""OBJ")V",              FN_PTR(MHI_init_Mem)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2388
  {CC"expand",                  CC"("MEM")V",                   FN_PTR(MHI_expand_Mem)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2389
  {CC"resolve",                 CC"("MEM""CLS")V",              FN_PTR(MHI_resolve_Mem)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2390
  {CC"getTarget",               CC"("MH"I)"OBJ,                 FN_PTR(MHI_getTarget)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2391
  {CC"getConstant",             CC"(I)I",                       FN_PTR(MHI_getConstant)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2392
  //  static native int getNamedCon(int which, Object[] name)
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2393
  {CC"getNamedCon",             CC"(I["OBJ")I",                 FN_PTR(MHI_getNamedCon)},
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2394
  //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2395
  //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2396
  {CC"getMembers",              CC"("CLS""STRG""STRG"I"CLS"I["MEM")I",  FN_PTR(MHI_getMembers)}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2397
};
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2398
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2399
// More entry points specifically for EnableInvokeDynamic.
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2400
static JNINativeMethod methods2[] = {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2401
  {CC"linkCallSite",            CC"("CSTI MH")V",               FN_PTR(MH_linkCallSite)}
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2402
};
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2403
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2404
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2405
// This one function is exported, used by NativeLookup.
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2406
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2407
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2408
  assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2409
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2410
  // note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2411
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2412
  if (!EnableMethodHandles) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2413
    warning("JSR 292 method handles are disabled in this JVM.  Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable.");
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2414
    return;  // bind nothing
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2415
  }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2416
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2417
  bool enable_MH = true;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2418
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2419
  {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2420
    ThreadToNativeFromVM ttnfv(thread);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2421
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2422
    int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2423
    if (env->ExceptionOccurred()) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2424
      MethodHandles::set_enabled(false);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2425
      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2426
      enable_MH = false;
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2427
      env->ExceptionClear();
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2428
    }
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2429
  }
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2430
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2431
  if (enable_MH) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2432
    KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2433
    if (MHI_klass.not_null()) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2434
      symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2435
      symbolHandle raiseException_sig  = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2436
      methodOop raiseException_method  = instanceKlass::cast(MHI_klass->as_klassOop())
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2437
                    ->find_method(raiseException_name(), raiseException_sig());
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2438
      if (raiseException_method != NULL && raiseException_method->is_static()) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2439
        MethodHandles::set_raise_exception_method(raiseException_method);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2440
      } else {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2441
        warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2442
        enable_MH = false;
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2443
      }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2444
    }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2445
  }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2446
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2447
  if (enable_MH) {
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2448
    MethodHandles::set_enabled(true);
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2449
  }
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2450
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2451
  if (!EnableInvokeDynamic) {
4094
1f424b2b2171 6815692: method handle code needs some cleanup (post-6655638)
jrose
parents: 2570
diff changeset
  2452
    warning("JSR 292 invokedynamic is disabled in this JVM.  Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable.");
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2453
    return;  // bind nothing
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2454
  }
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2455
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2456
  {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2457
    ThreadToNativeFromVM ttnfv(thread);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2458
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2459
    int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2460
    if (env->ExceptionOccurred()) {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2461
      MethodHandles::set_enabled(false);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2462
      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2463
      env->ExceptionClear();
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2464
    } else {
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2465
      MethodHandles::set_enabled(true);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2466
    }
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 2534
diff changeset
  2467
  }
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2468
}
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents:
diff changeset
  2469
JVM_END