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