src/share/vm/prims/methodHandleWalk.cpp

changeset 1573
dd57230ba8fe
parent 1568
aa62b9388fce
child 1577
4ce7240d622c
     1.1 --- a/src/share/vm/prims/methodHandleWalk.cpp	Tue Jan 05 13:05:58 2010 +0100
     1.2 +++ b/src/share/vm/prims/methodHandleWalk.cpp	Tue Jan 05 15:21:25 2010 +0100
     1.3 @@ -29,6 +29,10 @@
     1.4  #include "incls/_precompiled.incl"
     1.5  #include "incls/_methodHandleWalk.cpp.incl"
     1.6  
     1.7 +
     1.8 +// -----------------------------------------------------------------------------
     1.9 +// MethodHandleChain
    1.10 +
    1.11  void MethodHandleChain::set_method_handle(Handle mh, TRAPS) {
    1.12    if (!java_dyn_MethodHandle::is_instance(mh()))  lose("bad method handle", CHECK);
    1.13  
    1.14 @@ -58,7 +62,8 @@
    1.15      if (!is_bound() || java_dyn_MethodHandle::is_instance(target)) {
    1.16        _arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK);
    1.17      } else if (target != NULL && target->is_method()) {
    1.18 -      _arg_type = compute_bound_arg_type(NULL, (methodOop)target, _arg_slot, CHECK);
    1.19 +      methodOop m = (methodOop) target;
    1.20 +      _arg_type = compute_bound_arg_type(NULL, m, _arg_slot, CHECK);
    1.21        set_last_method(mh(), CHECK);
    1.22      } else {
    1.23        _is_bound = false;  // lose!
    1.24 @@ -72,6 +77,7 @@
    1.25    }
    1.26  }
    1.27  
    1.28 +
    1.29  void MethodHandleChain::set_last_method(oop target, TRAPS) {
    1.30    _is_last = true;
    1.31    klassOop receiver_limit_oop = NULL;
    1.32 @@ -88,6 +94,7 @@
    1.33      _last_invoke = Bytecodes::_invokevirtual;
    1.34  }
    1.35  
    1.36 +
    1.37  BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) {
    1.38    // There is no direct indication of whether the argument is primitive or not.
    1.39    // It is implied by the _vmentry code, and by the MethodType of the target.
    1.40 @@ -126,7 +133,9 @@
    1.41    return arg_type;
    1.42  }
    1.43  
    1.44 +
    1.45  void MethodHandleChain::lose(const char* msg, TRAPS) {
    1.46 +  assert(false, "lose");
    1.47    _lose_message = msg;
    1.48    if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) {
    1.49      // throw a preallocated exception
    1.50 @@ -135,6 +144,10 @@
    1.51    THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
    1.52  }
    1.53  
    1.54 +
    1.55 +// -----------------------------------------------------------------------------
    1.56 +// MethodHandleWalker
    1.57 +
    1.58  Bytecodes::Code MethodHandleWalker::conversion_code(BasicType src, BasicType dest) {
    1.59    if (is_subword_type(src)) {
    1.60      src = T_INT;          // all subword src types act like int
    1.61 @@ -170,9 +183,15 @@
    1.62    return Bytecodes::_illegal;
    1.63  }
    1.64  
    1.65 +
    1.66 +// -----------------------------------------------------------------------------
    1.67 +// MethodHandleWalker::walk
    1.68 +//
    1.69  MethodHandleWalker::ArgToken
    1.70  MethodHandleWalker::walk(TRAPS) {
    1.71 -  walk_incoming_state(CHECK_NULL);
    1.72 +  ArgToken empty = ArgToken();  // Empty return value.
    1.73 +
    1.74 +  walk_incoming_state(CHECK_(empty));
    1.75  
    1.76    for (;;) {
    1.77      set_method_handle(chain().method_handle_oop());
    1.78 @@ -185,26 +204,77 @@
    1.79        SlotState* arg_state = slot_state(arg_slot);
    1.80        if (arg_state == NULL
    1.81            && conv_op > sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW) {
    1.82 -        lose("bad argument index", CHECK_NULL);
    1.83 +        lose("bad argument index", CHECK_(empty));
    1.84        }
    1.85  
    1.86        // perform the adapter action
    1.87        switch (chain().adapter_conversion_op()) {
    1.88        case sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY:
    1.89 -      case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW:
    1.90          // No changes to arguments; pass the bits through.
    1.91 -        // The only difference between the two ops is that the "only" version
    1.92 -        // is fully compatible with the verifier, while the "raw" version
    1.93 -        // performs a few extra bitwise conversions (like long <-> double).
    1.94          break;
    1.95  
    1.96 +      case sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW: {
    1.97 +        // To keep the verifier happy, emit bitwise ("raw") conversions as needed.
    1.98 +        // See MethodHandles::same_basic_type_for_arguments for allowed conversions.
    1.99 +        Handle incoming_mtype(THREAD, chain().method_type_oop());
   1.100 +        oop outgoing_mh_oop = chain().vmtarget_oop();
   1.101 +        if (!java_dyn_MethodHandle::is_instance(outgoing_mh_oop))
   1.102 +          lose("outgoing target not a MethodHandle", CHECK_(empty));
   1.103 +        Handle outgoing_mtype(THREAD, java_dyn_MethodHandle::type(outgoing_mh_oop));
   1.104 +        outgoing_mh_oop = NULL;  // GC safety
   1.105 +
   1.106 +        int nptypes = java_dyn_MethodType::ptype_count(outgoing_mtype());
   1.107 +        if (nptypes != java_dyn_MethodType::ptype_count(incoming_mtype()))
   1.108 +          lose("incoming and outgoing parameter count do not agree", CHECK_(empty));
   1.109 +
   1.110 +        for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) {
   1.111 +          SlotState* arg_state = slot_state(slot);
   1.112 +          if (arg_state->_type == T_VOID)  continue;
   1.113 +          ArgToken arg = _outgoing.at(slot)._arg;
   1.114 +
   1.115 +          klassOop  in_klass  = NULL;
   1.116 +          klassOop  out_klass = NULL;
   1.117 +          BasicType inpbt  = java_lang_Class::as_BasicType(java_dyn_MethodType::ptype(incoming_mtype(), i), &in_klass);
   1.118 +          BasicType outpbt = java_lang_Class::as_BasicType(java_dyn_MethodType::ptype(outgoing_mtype(), i), &out_klass);
   1.119 +          assert(inpbt == arg.basic_type(), "sanity");
   1.120 +
   1.121 +          if (inpbt != outpbt) {
   1.122 +            vmIntrinsics::ID iid = vmIntrinsics::for_raw_conversion(inpbt, outpbt);
   1.123 +            if (iid == vmIntrinsics::_none) {
   1.124 +              lose("no raw conversion method", CHECK_(empty));
   1.125 +            }
   1.126 +            ArgToken arglist[2];
   1.127 +            arglist[0] = arg;         // outgoing 'this'
   1.128 +            arglist[1] = ArgToken();  // sentinel
   1.129 +            arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
   1.130 +            change_argument(inpbt, slot, outpbt, arg);
   1.131 +          }
   1.132 +
   1.133 +          i++;  // We need to skip void slots at the top of the loop.
   1.134 +        }
   1.135 +
   1.136 +        BasicType inrbt  = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(incoming_mtype()));
   1.137 +        BasicType outrbt = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(outgoing_mtype()));
   1.138 +        if (inrbt != outrbt) {
   1.139 +          if (inrbt == T_INT && outrbt == T_VOID) {
   1.140 +            // See comments in MethodHandles::same_basic_type_for_arguments.
   1.141 +          } else {
   1.142 +            assert(false, "IMPLEMENT ME");
   1.143 +            lose("no raw conversion method", CHECK_(empty));
   1.144 +          }
   1.145 +        }
   1.146 +        break;
   1.147 +      }
   1.148 +
   1.149        case sun_dyn_AdapterMethodHandle::OP_CHECK_CAST: {
   1.150          // checkcast the Nth outgoing argument in place
   1.151          klassOop dest_klass = NULL;
   1.152          BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass);
   1.153          assert(dest == T_OBJECT, "");
   1.154          assert(dest == arg_state->_type, "");
   1.155 -        arg_state->_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg_state->_arg, CHECK_NULL);
   1.156 +        ArgToken arg = arg_state->_arg;
   1.157 +        ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty));
   1.158 +        assert(arg.index() == new_arg.index(), "should be the same index");
   1.159          debug_only(dest_klass = (klassOop)badOop);
   1.160          break;
   1.161        }
   1.162 @@ -218,17 +288,17 @@
   1.163          if (bc == Bytecodes::_nop) {
   1.164            break;
   1.165          } else if (bc != Bytecodes::_illegal) {
   1.166 -          arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL);
   1.167 +          arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
   1.168          } else if (is_subword_type(dest)) {
   1.169            bc = conversion_code(src, T_INT);
   1.170            if (bc != Bytecodes::_illegal) {
   1.171 -            arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL);
   1.172 +            arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
   1.173              bc = conversion_code(T_INT, dest);
   1.174 -            arg = make_conversion(dest, NULL, bc, arg, CHECK_NULL);
   1.175 +            arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
   1.176            }
   1.177          }
   1.178          if (bc == Bytecodes::_illegal) {
   1.179 -          lose("bad primitive conversion", CHECK_NULL);
   1.180 +          lose("bad primitive conversion", CHECK_(empty));
   1.181          }
   1.182          change_argument(src, arg_slot, dest, arg);
   1.183          break;
   1.184 @@ -239,15 +309,15 @@
   1.185          BasicType dest = chain().adapter_conversion_dest_type();
   1.186          ArgToken arg = arg_state->_arg;
   1.187          arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest),
   1.188 -                              Bytecodes::_checkcast, arg, CHECK_NULL);
   1.189 +                              Bytecodes::_checkcast, arg, CHECK_(empty));
   1.190          vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest);
   1.191          if (unboxer == vmIntrinsics::_none) {
   1.192 -          lose("no unboxing method", CHECK_NULL);
   1.193 +          lose("no unboxing method", CHECK_(empty));
   1.194          }
   1.195          ArgToken arglist[2];
   1.196 -        arglist[0] = arg;       // outgoing 'this'
   1.197 -        arglist[1] = NULL;      // sentinel
   1.198 -        arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL);
   1.199 +        arglist[0] = arg;         // outgoing 'this'
   1.200 +        arglist[1] = ArgToken();  // sentinel
   1.201 +        arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_(empty));
   1.202          change_argument(T_OBJECT, arg_slot, dest, arg);
   1.203          break;
   1.204        }
   1.205 @@ -258,12 +328,13 @@
   1.206          ArgToken arg = arg_state->_arg;
   1.207          vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src);
   1.208          if (boxer == vmIntrinsics::_none) {
   1.209 -          lose("no boxing method", CHECK_NULL);
   1.210 +          lose("no boxing method", CHECK_(empty));
   1.211          }
   1.212          ArgToken arglist[2];
   1.213 -        arglist[0] = arg;       // outgoing value
   1.214 -        arglist[1] = NULL;      // sentinel
   1.215 -        arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_NULL);
   1.216 +        arglist[0] = arg;         // outgoing value
   1.217 +        arglist[1] = ArgToken();  // sentinel
   1.218 +        assert(false, "I think the argument count must be 1 instead of 0");
   1.219 +        arg = make_invoke(NULL, boxer, Bytecodes::_invokevirtual, false, 0, &arglist[0], CHECK_(empty));
   1.220          change_argument(src, arg_slot, T_OBJECT, arg);
   1.221          break;
   1.222        }
   1.223 @@ -271,7 +342,7 @@
   1.224        case sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS: {
   1.225          int dest_arg_slot = chain().adapter_conversion_vminfo();
   1.226          if (!slot_has_argument(dest_arg_slot)) {
   1.227 -          lose("bad swap index", CHECK_NULL);
   1.228 +          lose("bad swap index", CHECK_(empty));
   1.229          }
   1.230          // a simple swap between two arguments
   1.231          SlotState* dest_arg_state = slot_state(dest_arg_slot);
   1.232 @@ -284,7 +355,7 @@
   1.233        case sun_dyn_AdapterMethodHandle::OP_ROT_ARGS: {
   1.234          int dest_arg_slot = chain().adapter_conversion_vminfo();
   1.235          if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) {
   1.236 -          lose("bad rotate index", CHECK_NULL);
   1.237 +          lose("bad rotate index", CHECK_(empty));
   1.238          }
   1.239          SlotState* dest_arg_state = slot_state(dest_arg_slot);
   1.240          // Rotate the source argument (plus following N slots) into the
   1.241 @@ -310,7 +381,7 @@
   1.242        case sun_dyn_AdapterMethodHandle::OP_DUP_ARGS: {
   1.243          int dup_slots = chain().adapter_conversion_stack_pushes();
   1.244          if (dup_slots <= 0) {
   1.245 -          lose("bad dup count", CHECK_NULL);
   1.246 +          lose("bad dup count", CHECK_(empty));
   1.247          }
   1.248          for (int i = 0; i < dup_slots; i++) {
   1.249            SlotState* dup = slot_state(arg_slot + 2*i);
   1.250 @@ -324,7 +395,7 @@
   1.251        case sun_dyn_AdapterMethodHandle::OP_DROP_ARGS: {
   1.252          int drop_slots = -chain().adapter_conversion_stack_pushes();
   1.253          if (drop_slots <= 0) {
   1.254 -          lose("bad drop count", CHECK_NULL);
   1.255 +          lose("bad drop count", CHECK_(empty));
   1.256          }
   1.257          for (int i = 0; i < drop_slots; i++) {
   1.258            SlotState* drop = slot_state(arg_slot);
   1.259 @@ -336,7 +407,7 @@
   1.260        }
   1.261  
   1.262        case sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS: { //NYI, may GC
   1.263 -        lose("unimplemented", CHECK_NULL);
   1.264 +        lose("unimplemented", CHECK_(empty));
   1.265          break;
   1.266        }
   1.267  
   1.268 @@ -358,8 +429,8 @@
   1.269          // Fetch the argument, which we will cast to the required array type.
   1.270          assert(arg_state->_type == T_OBJECT, "");
   1.271          ArgToken array_arg = arg_state->_arg;
   1.272 -        array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_NULL);
   1.273 -        change_argument(T_OBJECT, arg_slot, T_VOID, NULL);
   1.274 +        array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_(empty));
   1.275 +        change_argument(T_OBJECT, arg_slot, T_VOID, ArgToken(tt_void));
   1.276  
   1.277          // Check the required length.
   1.278          int spread_slots = 1 + chain().adapter_conversion_stack_pushes();
   1.279 @@ -369,29 +440,29 @@
   1.280            spread_length = spread_slots / 2;
   1.281          }
   1.282          if (spread_slots < 0) {
   1.283 -          lose("bad spread length", CHECK_NULL);
   1.284 +          lose("bad spread length", CHECK_(empty));
   1.285          }
   1.286  
   1.287          jvalue   length_jvalue;  length_jvalue.i = spread_length;
   1.288 -        ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_NULL);
   1.289 +        ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_(empty));
   1.290          // Call a built-in method known to the JVM to validate the length.
   1.291          ArgToken arglist[3];
   1.292 -        arglist[0] = array_arg;  // value to check
   1.293 -        arglist[1] = length_arg; // length to check
   1.294 -        arglist[2] = NULL;       // sentinel
   1.295 +        arglist[0] = array_arg;   // value to check
   1.296 +        arglist[1] = length_arg;  // length to check
   1.297 +        arglist[2] = ArgToken();  // sentinel
   1.298          make_invoke(NULL, vmIntrinsics::_checkSpreadArgument,
   1.299 -                    Bytecodes::_invokestatic, false, 3, &arglist[0], CHECK_NULL);
   1.300 +                    Bytecodes::_invokestatic, false, 3, &arglist[0], CHECK_(empty));
   1.301  
   1.302          // Spread out the array elements.
   1.303          Bytecodes::Code aload_op = Bytecodes::_aaload;
   1.304          if (element_type != T_OBJECT) {
   1.305 -          lose("primitive array NYI", CHECK_NULL);
   1.306 +          lose("primitive array NYI", CHECK_(empty));
   1.307          }
   1.308          int ap = arg_slot;
   1.309          for (int i = 0; i < spread_length; i++) {
   1.310            jvalue   offset_jvalue;  offset_jvalue.i = i;
   1.311 -          ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_NULL);
   1.312 -          ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_NULL);
   1.313 +          ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_(empty));
   1.314 +          ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_(empty));
   1.315            change_argument(T_VOID, ap, element_type, element_arg);
   1.316            ap += type2size[element_type];
   1.317          }
   1.318 @@ -400,11 +471,11 @@
   1.319  
   1.320        case sun_dyn_AdapterMethodHandle::OP_FLYBY: //NYI, runs Java code
   1.321        case sun_dyn_AdapterMethodHandle::OP_RICOCHET: //NYI, runs Java code
   1.322 -        lose("unimplemented", CHECK_NULL);
   1.323 +        lose("unimplemented", CHECK_(empty));
   1.324          break;
   1.325  
   1.326        default:
   1.327 -        lose("bad adapter conversion", CHECK_NULL);
   1.328 +        lose("bad adapter conversion", CHECK_(empty));
   1.329          break;
   1.330        }
   1.331      }
   1.332 @@ -414,16 +485,16 @@
   1.333        BasicType arg_type  = chain().bound_arg_type();
   1.334        jint      arg_slot  = chain().bound_arg_slot();
   1.335        oop       arg_oop   = chain().bound_arg_oop();
   1.336 -      ArgToken  arg       = NULL;
   1.337 +      ArgToken  arg;
   1.338        if (arg_type == T_OBJECT) {
   1.339 -        arg = make_oop_constant(arg_oop, CHECK_NULL);
   1.340 +        arg = make_oop_constant(arg_oop, CHECK_(empty));
   1.341        } else {
   1.342          jvalue arg_value;
   1.343          BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value);
   1.344          if (bt == arg_type) {
   1.345 -          arg = make_prim_constant(arg_type, &arg_value, CHECK_NULL);
   1.346 +          arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty));
   1.347          } else {
   1.348 -          lose("bad bound value", CHECK_NULL);
   1.349 +          lose("bad bound value", CHECK_(empty));
   1.350          }
   1.351        }
   1.352        debug_only(arg_oop = badOop);
   1.353 @@ -432,7 +503,7 @@
   1.354  
   1.355      // this test must come after the body of the loop
   1.356      if (!chain().is_last()) {
   1.357 -      chain().next(CHECK_NULL);
   1.358 +      chain().next(CHECK_(empty));
   1.359      } else {
   1.360        break;
   1.361      }
   1.362 @@ -448,31 +519,36 @@
   1.363      arglist[ap++] = _outgoing.at(i)._arg;
   1.364    }
   1.365    assert(ap == _outgoing_argc, "");
   1.366 -  arglist[ap] = NULL; // add a sentinel, for the sake of asserts
   1.367 +  arglist[ap] = ArgToken();  // add a sentinel, for the sake of asserts
   1.368    return make_invoke(chain().last_method_oop(),
   1.369                       vmIntrinsics::_none,
   1.370                       chain().last_invoke_code(), true,
   1.371                       ap, arglist, THREAD);
   1.372  }
   1.373  
   1.374 +
   1.375 +// -----------------------------------------------------------------------------
   1.376 +// MethodHandleWalker::walk_incoming_state
   1.377 +//
   1.378  void MethodHandleWalker::walk_incoming_state(TRAPS) {
   1.379    Handle mtype(THREAD, chain().method_type_oop());
   1.380    int nptypes = java_dyn_MethodType::ptype_count(mtype());
   1.381    _outgoing_argc = nptypes;
   1.382    int argp = nptypes - 1;
   1.383    if (argp >= 0) {
   1.384 -    _outgoing.at_grow(argp, make_state(T_VOID, NULL)); // presize
   1.385 +    _outgoing.at_grow(argp, make_state(T_VOID, ArgToken(tt_void))); // presize
   1.386    }
   1.387    for (int i = 0; i < nptypes; i++) {
   1.388      klassOop  arg_type_klass = NULL;
   1.389      BasicType arg_type = java_lang_Class::as_BasicType(
   1.390                  java_dyn_MethodType::ptype(mtype(), i), &arg_type_klass);
   1.391 -    ArgToken  arg = make_parameter(arg_type, arg_type_klass, i, CHECK);
   1.392 -    debug_only(arg_type_klass = (klassOop)NULL);
   1.393 +    int index = new_local_index(arg_type);
   1.394 +    ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK);
   1.395 +    debug_only(arg_type_klass = (klassOop) NULL);
   1.396      _outgoing.at_put(argp, make_state(arg_type, arg));
   1.397      if (type2size[arg_type] == 2) {
   1.398        // add the extra slot, so we can model the JVM stack
   1.399 -      _outgoing.insert_before(argp+1, make_state(T_VOID, NULL));
   1.400 +      _outgoing.insert_before(argp+1, make_state(T_VOID, ArgToken(tt_void)));
   1.401      }
   1.402      --argp;
   1.403    }
   1.404 @@ -484,17 +560,21 @@
   1.405    // ignore ret; client can catch it if needed
   1.406  }
   1.407  
   1.408 -// this is messy because some kinds of arguments are paired with
   1.409 -// companion slots containing an empty value
   1.410 +
   1.411 +// -----------------------------------------------------------------------------
   1.412 +// MethodHandleWalker::change_argument
   1.413 +//
   1.414 +// This is messy because some kinds of arguments are paired with
   1.415 +// companion slots containing an empty value.
   1.416  void MethodHandleWalker::change_argument(BasicType old_type, int slot, BasicType new_type,
   1.417 -                                         MethodHandleWalker::ArgToken new_arg) {
   1.418 +                                         const ArgToken& new_arg) {
   1.419    int old_size = type2size[old_type];
   1.420    int new_size = type2size[new_type];
   1.421    if (old_size == new_size) {
   1.422      // simple case first
   1.423      _outgoing.at_put(slot, make_state(new_type, new_arg));
   1.424    } else if (old_size > new_size) {
   1.425 -    for (int i = old_size-1; i >= new_size; i++) {
   1.426 +    for (int i = old_size - 1; i >= new_size; i--) {
   1.427        assert((i != 0) == (_outgoing.at(slot + i)._type == T_VOID), "");
   1.428        _outgoing.remove_at(slot + i);
   1.429      }
   1.430 @@ -504,7 +584,7 @@
   1.431        _outgoing_argc -= 1;      // deleted a real argument
   1.432    } else {
   1.433      for (int i = old_size; i < new_size; i++) {
   1.434 -      _outgoing.insert_before(slot+i, make_state(T_VOID, NULL));
   1.435 +      _outgoing.insert_before(slot + i, make_state(T_VOID, ArgToken(tt_void)));
   1.436      }
   1.437      _outgoing.at_put(slot, make_state(new_type, new_arg));
   1.438      if (old_size == 0)
   1.439 @@ -526,72 +606,485 @@
   1.440  #endif
   1.441  
   1.442  
   1.443 -void MethodHandleCompiler::compile(TRAPS) {
   1.444 +// -----------------------------------------------------------------------------
   1.445 +// MethodHandleCompiler
   1.446 +
   1.447 +MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, bool is_invokedynamic, TRAPS)
   1.448 +  : MethodHandleWalker(root, is_invokedynamic, THREAD),
   1.449 +    _callee(callee),
   1.450 +    _thread(THREAD),
   1.451 +    _bytecode(THREAD, 50),
   1.452 +    _constants(THREAD, 10),
   1.453 +    _cur_stack(0),
   1.454 +    _max_stack(0),
   1.455 +    _rtype(T_ILLEGAL)
   1.456 +{
   1.457 +
   1.458 +  // Element zero is always the null constant.
   1.459 +  (void) _constants.append(NULL);
   1.460 +
   1.461 +  // Set name and signature index.
   1.462 +  _name_index      = cpool_symbol_put(_callee->name());
   1.463 +  _signature_index = cpool_symbol_put(_callee->signature());
   1.464 +
   1.465 +  // Get return type klass.
   1.466 +  Handle first_mtype(THREAD, chain().method_type_oop());
   1.467 +  // _rklass is NULL for primitives.
   1.468 +  _rtype = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(first_mtype()), &_rklass);
   1.469 +
   1.470 +  int params = _callee->size_of_parameters();  // Incoming arguments plus receiver.
   1.471 +  _num_params = for_invokedynamic() ? params - 1 : params;  // XXX Check if callee is static?
   1.472 +}
   1.473 +
   1.474 +
   1.475 +// -----------------------------------------------------------------------------
   1.476 +// MethodHandleCompiler::compile
   1.477 +//
   1.478 +// Compile this MethodHandle into a bytecode adapter and return a
   1.479 +// methodOop.
   1.480 +methodHandle MethodHandleCompiler::compile(TRAPS) {
   1.481    assert(_thread == THREAD, "must be same thread");
   1.482 +  methodHandle nullHandle;
   1.483 +  (void) walk(CHECK_(nullHandle));
   1.484 +  return get_method_oop(CHECK_(nullHandle));
   1.485 +}
   1.486  
   1.487 -  _constant_oops.append(Handle());  // element zero is always the null constant
   1.488 -  _constant_prims.append(NULL);
   1.489 -  {
   1.490 -    symbolOop sig
   1.491 -      = java_dyn_MethodType::as_signature(chain().method_type_oop(), true, CHECK);
   1.492 -    _signature_index = find_oop_constant(sig);
   1.493 -    assert(signature() == sig, "");
   1.494 +
   1.495 +void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
   1.496 +  Bytecodes::check(op);  // Are we legal?
   1.497 +
   1.498 +  switch (op) {
   1.499 +  // b
   1.500 +  case Bytecodes::_aconst_null:
   1.501 +  case Bytecodes::_iconst_m1:
   1.502 +  case Bytecodes::_iconst_0:
   1.503 +  case Bytecodes::_iconst_1:
   1.504 +  case Bytecodes::_iconst_2:
   1.505 +  case Bytecodes::_iconst_3:
   1.506 +  case Bytecodes::_iconst_4:
   1.507 +  case Bytecodes::_iconst_5:
   1.508 +  case Bytecodes::_lconst_0:
   1.509 +  case Bytecodes::_lconst_1:
   1.510 +  case Bytecodes::_fconst_0:
   1.511 +  case Bytecodes::_fconst_1:
   1.512 +  case Bytecodes::_fconst_2:
   1.513 +  case Bytecodes::_dconst_0:
   1.514 +  case Bytecodes::_dconst_1:
   1.515 +  case Bytecodes::_iload_0:
   1.516 +  case Bytecodes::_iload_1:
   1.517 +  case Bytecodes::_iload_2:
   1.518 +  case Bytecodes::_iload_3:
   1.519 +  case Bytecodes::_lload_0:
   1.520 +  case Bytecodes::_lload_1:
   1.521 +  case Bytecodes::_lload_2:
   1.522 +  case Bytecodes::_lload_3:
   1.523 +  case Bytecodes::_fload_0:
   1.524 +  case Bytecodes::_fload_1:
   1.525 +  case Bytecodes::_fload_2:
   1.526 +  case Bytecodes::_fload_3:
   1.527 +  case Bytecodes::_dload_0:
   1.528 +  case Bytecodes::_dload_1:
   1.529 +  case Bytecodes::_dload_2:
   1.530 +  case Bytecodes::_dload_3:
   1.531 +  case Bytecodes::_aload_0:
   1.532 +  case Bytecodes::_aload_1:
   1.533 +  case Bytecodes::_aload_2:
   1.534 +  case Bytecodes::_aload_3:
   1.535 +  case Bytecodes::_istore_0:
   1.536 +  case Bytecodes::_istore_1:
   1.537 +  case Bytecodes::_istore_2:
   1.538 +  case Bytecodes::_istore_3:
   1.539 +  case Bytecodes::_lstore_0:
   1.540 +  case Bytecodes::_lstore_1:
   1.541 +  case Bytecodes::_lstore_2:
   1.542 +  case Bytecodes::_lstore_3:
   1.543 +  case Bytecodes::_fstore_0:
   1.544 +  case Bytecodes::_fstore_1:
   1.545 +  case Bytecodes::_fstore_2:
   1.546 +  case Bytecodes::_fstore_3:
   1.547 +  case Bytecodes::_dstore_0:
   1.548 +  case Bytecodes::_dstore_1:
   1.549 +  case Bytecodes::_dstore_2:
   1.550 +  case Bytecodes::_dstore_3:
   1.551 +  case Bytecodes::_astore_0:
   1.552 +  case Bytecodes::_astore_1:
   1.553 +  case Bytecodes::_astore_2:
   1.554 +  case Bytecodes::_astore_3:
   1.555 +  case Bytecodes::_i2l:
   1.556 +  case Bytecodes::_i2f:
   1.557 +  case Bytecodes::_i2d:
   1.558 +  case Bytecodes::_i2b:
   1.559 +  case Bytecodes::_i2c:
   1.560 +  case Bytecodes::_i2s:
   1.561 +  case Bytecodes::_l2i:
   1.562 +  case Bytecodes::_l2f:
   1.563 +  case Bytecodes::_l2d:
   1.564 +  case Bytecodes::_f2i:
   1.565 +  case Bytecodes::_f2l:
   1.566 +  case Bytecodes::_f2d:
   1.567 +  case Bytecodes::_d2i:
   1.568 +  case Bytecodes::_d2l:
   1.569 +  case Bytecodes::_d2f:
   1.570 +  case Bytecodes::_ireturn:
   1.571 +  case Bytecodes::_lreturn:
   1.572 +  case Bytecodes::_freturn:
   1.573 +  case Bytecodes::_dreturn:
   1.574 +  case Bytecodes::_areturn:
   1.575 +  case Bytecodes::_return:
   1.576 +    assert(strcmp(Bytecodes::format(op), "b") == 0, "wrong bytecode format");
   1.577 +    _bytecode.push(op);
   1.578 +    break;
   1.579 +
   1.580 +  // bi
   1.581 +  case Bytecodes::_ldc:
   1.582 +  case Bytecodes::_iload:
   1.583 +  case Bytecodes::_lload:
   1.584 +  case Bytecodes::_fload:
   1.585 +  case Bytecodes::_dload:
   1.586 +  case Bytecodes::_aload:
   1.587 +  case Bytecodes::_istore:
   1.588 +  case Bytecodes::_lstore:
   1.589 +  case Bytecodes::_fstore:
   1.590 +  case Bytecodes::_dstore:
   1.591 +  case Bytecodes::_astore:
   1.592 +    assert(strcmp(Bytecodes::format(op), "bi") == 0, "wrong bytecode format");
   1.593 +    assert((char) index == index, "index does not fit in 8-bit");
   1.594 +    _bytecode.push(op);
   1.595 +    _bytecode.push(index);
   1.596 +    break;
   1.597 +
   1.598 +  // bii
   1.599 +  case Bytecodes::_ldc2_w:
   1.600 +  case Bytecodes::_checkcast:
   1.601 +    assert(strcmp(Bytecodes::format(op), "bii") == 0, "wrong bytecode format");
   1.602 +    assert((short) index == index, "index does not fit in 16-bit");
   1.603 +    _bytecode.push(op);
   1.604 +    _bytecode.push(index >> 8);
   1.605 +    _bytecode.push(index);
   1.606 +    break;
   1.607 +
   1.608 +  // bjj
   1.609 +  case Bytecodes::_invokestatic:
   1.610 +  case Bytecodes::_invokespecial:
   1.611 +  case Bytecodes::_invokevirtual:
   1.612 +    assert(strcmp(Bytecodes::format(op), "bjj") == 0, "wrong bytecode format");
   1.613 +    assert((short) index == index, "index does not fit in 16-bit");
   1.614 +    _bytecode.push(op);
   1.615 +    _bytecode.push(index >> 8);
   1.616 +    _bytecode.push(index);
   1.617 +    break;
   1.618 +
   1.619 +  default:
   1.620 +    ShouldNotReachHere();
   1.621    }
   1.622 +}
   1.623  
   1.624 -  walk(CHECK);
   1.625 +
   1.626 +void MethodHandleCompiler::emit_load(BasicType bt, int index) {
   1.627 +  if (index <= 3) {
   1.628 +    switch (bt) {
   1.629 +    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
   1.630 +    case T_INT:    emit_bc(Bytecodes::cast(Bytecodes::_iload_0 + index)); break;
   1.631 +    case T_LONG:   emit_bc(Bytecodes::cast(Bytecodes::_lload_0 + index)); break;
   1.632 +    case T_FLOAT:  emit_bc(Bytecodes::cast(Bytecodes::_fload_0 + index)); break;
   1.633 +    case T_DOUBLE: emit_bc(Bytecodes::cast(Bytecodes::_dload_0 + index)); break;
   1.634 +    case T_OBJECT: emit_bc(Bytecodes::cast(Bytecodes::_aload_0 + index)); break;
   1.635 +    default:
   1.636 +      ShouldNotReachHere();
   1.637 +    }
   1.638 +  }
   1.639 +  else {
   1.640 +    switch (bt) {
   1.641 +    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
   1.642 +    case T_INT:    emit_bc(Bytecodes::_iload, index); break;
   1.643 +    case T_LONG:   emit_bc(Bytecodes::_lload, index); break;
   1.644 +    case T_FLOAT:  emit_bc(Bytecodes::_fload, index); break;
   1.645 +    case T_DOUBLE: emit_bc(Bytecodes::_dload, index); break;
   1.646 +    case T_OBJECT: emit_bc(Bytecodes::_aload, index); break;
   1.647 +    default:
   1.648 +      ShouldNotReachHere();
   1.649 +    }
   1.650 +  }
   1.651 +  stack_push(bt);
   1.652  }
   1.653  
   1.654 +void MethodHandleCompiler::emit_store(BasicType bt, int index) {
   1.655 +  if (index <= 3) {
   1.656 +    switch (bt) {
   1.657 +    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
   1.658 +    case T_INT:    emit_bc(Bytecodes::cast(Bytecodes::_istore_0 + index)); break;
   1.659 +    case T_LONG:   emit_bc(Bytecodes::cast(Bytecodes::_lstore_0 + index)); break;
   1.660 +    case T_FLOAT:  emit_bc(Bytecodes::cast(Bytecodes::_fstore_0 + index)); break;
   1.661 +    case T_DOUBLE: emit_bc(Bytecodes::cast(Bytecodes::_dstore_0 + index)); break;
   1.662 +    case T_OBJECT: emit_bc(Bytecodes::cast(Bytecodes::_astore_0 + index)); break;
   1.663 +    default:
   1.664 +      ShouldNotReachHere();
   1.665 +    }
   1.666 +  }
   1.667 +  else {
   1.668 +    switch (bt) {
   1.669 +    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
   1.670 +    case T_INT:    emit_bc(Bytecodes::_istore, index); break;
   1.671 +    case T_LONG:   emit_bc(Bytecodes::_lstore, index); break;
   1.672 +    case T_FLOAT:  emit_bc(Bytecodes::_fstore, index); break;
   1.673 +    case T_DOUBLE: emit_bc(Bytecodes::_dstore, index); break;
   1.674 +    case T_OBJECT: emit_bc(Bytecodes::_astore, index); break;
   1.675 +    default:
   1.676 +      ShouldNotReachHere();
   1.677 +    }
   1.678 +  }
   1.679 +  stack_pop(bt);
   1.680 +}
   1.681 +
   1.682 +
   1.683 +void MethodHandleCompiler::emit_load_constant(ArgToken arg) {
   1.684 +  BasicType bt = arg.basic_type();
   1.685 +  switch (bt) {
   1.686 +  case T_INT: {
   1.687 +    jint value = arg.get_jint();
   1.688 +    if (-1 <= value && value <= 5)
   1.689 +      emit_bc(Bytecodes::cast(Bytecodes::_iconst_0 + value));
   1.690 +    else
   1.691 +      emit_bc(Bytecodes::_ldc, cpool_int_put(value));
   1.692 +    break;
   1.693 +  }
   1.694 +  case T_LONG: {
   1.695 +    jlong value = arg.get_jlong();
   1.696 +    if (0 <= value && value <= 1)
   1.697 +      emit_bc(Bytecodes::cast(Bytecodes::_lconst_0 + (int) value));
   1.698 +    else
   1.699 +      emit_bc(Bytecodes::_ldc2_w, cpool_long_put(value));
   1.700 +    break;
   1.701 +  }
   1.702 +  case T_FLOAT: {
   1.703 +    jfloat value  = arg.get_jfloat();
   1.704 +    if (value == 0.0 || value == 1.0 || value == 2.0)
   1.705 +      emit_bc(Bytecodes::cast(Bytecodes::_fconst_0 + (int) value));
   1.706 +    else
   1.707 +      emit_bc(Bytecodes::_ldc, cpool_float_put(value));
   1.708 +    break;
   1.709 +  }
   1.710 +  case T_DOUBLE: {
   1.711 +    jdouble value = arg.get_jdouble();
   1.712 +    if (value == 0.0 || value == 1.0)
   1.713 +      emit_bc(Bytecodes::cast(Bytecodes::_dconst_0 + (int) value));
   1.714 +    else
   1.715 +      emit_bc(Bytecodes::_ldc2_w, cpool_double_put(value));
   1.716 +    break;
   1.717 +  }
   1.718 +  case T_OBJECT: {
   1.719 +    Handle value = arg.object();
   1.720 +    if (value.is_null())
   1.721 +      emit_bc(Bytecodes::_aconst_null);
   1.722 +    else
   1.723 +      emit_bc(Bytecodes::_ldc, cpool_object_put(value));
   1.724 +    break;
   1.725 +  }
   1.726 +  default:
   1.727 +    ShouldNotReachHere();
   1.728 +  }
   1.729 +  stack_push(bt);
   1.730 +}
   1.731 +
   1.732 +
   1.733  MethodHandleWalker::ArgToken
   1.734  MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Code op,
   1.735 -                                      MethodHandleWalker::ArgToken src, TRAPS) {
   1.736 -  Unimplemented();
   1.737 -  return NULL;
   1.738 +                                      const ArgToken& src, TRAPS) {
   1.739 +
   1.740 +  BasicType srctype = src.basic_type();
   1.741 +  int index = src.index();
   1.742 +
   1.743 +  switch (op) {
   1.744 +  case Bytecodes::_i2l:
   1.745 +  case Bytecodes::_i2f:
   1.746 +  case Bytecodes::_i2d:
   1.747 +  case Bytecodes::_i2b:
   1.748 +  case Bytecodes::_i2c:
   1.749 +  case Bytecodes::_i2s:
   1.750 +
   1.751 +  case Bytecodes::_l2i:
   1.752 +  case Bytecodes::_l2f:
   1.753 +  case Bytecodes::_l2d:
   1.754 +
   1.755 +  case Bytecodes::_f2i:
   1.756 +  case Bytecodes::_f2l:
   1.757 +  case Bytecodes::_f2d:
   1.758 +
   1.759 +  case Bytecodes::_d2i:
   1.760 +  case Bytecodes::_d2l:
   1.761 +  case Bytecodes::_d2f:
   1.762 +    emit_load(srctype, index);
   1.763 +    stack_pop(srctype);  // pop the src type
   1.764 +    emit_bc(op);
   1.765 +    stack_push(type);    // push the dest value
   1.766 +    if (srctype != type)
   1.767 +      index = new_local_index(type);
   1.768 +    emit_store(type, index);
   1.769 +    break;
   1.770 +
   1.771 +  case Bytecodes::_checkcast:
   1.772 +    emit_load(srctype, index);
   1.773 +    emit_bc(op, cpool_klass_put(tk));
   1.774 +    emit_store(srctype, index);
   1.775 +    break;
   1.776 +
   1.777 +  default:
   1.778 +    ShouldNotReachHere();
   1.779 +  }
   1.780 +
   1.781 +  return make_parameter(type, tk, index, THREAD);
   1.782  }
   1.783  
   1.784 +
   1.785 +// -----------------------------------------------------------------------------
   1.786 +// MethodHandleCompiler
   1.787 +//
   1.788 +
   1.789 +static jvalue zero_jvalue;
   1.790 +
   1.791 +// Emit bytecodes for the given invoke instruction.
   1.792  MethodHandleWalker::ArgToken
   1.793  MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
   1.794                                    Bytecodes::Code op, bool tailcall,
   1.795                                    int argc, MethodHandleWalker::ArgToken* argv,
   1.796                                    TRAPS) {
   1.797 -  // If tailcall, we have walked all the way to a direct method handle.
   1.798 -  // Otherwise, make a recursive call to some helper routine.
   1.799 -#ifdef ASSERT
   1.800 +  if (m == NULL) {
   1.801 +    // Get the intrinsic methodOop.
   1.802 +    m = vmIntrinsics::method_for(iid);
   1.803 +  }
   1.804 +
   1.805 +  klassOop  klass     = m->method_holder();
   1.806 +  symbolOop name      = m->name();
   1.807 +  symbolOop signature = m->signature();
   1.808 +
   1.809 +  // This generated adapter method should be in the same class as the
   1.810 +  // DMH target method (for accessability reasons).
   1.811 +  if (tailcall) {
   1.812 +    _target_klass = klass;
   1.813 +  }
   1.814 +
   1.815 +  // instanceKlass* ik = instanceKlass::cast(klass);
   1.816 +  // tty->print_cr("MethodHandleCompiler::make_invoke: %s %s.%s%s", Bytecodes::name(op), ik->external_name(), name->as_C_string(), signature->as_C_string());
   1.817 +
   1.818 +  // Inline the method.
   1.819 +  InvocationCounter* ic = m->invocation_counter();
   1.820 +  ic->set_carry();
   1.821 +
   1.822 +  for (int i = 0; i < argc; i++) {
   1.823 +    ArgToken arg = argv[i];
   1.824 +    TokenType tt = arg.token_type();
   1.825 +    BasicType bt = arg.basic_type();
   1.826 +
   1.827 +    switch (tt) {
   1.828 +    case tt_parameter:
   1.829 +    case tt_temporary:
   1.830 +      emit_load(bt, arg.index());
   1.831 +      break;
   1.832 +    case tt_constant:
   1.833 +      emit_load_constant(arg);
   1.834 +      break;
   1.835 +    case tt_illegal:
   1.836 +      // Sentinel.
   1.837 +      assert(i == (argc - 1), "sentinel must be last entry");
   1.838 +      break;
   1.839 +    case tt_void:
   1.840 +    default:
   1.841 +      ShouldNotReachHere();
   1.842 +    }
   1.843 +  }
   1.844 +
   1.845 +  // Populate constant pool.
   1.846 +  int name_index          = cpool_symbol_put(name);
   1.847 +  int signature_index     = cpool_symbol_put(signature);
   1.848 +  int name_and_type_index = cpool_name_and_type_put(name_index, signature_index);
   1.849 +  int klass_index         = cpool_klass_put(klass);
   1.850 +  int methodref_index     = cpool_methodref_put(klass_index, name_and_type_index);
   1.851 +
   1.852 +  // Generate invoke.
   1.853    switch (op) {
   1.854 +  case Bytecodes::_invokestatic:
   1.855 +  case Bytecodes::_invokespecial:
   1.856    case Bytecodes::_invokevirtual:
   1.857 -  case Bytecodes::_invokespecial:
   1.858 -  case Bytecodes::_invokestatic:
   1.859 +    emit_bc(op, methodref_index);
   1.860 +    break;
   1.861    case Bytecodes::_invokeinterface:
   1.862 +    Unimplemented();
   1.863      break;
   1.864    default:
   1.865      ShouldNotReachHere();
   1.866    }
   1.867 -#endif //ASSERT
   1.868 -  _bytes.put((char) op);
   1.869  
   1.870 -  Unimplemented();
   1.871 -  return NULL;
   1.872 +  // If tailcall, we have walked all the way to a direct method handle.
   1.873 +  // Otherwise, make a recursive call to some helper routine.
   1.874 +  BasicType rbt = m->result_type();
   1.875 +  ArgToken ret;
   1.876 +  if (tailcall) {
   1.877 +    if (rbt != _rtype) {
   1.878 +      if (rbt == T_VOID) {
   1.879 +        // push a zero of the right sort
   1.880 +        ArgToken zero;
   1.881 +        if (_rtype == T_OBJECT) {
   1.882 +          zero = make_oop_constant(NULL, CHECK_(zero));
   1.883 +        } else {
   1.884 +          zero = make_prim_constant(_rtype, &zero_jvalue, CHECK_(zero));
   1.885 +        }
   1.886 +        emit_load_constant(zero);
   1.887 +      } else if (_rtype == T_VOID) {
   1.888 +        // We'll emit a _return with something on the stack.
   1.889 +        // It's OK to ignore what's on the stack.
   1.890 +      } else {
   1.891 +        tty->print_cr("*** rbt=%d != rtype=%d", rbt, _rtype);
   1.892 +        assert(false, "IMPLEMENT ME");
   1.893 +      }
   1.894 +    }
   1.895 +    switch (_rtype) {
   1.896 +    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
   1.897 +    case T_INT:    emit_bc(Bytecodes::_ireturn); break;
   1.898 +    case T_LONG:   emit_bc(Bytecodes::_lreturn); break;
   1.899 +    case T_FLOAT:  emit_bc(Bytecodes::_freturn); break;
   1.900 +    case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break;
   1.901 +    case T_VOID:   emit_bc(Bytecodes::_return);  break;
   1.902 +    case T_OBJECT:
   1.903 +      if (_rklass.not_null() && _rklass() != SystemDictionary::object_klass())
   1.904 +        emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass()));
   1.905 +      emit_bc(Bytecodes::_areturn);
   1.906 +      break;
   1.907 +    default: ShouldNotReachHere();
   1.908 +    }
   1.909 +    ret = ArgToken();  // Dummy return value.
   1.910 +  }
   1.911 +  else {
   1.912 +    stack_push(rbt);  // The return value is already pushed onto the stack.
   1.913 +    int index = new_local_index(rbt);
   1.914 +    switch (rbt) {
   1.915 +    case T_BOOLEAN: case T_BYTE: case T_CHAR:  case T_SHORT:
   1.916 +    case T_INT:     case T_LONG: case T_FLOAT: case T_DOUBLE:
   1.917 +    case T_OBJECT:
   1.918 +      emit_store(rbt, index);
   1.919 +      ret = ArgToken(tt_temporary, rbt, index);
   1.920 +      break;
   1.921 +    case T_VOID:
   1.922 +      ret = ArgToken(tt_void);
   1.923 +      break;
   1.924 +    default:
   1.925 +      ShouldNotReachHere();
   1.926 +    }
   1.927 +  }
   1.928 +
   1.929 +  return ret;
   1.930  }
   1.931  
   1.932  MethodHandleWalker::ArgToken
   1.933  MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op,
   1.934 -                                 MethodHandleWalker::ArgToken base,
   1.935 -                                 MethodHandleWalker::ArgToken offset,
   1.936 +                                 const MethodHandleWalker::ArgToken& base,
   1.937 +                                 const MethodHandleWalker::ArgToken& offset,
   1.938                                   TRAPS) {
   1.939    Unimplemented();
   1.940 -  return NULL;
   1.941 +  return ArgToken();
   1.942  }
   1.943  
   1.944 -int MethodHandleCompiler::find_oop_constant(oop con) {
   1.945 -  if (con == NULL)  return 0;
   1.946 -  for (int i = 1, imax = _constant_oops.length(); i < imax; i++) {
   1.947 -    if (_constant_oops.at(i) == con)
   1.948 -      return i;
   1.949 -  }
   1.950 -  _constant_prims.append(NULL);
   1.951 -  return _constant_oops.append(con);
   1.952 -}
   1.953  
   1.954 -int MethodHandleCompiler::find_prim_constant(BasicType bt, jvalue* con) {
   1.955 +int MethodHandleCompiler::cpool_primitive_put(BasicType bt, jvalue* con) {
   1.956    jvalue con_copy;
   1.957    assert(bt < T_OBJECT, "");
   1.958    if (type2aelembytes(bt) < jintSize) {
   1.959 @@ -607,28 +1100,125 @@
   1.960      }
   1.961      bt = T_INT;
   1.962    }
   1.963 -  for (int i = 1, imax = _constant_prims.length(); i < imax; i++) {
   1.964 -    PrimCon* pcon = _constant_prims.at(i);
   1.965 -    if (pcon != NULL && pcon->_type == bt) {
   1.966 -      bool match = false;
   1.967 -      switch (type2size[bt]) {
   1.968 -      case 1:  if (pcon->_value.i == con->i)  match = true;  break;
   1.969 -      case 2:  if (pcon->_value.j == con->j)  match = true;  break;
   1.970 -      }
   1.971 -      if (match)
   1.972 -        return i;
   1.973 +
   1.974 +//   for (int i = 1, imax = _constants.length(); i < imax; i++) {
   1.975 +//     ConstantValue* con = _constants.at(i);
   1.976 +//     if (con != NULL && con->is_primitive() && con->_type == bt) {
   1.977 +//       bool match = false;
   1.978 +//       switch (type2size[bt]) {
   1.979 +//       case 1:  if (pcon->_value.i == con->i)  match = true;  break;
   1.980 +//       case 2:  if (pcon->_value.j == con->j)  match = true;  break;
   1.981 +//       }
   1.982 +//       if (match)
   1.983 +//         return i;
   1.984 +//     }
   1.985 +//   }
   1.986 +  ConstantValue* cv = new ConstantValue(bt, *con);
   1.987 +  int index = _constants.append(cv);
   1.988 +
   1.989 +  // long and double entries take 2 slots, we add another empty entry.
   1.990 +  if (type2size[bt] == 2)
   1.991 +    (void) _constants.append(NULL);
   1.992 +
   1.993 +  return index;
   1.994 +}
   1.995 +
   1.996 +
   1.997 +constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const {
   1.998 +  constantPoolHandle nullHandle;
   1.999 +  bool is_conc_safe = true;
  1.1000 +  constantPoolOop cpool_oop = oopFactory::new_constantPool(_constants.length(), is_conc_safe, CHECK_(nullHandle));
  1.1001 +  constantPoolHandle cpool(THREAD, cpool_oop);
  1.1002 +
  1.1003 +  // Fill the real constant pool skipping the zero element.
  1.1004 +  for (int i = 1; i < _constants.length(); i++) {
  1.1005 +    ConstantValue* cv = _constants.at(i);
  1.1006 +    switch (cv->tag()) {
  1.1007 +    case JVM_CONSTANT_Utf8:        cpool->symbol_at_put(       i, cv->symbol_oop()                     ); break;
  1.1008 +    case JVM_CONSTANT_Integer:     cpool->int_at_put(          i, cv->get_jint()                       ); break;
  1.1009 +    case JVM_CONSTANT_Float:       cpool->float_at_put(        i, cv->get_jfloat()                     ); break;
  1.1010 +    case JVM_CONSTANT_Long:        cpool->long_at_put(         i, cv->get_jlong()                      ); break;
  1.1011 +    case JVM_CONSTANT_Double:      cpool->double_at_put(       i, cv->get_jdouble()                    ); break;
  1.1012 +    case JVM_CONSTANT_Class:       cpool->klass_at_put(        i, cv->klass_oop()                      ); break;
  1.1013 +    case JVM_CONSTANT_Methodref:   cpool->method_at_put(       i, cv->first_index(), cv->second_index()); break;
  1.1014 +    case JVM_CONSTANT_NameAndType: cpool->name_and_type_at_put(i, cv->first_index(), cv->second_index()); break;
  1.1015 +    case JVM_CONSTANT_Object:      cpool->object_at_put(       i, cv->object_oop()                     ); break;
  1.1016 +    default: ShouldNotReachHere();
  1.1017 +    }
  1.1018 +
  1.1019 +    switch (cv->tag()) {
  1.1020 +    case JVM_CONSTANT_Long:
  1.1021 +    case JVM_CONSTANT_Double:
  1.1022 +      i++;  // Skip empty entry.
  1.1023 +      assert(_constants.at(i) == NULL, "empty entry");
  1.1024 +      break;
  1.1025      }
  1.1026    }
  1.1027 -  PrimCon* pcon = new PrimCon();
  1.1028 -  pcon->_type = bt;
  1.1029 -  pcon->_value = (*con);
  1.1030 -  _constant_oops.append(Handle());
  1.1031 -  return _constant_prims.append(pcon);
  1.1032 +
  1.1033 +  // Set the constant pool holder to the target method's class.
  1.1034 +  cpool->set_pool_holder(_target_klass());
  1.1035 +
  1.1036 +  return cpool;
  1.1037 +}
  1.1038 +
  1.1039 +
  1.1040 +methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
  1.1041 +  methodHandle nullHandle;
  1.1042 +  // Create a method that holds the generated bytecode.  invokedynamic
  1.1043 +  // has no receiver, normal MH calls do.
  1.1044 +  int flags_bits;
  1.1045 +  if (for_invokedynamic())
  1.1046 +    flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_STATIC);
  1.1047 +  else
  1.1048 +    flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL);
  1.1049 +
  1.1050 +  bool is_conc_safe = true;
  1.1051 +  methodOop m_oop = oopFactory::new_method(bytecode_length(),
  1.1052 +                                           accessFlags_from(flags_bits),
  1.1053 +                                           0, 0, 0, is_conc_safe, CHECK_(nullHandle));
  1.1054 +  methodHandle m(THREAD, m_oop);
  1.1055 +  m_oop = NULL;  // oop not GC safe
  1.1056 +
  1.1057 +  constantPoolHandle cpool = get_constant_pool(CHECK_(nullHandle));
  1.1058 +  m->set_constants(cpool());
  1.1059 +
  1.1060 +  m->set_name_index(_name_index);
  1.1061 +  m->set_signature_index(_signature_index);
  1.1062 +
  1.1063 +  m->set_code((address) bytecode());
  1.1064 +
  1.1065 +  m->set_max_stack(_max_stack);
  1.1066 +  m->set_max_locals(max_locals());
  1.1067 +  m->set_size_of_parameters(_num_params);
  1.1068 +
  1.1069 +  typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
  1.1070 +  m->set_exception_table(exception_handlers());
  1.1071 +
  1.1072 +  // Set the carry bit of the invocation counter to force inlining of
  1.1073 +  // the adapter.
  1.1074 +  InvocationCounter* ic = m->invocation_counter();
  1.1075 +  ic->set_carry();
  1.1076 +
  1.1077 +  // Rewrite the method and set up the constant pool cache.
  1.1078 +  objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(nullHandle));
  1.1079 +  objArrayHandle methods(THREAD, m_array);
  1.1080 +  methods->obj_at_put(0, m());
  1.1081 +  Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(nullHandle));  // Use fake class.
  1.1082 +
  1.1083 +#ifndef PRODUCT
  1.1084 +  if (TraceMethodHandles) {
  1.1085 +    m->print();
  1.1086 +    m->print_codes();
  1.1087 +  }
  1.1088 +#endif //PRODUCT
  1.1089 +
  1.1090 +  return m;
  1.1091  }
  1.1092  
  1.1093  
  1.1094  #ifndef PRODUCT
  1.1095  
  1.1096 +#if 0
  1.1097  // MH printer for debugging.
  1.1098  
  1.1099  class MethodHandlePrinter : public MethodHandleWalker {
  1.1100 @@ -791,11 +1381,12 @@
  1.1101      out->print("\n");
  1.1102    }
  1.1103  };
  1.1104 +#endif // 0
  1.1105  
  1.1106  extern "C"
  1.1107  void print_method_handle(oop mh) {
  1.1108    if (java_dyn_MethodHandle::is_instance(mh)) {
  1.1109 -    MethodHandlePrinter::print(mh);
  1.1110 +    //MethodHandlePrinter::print(mh);
  1.1111    } else {
  1.1112      tty->print("*** not a method handle: ");
  1.1113      mh->print();

mercurial