hotspot/src/share/vm/prims/methodHandleWalk.cpp
author twisti
Mon, 04 Jan 2010 15:52:40 +0100
changeset 4562 5d93cb2d2090
child 4567 7fc02fbe5c7a
permissions -rw-r--r--
6894206: JVM needs a way to traverse method handle structures Summary: We need a way to walk chained method handles in the JVM to call the right methods and to generate required bytecode adapters for the compilers. Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4562
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     1
/*
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     2
 * Copyright 2008-2010 Sun Microsystems, Inc.  All Rights Reserved.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     4
 *
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     7
 * published by the Free Software Foundation.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     8
 *
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    13
 * accompanied this code).
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    14
 *
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    18
 *
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    21
 * have any questions.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    22
 *
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    23
 */
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    24
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    25
/*
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    26
 * JSR 292 reference implementation: method handle structure analysis
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    27
 */
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    28
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    29
#include "incls/_precompiled.incl"
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    30
#include "incls/_methodHandleWalk.cpp.incl"
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    31
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    32
void MethodHandleChain::set_method_handle(Handle mh, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    33
  if (!java_dyn_MethodHandle::is_instance(mh()))  lose("bad method handle", CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    34
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    35
  // set current method handle and unpack partially
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    36
  _method_handle = mh;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    37
  _is_last       = false;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    38
  _is_bound      = false;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    39
  _arg_slot      = -1;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    40
  _arg_type      = T_VOID;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    41
  _conversion    = -1;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    42
  _last_invoke   = Bytecodes::_nop;  //arbitrary non-garbage
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    43
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    44
  if (sun_dyn_DirectMethodHandle::is_instance(mh())) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    45
    set_last_method(mh(), THREAD);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    46
    return;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    47
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    48
  if (sun_dyn_AdapterMethodHandle::is_instance(mh())) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    49
    _conversion = AdapterMethodHandle_conversion();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    50
    assert(_conversion != -1, "bad conv value");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    51
    assert(sun_dyn_BoundMethodHandle::is_instance(mh()), "also BMH");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    52
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    53
  if (sun_dyn_BoundMethodHandle::is_instance(mh())) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    54
    if (!is_adapter())          // keep AMH and BMH separate in this model
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    55
      _is_bound = true;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    56
    _arg_slot = BoundMethodHandle_vmargslot();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    57
    oop target = MethodHandle_vmtarget_oop();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    58
    if (!is_bound() || java_dyn_MethodHandle::is_instance(target)) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    59
      _arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    60
    } else if (target != NULL && target->is_method()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    61
      _arg_type = compute_bound_arg_type(NULL, (methodOop)target, _arg_slot, CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    62
      set_last_method(mh(), CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    63
    } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    64
      _is_bound = false;  // lose!
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    65
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    66
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    67
  if (is_bound() && _arg_type == T_VOID) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    68
    lose("bad vmargslot", CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    69
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    70
  if (!is_bound() && !is_adapter()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    71
    lose("unrecognized MH type", CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    72
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    73
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    74
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    75
void MethodHandleChain::set_last_method(oop target, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    76
  _is_last = true;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    77
  klassOop receiver_limit_oop = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    78
  int flags = 0;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    79
  methodOop m = MethodHandles::decode_method(target, receiver_limit_oop, flags);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    80
  _last_method = methodHandle(THREAD, m);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    81
  if ((flags & MethodHandles::_dmf_has_receiver) == 0)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    82
    _last_invoke = Bytecodes::_invokestatic;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    83
  else if ((flags & MethodHandles::_dmf_does_dispatch) == 0)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    84
    _last_invoke = Bytecodes::_invokespecial;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    85
  else if ((flags & MethodHandles::_dmf_from_interface) != 0)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    86
    _last_invoke = Bytecodes::_invokeinterface;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    87
  else
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    88
    _last_invoke = Bytecodes::_invokevirtual;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    89
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    90
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    91
BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    92
  // There is no direct indication of whether the argument is primitive or not.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    93
  // It is implied by the _vmentry code, and by the MethodType of the target.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    94
  // FIXME: Make it explicit MethodHandleImpl refactors out from MethodHandle
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    95
  BasicType arg_type = T_VOID;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    96
  if (target != NULL) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    97
    oop mtype = java_dyn_MethodHandle::type(target);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    98
    int arg_num = MethodHandles::argument_slot_to_argnum(mtype, arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
    99
    if (arg_num >= 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   100
      oop ptype = java_dyn_MethodType::ptype(mtype, arg_num);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   101
      arg_type = java_lang_Class::as_BasicType(ptype);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   102
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   103
  } else if (m != NULL) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   104
    // figure out the argument type from the slot
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   105
    // FIXME: make this explicit in the MH
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   106
    int cur_slot = m->size_of_parameters();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   107
    if (arg_slot >= cur_slot)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   108
      return T_VOID;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   109
    if (!m->is_static()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   110
      cur_slot -= type2size[T_OBJECT];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   111
      if (cur_slot == arg_slot)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   112
        return T_OBJECT;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   113
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   114
    for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   115
      BasicType bt = ss.type();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   116
      cur_slot -= type2size[bt];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   117
      if (cur_slot <= arg_slot) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   118
        if (cur_slot == arg_slot)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   119
          arg_type = bt;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   120
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   121
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   122
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   123
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   124
  if (arg_type == T_ARRAY)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   125
    arg_type = T_OBJECT;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   126
  return arg_type;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   127
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   128
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   129
void MethodHandleChain::lose(const char* msg, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   130
  _lose_message = msg;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   131
  if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   132
    // throw a preallocated exception
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   133
    THROW_OOP(Universe::virtual_machine_error_instance());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   134
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   135
  THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   136
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   137
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   138
Bytecodes::Code MethodHandleWalker::conversion_code(BasicType src, BasicType dest) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   139
  if (is_subword_type(src)) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   140
    src = T_INT;          // all subword src types act like int
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   141
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   142
  if (src == dest) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   143
    return Bytecodes::_nop;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   144
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   145
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   146
#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d))
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   147
  switch (SRC_DEST(src, dest)) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   148
  case SRC_DEST(T_INT, T_LONG):           return Bytecodes::_i2l;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   149
  case SRC_DEST(T_INT, T_FLOAT):          return Bytecodes::_i2f;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   150
  case SRC_DEST(T_INT, T_DOUBLE):         return Bytecodes::_i2d;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   151
  case SRC_DEST(T_INT, T_BYTE):           return Bytecodes::_i2b;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   152
  case SRC_DEST(T_INT, T_CHAR):           return Bytecodes::_i2c;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   153
  case SRC_DEST(T_INT, T_SHORT):          return Bytecodes::_i2s;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   154
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   155
  case SRC_DEST(T_LONG, T_INT):           return Bytecodes::_l2i;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   156
  case SRC_DEST(T_LONG, T_FLOAT):         return Bytecodes::_l2f;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   157
  case SRC_DEST(T_LONG, T_DOUBLE):        return Bytecodes::_l2d;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   158
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   159
  case SRC_DEST(T_FLOAT, T_INT):          return Bytecodes::_f2i;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   160
  case SRC_DEST(T_FLOAT, T_LONG):         return Bytecodes::_f2l;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   161
  case SRC_DEST(T_FLOAT, T_DOUBLE):       return Bytecodes::_f2d;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   162
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   163
  case SRC_DEST(T_DOUBLE, T_INT):         return Bytecodes::_d2i;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   164
  case SRC_DEST(T_DOUBLE, T_LONG):        return Bytecodes::_d2l;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   165
  case SRC_DEST(T_DOUBLE, T_FLOAT):       return Bytecodes::_d2f;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   166
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   167
#undef SRC_DEST
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   168
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   169
  // cannot do it in one step, or at all
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   170
  return Bytecodes::_illegal;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   171
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   172
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   173
MethodHandleWalker::ArgToken
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   174
MethodHandleWalker::walk(TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   175
  walk_incoming_state(CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   176
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   177
  for (;;) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   178
    set_method_handle(chain().method_handle_oop());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   179
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   180
    assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   181
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   182
    if (chain().is_adapter()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   183
      int conv_op = chain().adapter_conversion_op();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   184
      int arg_slot = chain().adapter_arg_slot();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   185
      SlotState* arg_state = slot_state(arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   186
      if (arg_state == NULL
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   187
          && conv_op > sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   188
        lose("bad argument index", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   189
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   190
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   191
      // perform the adapter action
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   192
      switch (chain().adapter_conversion_op()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   193
      case sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   194
      case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   195
        // No changes to arguments; pass the bits through.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   196
        // The only difference between the two ops is that the "only" version
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   197
        // is fully compatible with the verifier, while the "raw" version
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   198
        // performs a few extra bitwise conversions (like long <-> double).
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   199
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   200
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   201
      case sun_dyn_AdapterMethodHandle::OP_CHECK_CAST: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   202
        // checkcast the Nth outgoing argument in place
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   203
        klassOop dest_klass = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   204
        BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   205
        assert(dest == T_OBJECT, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   206
        assert(dest == arg_state->_type, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   207
        arg_state->_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg_state->_arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   208
        debug_only(dest_klass = (klassOop)badOop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   209
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   210
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   211
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   212
      case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   213
        // i2l, etc., on the Nth outgoing argument in place
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   214
        BasicType src = chain().adapter_conversion_src_type(),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   215
                  dest = chain().adapter_conversion_dest_type();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   216
        Bytecodes::Code bc = conversion_code(src, dest);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   217
        ArgToken arg = arg_state->_arg;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   218
        if (bc == Bytecodes::_nop) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   219
          break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   220
        } else if (bc != Bytecodes::_illegal) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   221
          arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   222
        } else if (is_subword_type(dest)) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   223
          bc = conversion_code(src, T_INT);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   224
          if (bc != Bytecodes::_illegal) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   225
            arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   226
            bc = conversion_code(T_INT, dest);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   227
            arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   228
          }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   229
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   230
        if (bc == Bytecodes::_illegal) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   231
          lose("bad primitive conversion", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   232
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   233
        change_argument(src, arg_slot, dest, arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   234
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   235
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   236
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   237
      case sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   238
        // checkcast to wrapper type & call intValue, etc.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   239
        BasicType dest = chain().adapter_conversion_dest_type();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   240
        ArgToken arg = arg_state->_arg;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   241
        arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   242
                              Bytecodes::_checkcast, arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   243
        vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   244
        if (unboxer == vmIntrinsics::_none) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   245
          lose("no unboxing method", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   246
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   247
        ArgToken arglist[2];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   248
        arglist[0] = arg;       // outgoing 'this'
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   249
        arglist[1] = NULL;      // sentinel
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   250
        arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   251
        change_argument(T_OBJECT, arg_slot, dest, arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   252
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   253
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   254
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   255
      case sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   256
        // call wrapper type.valueOf
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   257
        BasicType src = chain().adapter_conversion_src_type();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   258
        ArgToken arg = arg_state->_arg;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   259
        vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   260
        if (boxer == vmIntrinsics::_none) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   261
          lose("no boxing method", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   262
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   263
        ArgToken arglist[2];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   264
        arglist[0] = arg;       // outgoing value
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   265
        arglist[1] = NULL;      // sentinel
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   266
        arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   267
        change_argument(src, arg_slot, T_OBJECT, arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   268
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   269
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   270
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   271
      case sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   272
        int dest_arg_slot = chain().adapter_conversion_vminfo();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   273
        if (!slot_has_argument(dest_arg_slot)) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   274
          lose("bad swap index", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   275
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   276
        // a simple swap between two arguments
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   277
        SlotState* dest_arg_state = slot_state(dest_arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   278
        SlotState temp = (*dest_arg_state);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   279
        (*dest_arg_state) = (*arg_state);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   280
        (*arg_state) = temp;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   281
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   282
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   283
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   284
      case sun_dyn_AdapterMethodHandle::OP_ROT_ARGS: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   285
        int dest_arg_slot = chain().adapter_conversion_vminfo();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   286
        if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   287
          lose("bad rotate index", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   288
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   289
        SlotState* dest_arg_state = slot_state(dest_arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   290
        // Rotate the source argument (plus following N slots) into the
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   291
        // position occupied by the dest argument (plus following N slots).
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   292
        int rotate_count = type2size[dest_arg_state->_type];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   293
        // (no other rotate counts are currently supported)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   294
        if (arg_slot < dest_arg_slot) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   295
          for (int i = 0; i < rotate_count; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   296
            SlotState temp = _outgoing.at(arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   297
            _outgoing.remove_at(arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   298
            _outgoing.insert_before(dest_arg_slot + rotate_count - 1, temp);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   299
          }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   300
        } else { // arg_slot > dest_arg_slot
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   301
          for (int i = 0; i < rotate_count; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   302
            SlotState temp = _outgoing.at(arg_slot + rotate_count - 1);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   303
            _outgoing.remove_at(arg_slot + rotate_count - 1);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   304
            _outgoing.insert_before(dest_arg_slot, temp);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   305
          }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   306
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   307
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   308
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   309
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   310
      case sun_dyn_AdapterMethodHandle::OP_DUP_ARGS: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   311
        int dup_slots = chain().adapter_conversion_stack_pushes();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   312
        if (dup_slots <= 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   313
          lose("bad dup count", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   314
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   315
        for (int i = 0; i < dup_slots; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   316
          SlotState* dup = slot_state(arg_slot + 2*i);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   317
          if (dup == NULL)              break;  // safety net
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   318
          if (dup->_type != T_VOID)     _outgoing_argc += 1;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   319
          _outgoing.insert_before(i, (*dup));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   320
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   321
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   322
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   323
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   324
      case sun_dyn_AdapterMethodHandle::OP_DROP_ARGS: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   325
        int drop_slots = -chain().adapter_conversion_stack_pushes();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   326
        if (drop_slots <= 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   327
          lose("bad drop count", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   328
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   329
        for (int i = 0; i < drop_slots; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   330
          SlotState* drop = slot_state(arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   331
          if (drop == NULL)             break;  // safety net
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   332
          if (drop->_type != T_VOID)    _outgoing_argc -= 1;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   333
          _outgoing.remove_at(arg_slot);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   334
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   335
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   336
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   337
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   338
      case sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   339
        lose("unimplemented", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   340
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   341
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   342
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   343
      case sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS: {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   344
        klassOop array_klass_oop = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   345
        BasicType array_type = java_lang_Class::as_BasicType(chain().adapter_arg_oop(),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   346
                                                             &array_klass_oop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   347
        assert(array_type == T_OBJECT, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   348
        assert(Klass::cast(array_klass_oop)->oop_is_array(), "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   349
        arrayKlassHandle array_klass(THREAD, array_klass_oop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   350
        debug_only(array_klass_oop = (klassOop)badOop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   351
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   352
        klassOop element_klass_oop = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   353
        BasicType element_type = java_lang_Class::as_BasicType(array_klass->component_mirror(),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   354
                                                               &element_klass_oop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   355
        KlassHandle element_klass(THREAD, element_klass_oop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   356
        debug_only(element_klass_oop = (klassOop)badOop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   357
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   358
        // Fetch the argument, which we will cast to the required array type.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   359
        assert(arg_state->_type == T_OBJECT, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   360
        ArgToken array_arg = arg_state->_arg;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   361
        array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   362
        change_argument(T_OBJECT, arg_slot, T_VOID, NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   363
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   364
        // Check the required length.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   365
        int spread_slots = 1 + chain().adapter_conversion_stack_pushes();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   366
        int spread_length = spread_slots;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   367
        if (type2size[element_type] == 2) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   368
          if (spread_slots % 2 != 0)  spread_slots = -1;  // force error
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   369
          spread_length = spread_slots / 2;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   370
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   371
        if (spread_slots < 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   372
          lose("bad spread length", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   373
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   374
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   375
        jvalue   length_jvalue;  length_jvalue.i = spread_length;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   376
        ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   377
        // Call a built-in method known to the JVM to validate the length.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   378
        ArgToken arglist[3];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   379
        arglist[0] = array_arg;  // value to check
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   380
        arglist[1] = length_arg; // length to check
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   381
        arglist[2] = NULL;       // sentinel
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   382
        make_invoke(NULL, vmIntrinsics::_checkSpreadArgument,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   383
                    Bytecodes::_invokestatic, false, 3, &arglist[0], CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   384
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   385
        // Spread out the array elements.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   386
        Bytecodes::Code aload_op = Bytecodes::_aaload;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   387
        if (element_type != T_OBJECT) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   388
          lose("primitive array NYI", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   389
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   390
        int ap = arg_slot;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   391
        for (int i = 0; i < spread_length; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   392
          jvalue   offset_jvalue;  offset_jvalue.i = i;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   393
          ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   394
          ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   395
          change_argument(T_VOID, ap, element_type, element_arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   396
          ap += type2size[element_type];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   397
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   398
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   399
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   400
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   401
      case sun_dyn_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   402
      case sun_dyn_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   403
        lose("unimplemented", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   404
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   405
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   406
      default:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   407
        lose("bad adapter conversion", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   408
        break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   409
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   410
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   411
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   412
    if (chain().is_bound()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   413
      // push a new argument
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   414
      BasicType arg_type  = chain().bound_arg_type();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   415
      jint      arg_slot  = chain().bound_arg_slot();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   416
      oop       arg_oop   = chain().bound_arg_oop();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   417
      ArgToken  arg       = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   418
      if (arg_type == T_OBJECT) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   419
        arg = make_oop_constant(arg_oop, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   420
      } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   421
        jvalue arg_value;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   422
        BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   423
        if (bt == arg_type) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   424
          arg = make_prim_constant(arg_type, &arg_value, CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   425
        } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   426
          lose("bad bound value", CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   427
        }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   428
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   429
      debug_only(arg_oop = badOop);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   430
      change_argument(T_VOID, arg_slot, arg_type, arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   431
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   432
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   433
    // this test must come after the body of the loop
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   434
    if (!chain().is_last()) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   435
      chain().next(CHECK_NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   436
    } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   437
      break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   438
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   439
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   440
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   441
  // finish the sequence with a tail-call to the ultimate target
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   442
  // parameters are passed in logical order (recv 1st), not slot order
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   443
  ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, _outgoing.length() + 1);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   444
  int ap = 0;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   445
  for (int i = _outgoing.length() - 1; i >= 0; i--) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   446
    SlotState* arg_state = slot_state(i);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   447
    if (arg_state->_type == T_VOID)  continue;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   448
    arglist[ap++] = _outgoing.at(i)._arg;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   449
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   450
  assert(ap == _outgoing_argc, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   451
  arglist[ap] = NULL; // add a sentinel, for the sake of asserts
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   452
  return make_invoke(chain().last_method_oop(),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   453
                     vmIntrinsics::_none,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   454
                     chain().last_invoke_code(), true,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   455
                     ap, arglist, THREAD);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   456
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   457
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   458
void MethodHandleWalker::walk_incoming_state(TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   459
  Handle mtype(THREAD, chain().method_type_oop());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   460
  int nptypes = java_dyn_MethodType::ptype_count(mtype());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   461
  _outgoing_argc = nptypes;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   462
  int argp = nptypes - 1;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   463
  if (argp >= 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   464
    _outgoing.at_grow(argp, make_state(T_VOID, NULL)); // presize
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   465
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   466
  for (int i = 0; i < nptypes; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   467
    klassOop  arg_type_klass = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   468
    BasicType arg_type = java_lang_Class::as_BasicType(
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   469
                java_dyn_MethodType::ptype(mtype(), i), &arg_type_klass);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   470
    ArgToken  arg = make_parameter(arg_type, arg_type_klass, i, CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   471
    debug_only(arg_type_klass = (klassOop)NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   472
    _outgoing.at_put(argp, make_state(arg_type, arg));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   473
    if (type2size[arg_type] == 2) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   474
      // add the extra slot, so we can model the JVM stack
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   475
      _outgoing.insert_before(argp+1, make_state(T_VOID, NULL));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   476
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   477
    --argp;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   478
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   479
  // call make_parameter at the end of the list for the return type
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   480
  klassOop  ret_type_klass = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   481
  BasicType ret_type = java_lang_Class::as_BasicType(
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   482
              java_dyn_MethodType::rtype(mtype()), &ret_type_klass);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   483
  ArgToken  ret = make_parameter(ret_type, ret_type_klass, -1, CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   484
  // ignore ret; client can catch it if needed
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   485
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   486
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   487
// this is messy because some kinds of arguments are paired with
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   488
// companion slots containing an empty value
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   489
void MethodHandleWalker::change_argument(BasicType old_type, int slot, BasicType new_type,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   490
                                         MethodHandleWalker::ArgToken new_arg) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   491
  int old_size = type2size[old_type];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   492
  int new_size = type2size[new_type];
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   493
  if (old_size == new_size) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   494
    // simple case first
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   495
    _outgoing.at_put(slot, make_state(new_type, new_arg));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   496
  } else if (old_size > new_size) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   497
    for (int i = old_size-1; i >= new_size; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   498
      assert((i != 0) == (_outgoing.at(slot + i)._type == T_VOID), "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   499
      _outgoing.remove_at(slot + i);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   500
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   501
    if (new_size > 0)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   502
      _outgoing.at_put(slot, make_state(new_type, new_arg));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   503
    else
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   504
      _outgoing_argc -= 1;      // deleted a real argument
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   505
  } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   506
    for (int i = old_size; i < new_size; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   507
      _outgoing.insert_before(slot+i, make_state(T_VOID, NULL));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   508
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   509
    _outgoing.at_put(slot, make_state(new_type, new_arg));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   510
    if (old_size == 0)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   511
      _outgoing_argc += 1;      // inserted a real argument
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   512
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   513
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   514
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   515
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   516
#ifdef ASSERT
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   517
int MethodHandleWalker::argument_count_slow() {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   518
  int args_seen = 0;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   519
  for (int i = _outgoing.length() - 1; i >= 0; i--) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   520
    if (_outgoing.at(i)._type != T_VOID) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   521
      ++args_seen;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   522
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   523
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   524
  return args_seen;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   525
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   526
#endif
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   527
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   528
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   529
void MethodHandleCompiler::compile(TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   530
  assert(_thread == THREAD, "must be same thread");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   531
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   532
  _constant_oops.append(Handle());  // element zero is always the null constant
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   533
  _constant_prims.append(NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   534
  {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   535
    symbolOop sig
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   536
      = java_dyn_MethodType::as_signature(chain().method_type_oop(), true, CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   537
    _signature_index = find_oop_constant(sig);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   538
    assert(signature() == sig, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   539
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   540
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   541
  walk(CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   542
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   543
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   544
MethodHandleWalker::ArgToken
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   545
MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Code op,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   546
                                      MethodHandleWalker::ArgToken src, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   547
  Unimplemented();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   548
  return NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   549
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   550
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   551
MethodHandleWalker::ArgToken
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   552
MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   553
                                  Bytecodes::Code op, bool tailcall,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   554
                                  int argc, MethodHandleWalker::ArgToken* argv,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   555
                                  TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   556
  // If tailcall, we have walked all the way to a direct method handle.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   557
  // Otherwise, make a recursive call to some helper routine.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   558
#ifdef ASSERT
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   559
  switch (op) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   560
  case Bytecodes::_invokevirtual:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   561
  case Bytecodes::_invokespecial:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   562
  case Bytecodes::_invokestatic:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   563
  case Bytecodes::_invokeinterface:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   564
    break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   565
  default:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   566
    ShouldNotReachHere();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   567
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   568
#endif //ASSERT
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   569
  _bytes.put((char) op);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   570
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   571
  Unimplemented();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   572
  return NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   573
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   574
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   575
MethodHandleWalker::ArgToken
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   576
MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   577
                                 MethodHandleWalker::ArgToken base,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   578
                                 MethodHandleWalker::ArgToken offset,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   579
                                 TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   580
  Unimplemented();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   581
  return NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   582
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   583
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   584
int MethodHandleCompiler::find_oop_constant(oop con) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   585
  if (con == NULL)  return 0;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   586
  for (int i = 1, imax = _constant_oops.length(); i < imax; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   587
    if (_constant_oops.at(i) == con)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   588
      return i;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   589
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   590
  _constant_prims.append(NULL);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   591
  return _constant_oops.append(con);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   592
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   593
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   594
int MethodHandleCompiler::find_prim_constant(BasicType bt, jvalue* con) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   595
  jvalue con_copy;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   596
  assert(bt < T_OBJECT, "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   597
  if (type2aelembytes(bt) < jintSize) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   598
    // widen to int
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   599
    con_copy = (*con);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   600
    con = &con_copy;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   601
    switch (bt) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   602
    case T_BOOLEAN: con->i = (con->z ? 1 : 0); break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   603
    case T_BYTE:    con->i = con->b;           break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   604
    case T_CHAR:    con->i = con->c;           break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   605
    case T_SHORT:   con->i = con->s;           break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   606
    default: ShouldNotReachHere();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   607
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   608
    bt = T_INT;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   609
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   610
  for (int i = 1, imax = _constant_prims.length(); i < imax; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   611
    PrimCon* pcon = _constant_prims.at(i);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   612
    if (pcon != NULL && pcon->_type == bt) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   613
      bool match = false;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   614
      switch (type2size[bt]) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   615
      case 1:  if (pcon->_value.i == con->i)  match = true;  break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   616
      case 2:  if (pcon->_value.j == con->j)  match = true;  break;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   617
      }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   618
      if (match)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   619
        return i;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   620
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   621
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   622
  PrimCon* pcon = new PrimCon();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   623
  pcon->_type = bt;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   624
  pcon->_value = (*con);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   625
  _constant_oops.append(Handle());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   626
  return _constant_prims.append(pcon);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   627
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   628
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   629
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   630
#ifndef PRODUCT
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   631
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   632
// MH printer for debugging.
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   633
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   634
class MethodHandlePrinter : public MethodHandleWalker {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   635
private:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   636
  outputStream* _out;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   637
  bool          _verbose;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   638
  int           _temp_num;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   639
  stringStream  _strbuf;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   640
  const char* strbuf() {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   641
    const char* s = _strbuf.as_string();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   642
    _strbuf.reset();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   643
    return s;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   644
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   645
  ArgToken token(const char* str) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   646
    return (ArgToken) str;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   647
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   648
  void start_params() {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   649
    _out->print("(");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   650
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   651
  void end_params() {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   652
    if (_verbose)  _out->print("\n");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   653
    _out->print(") => {");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   654
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   655
  void put_type_name(BasicType type, klassOop tk, outputStream* s) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   656
    const char* kname = NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   657
    if (tk != NULL)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   658
      kname = Klass::cast(tk)->external_name();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   659
    s->print("%s", (kname != NULL) ? kname : type2name(type));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   660
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   661
  ArgToken maybe_make_temp(const char* statement_op, BasicType type, const char* temp_name) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   662
    const char* value = strbuf();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   663
    if (!_verbose)  return token(value);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   664
    // make an explicit binding for each separate value
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   665
    _strbuf.print("%s%d", temp_name, ++_temp_num);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   666
    const char* temp = strbuf();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   667
    _out->print("\n  %s %s %s = %s;", statement_op, type2name(type), temp, value);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   668
    return token(temp);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   669
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   670
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   671
public:
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   672
  MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   673
    : MethodHandleWalker(root, THREAD),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   674
      _out(out),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   675
      _verbose(verbose),
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   676
      _temp_num(0)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   677
  {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   678
    start_params();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   679
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   680
  virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   681
    if (argnum < 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   682
      end_params();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   683
      return NULL;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   684
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   685
    if (argnum == 0) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   686
      _out->print(_verbose ? "\n  " : "");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   687
    } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   688
      _out->print(_verbose ? ",\n  " : ", ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   689
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   690
    if (argnum >= _temp_num)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   691
      _temp_num = argnum;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   692
    // generate an argument name
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   693
    _strbuf.print("a%d", argnum);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   694
    const char* arg = strbuf();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   695
    put_type_name(type, tk, _out);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   696
    _out->print(" %s", arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   697
    return token(arg);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   698
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   699
  virtual ArgToken make_oop_constant(oop con, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   700
    if (con == NULL)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   701
      _strbuf.print("null");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   702
    else
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   703
      con->print_value_on(&_strbuf);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   704
    if (_strbuf.size() == 0) {  // yuck
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   705
      _strbuf.print("(a ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   706
      put_type_name(T_OBJECT, con->klass(), &_strbuf);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   707
      _strbuf.print(")");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   708
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   709
    return maybe_make_temp("constant", T_OBJECT, "k");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   710
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   711
  virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   712
    java_lang_boxing_object::print(type, con, &_strbuf);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   713
    return maybe_make_temp("constant", type, "k");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   714
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   715
  virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, ArgToken src, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   716
    _strbuf.print("%s(%s", Bytecodes::name(op), (const char*)src);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   717
    if (tk != NULL) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   718
      _strbuf.print(", ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   719
      put_type_name(type, tk, &_strbuf);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   720
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   721
    _strbuf.print(")");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   722
    return maybe_make_temp("convert", type, "v");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   723
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   724
  virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, ArgToken base, ArgToken offset, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   725
    _strbuf.print("%s(%s, %s", Bytecodes::name(op), (const char*)base, (const char*)offset);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   726
    if (tk != NULL) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   727
      _strbuf.print(", ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   728
      put_type_name(type, tk, &_strbuf);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   729
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   730
    _strbuf.print(")");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   731
    return maybe_make_temp("fetch", type, "x");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   732
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   733
  virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   734
                               Bytecodes::Code op, bool tailcall,
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   735
                               int argc, ArgToken* argv, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   736
    symbolOop name, sig;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   737
    if (m != NULL) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   738
      name = m->name();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   739
      sig  = m->signature();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   740
    } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   741
      name = vmSymbols::symbol_at(vmIntrinsics::name_for(iid));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   742
      sig  = vmSymbols::symbol_at(vmIntrinsics::signature_for(iid));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   743
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   744
    _strbuf.print("%s %s%s(", Bytecodes::name(op), name->as_C_string(), sig->as_C_string());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   745
    for (int i = 0; i < argc; i++) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   746
      _strbuf.print("%s%s", (i > 0 ? ", " : ""), (const char*)argv[i]);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   747
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   748
    _strbuf.print(")");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   749
    if (!tailcall) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   750
      BasicType rt = char2type(sig->byte_at(sig->utf8_length()-1));
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   751
      if (rt == T_ILLEGAL)  rt = T_OBJECT;  // ';' at the end of '(...)L...;'
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   752
      return maybe_make_temp("invoke", rt, "x");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   753
    } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   754
      const char* ret = strbuf();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   755
      _out->print(_verbose ? "\n  return " : " ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   756
      _out->print("%s", ret);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   757
      _out->print(_verbose ? "\n}\n" : " }");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   758
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   759
    return ArgToken();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   760
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   761
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   762
  virtual void set_method_handle(oop mh) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   763
    if (WizardMode && Verbose) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   764
      tty->print("\n--- next target: ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   765
      mh->print();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   766
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   767
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   768
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   769
  static void print(Handle root, bool verbose, outputStream* out, TRAPS) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   770
    ResourceMark rm;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   771
    MethodHandlePrinter printer(root, verbose, out, CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   772
    printer.walk(CHECK);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   773
    out->print("\n");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   774
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   775
  static void print(Handle root, bool verbose = Verbose, outputStream* out = tty) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   776
    EXCEPTION_MARK;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   777
    ResourceMark rm;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   778
    MethodHandlePrinter printer(root, verbose, out, THREAD);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   779
    if (!HAS_PENDING_EXCEPTION)
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   780
      printer.walk(THREAD);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   781
    if (HAS_PENDING_EXCEPTION) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   782
      oop ex = PENDING_EXCEPTION;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   783
      CLEAR_PENDING_EXCEPTION;
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   784
      out->print("\n*** ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   785
      if (ex != Universe::virtual_machine_error_instance())
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   786
        ex->print_on(out);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   787
      else
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   788
        out->print("lose: %s", printer.lose_message());
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   789
      out->print("\n}\n");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   790
    }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   791
    out->print("\n");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   792
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   793
};
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   794
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   795
extern "C"
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   796
void print_method_handle(oop mh) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   797
  if (java_dyn_MethodHandle::is_instance(mh)) {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   798
    MethodHandlePrinter::print(mh);
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   799
  } else {
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   800
    tty->print("*** not a method handle: ");
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   801
    mh->print();
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   802
  }
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   803
}
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   804
5d93cb2d2090 6894206: JVM needs a way to traverse method handle structures
twisti
parents:
diff changeset
   805
#endif // PRODUCT