src/share/vm/prims/methodHandleWalk.cpp

changeset 2920
a80577f854f9
parent 2917
33ae33516634
child 2937
5ac411b3b8fc
child 2945
d3b9f2be46ab
     1.1 --- a/src/share/vm/prims/methodHandleWalk.cpp	Tue May 17 16:50:27 2011 +0200
     1.2 +++ b/src/share/vm/prims/methodHandleWalk.cpp	Tue May 17 19:11:51 2011 -0700
     1.3 @@ -265,7 +265,7 @@
     1.4          assert(dest == arg_state->_type, "");
     1.5          ArgToken arg = arg_state->_arg;
     1.6          ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty));
     1.7 -        assert(arg.token_type() >= tt_symbolic || arg.index() == new_arg.index(), "should be the same index");
     1.8 +        assert(!arg.has_index() || arg.index() == new_arg.index(), "should be the same index");
     1.9          debug_only(dest_klass = (klassOop)badOop);
    1.10          break;
    1.11        }
    1.12 @@ -443,8 +443,10 @@
    1.13              ret = make_conversion(T_OBJECT, rklass, Bytecodes::_checkcast, ret, CHECK_(empty));
    1.14            }
    1.15          }
    1.16 -        int ret_slot = arg_slot + (retain_original_args ? coll_slots : 0);
    1.17 -        change_argument(T_VOID, ret_slot, rtype, ret);
    1.18 +        if (rtype != T_VOID) {
    1.19 +          int ret_slot = arg_slot + (retain_original_args ? coll_slots : 0);
    1.20 +          change_argument(T_VOID, ret_slot, rtype, ret);
    1.21 +        }
    1.22          break;
    1.23        }
    1.24  
    1.25 @@ -690,9 +692,8 @@
    1.26  // -----------------------------------------------------------------------------
    1.27  // MethodHandleCompiler
    1.28  
    1.29 -MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, int invoke_count, bool is_invokedynamic, TRAPS)
    1.30 +MethodHandleCompiler::MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool is_invokedynamic, TRAPS)
    1.31    : MethodHandleWalker(root, is_invokedynamic, THREAD),
    1.32 -    _callee(callee),
    1.33      _invoke_count(invoke_count),
    1.34      _thread(THREAD),
    1.35      _bytecode(THREAD, 50),
    1.36 @@ -706,8 +707,8 @@
    1.37    (void) _constants.append(NULL);
    1.38  
    1.39    // Set name and signature index.
    1.40 -  _name_index      = cpool_symbol_put(_callee->name());
    1.41 -  _signature_index = cpool_symbol_put(_callee->signature());
    1.42 +  _name_index      = cpool_symbol_put(name);
    1.43 +  _signature_index = cpool_symbol_put(signature);
    1.44  
    1.45    // Get return type klass.
    1.46    Handle first_mtype(THREAD, chain().method_type_oop());
    1.47 @@ -715,7 +716,8 @@
    1.48    _rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(first_mtype()), &_rklass);
    1.49    if (_rtype == T_ARRAY)  _rtype = T_OBJECT;
    1.50  
    1.51 -  int params = _callee->size_of_parameters();  // Incoming arguments plus receiver.
    1.52 +  ArgumentSizeComputer args(signature);
    1.53 +  int params = args.size() + 1;  // Incoming arguments plus receiver.
    1.54    _num_params = for_invokedynamic() ? params - 1 : params;  // XXX Check if callee is static?
    1.55  }
    1.56  
    1.57 @@ -733,7 +735,7 @@
    1.58  }
    1.59  
    1.60  
    1.61 -void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
    1.62 +void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index, int args_size) {
    1.63    Bytecodes::check(op);  // Are we legal?
    1.64  
    1.65    switch (op) {
    1.66 @@ -809,6 +811,14 @@
    1.67    case Bytecodes::_d2i:
    1.68    case Bytecodes::_d2l:
    1.69    case Bytecodes::_d2f:
    1.70 +  case Bytecodes::_iaload:
    1.71 +  case Bytecodes::_laload:
    1.72 +  case Bytecodes::_faload:
    1.73 +  case Bytecodes::_daload:
    1.74 +  case Bytecodes::_aaload:
    1.75 +  case Bytecodes::_baload:
    1.76 +  case Bytecodes::_caload:
    1.77 +  case Bytecodes::_saload:
    1.78    case Bytecodes::_ireturn:
    1.79    case Bytecodes::_lreturn:
    1.80    case Bytecodes::_freturn:
    1.81 @@ -822,9 +832,14 @@
    1.82    // bi
    1.83    case Bytecodes::_ldc:
    1.84      assert(Bytecodes::format_bits(op, false) == (Bytecodes::_fmt_b|Bytecodes::_fmt_has_k), "wrong bytecode format");
    1.85 -    assert((char) index == index, "index does not fit in 8-bit");
    1.86 -    _bytecode.push(op);
    1.87 -    _bytecode.push(index);
    1.88 +    if (index == (index & 0xff)) {
    1.89 +      _bytecode.push(op);
    1.90 +      _bytecode.push(index);
    1.91 +    } else {
    1.92 +      _bytecode.push(Bytecodes::_ldc_w);
    1.93 +      _bytecode.push(index >> 8);
    1.94 +      _bytecode.push(index);
    1.95 +    }
    1.96      break;
    1.97  
    1.98    case Bytecodes::_iload:
    1.99 @@ -838,9 +853,16 @@
   1.100    case Bytecodes::_dstore:
   1.101    case Bytecodes::_astore:
   1.102      assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bi, "wrong bytecode format");
   1.103 -    assert((char) index == index, "index does not fit in 8-bit");
   1.104 -    _bytecode.push(op);
   1.105 -    _bytecode.push(index);
   1.106 +    if (index == (index & 0xff)) {
   1.107 +      _bytecode.push(op);
   1.108 +      _bytecode.push(index);
   1.109 +    } else {
   1.110 +      // doesn't fit in a u2
   1.111 +      _bytecode.push(Bytecodes::_wide);
   1.112 +      _bytecode.push(op);
   1.113 +      _bytecode.push(index >> 8);
   1.114 +      _bytecode.push(index);
   1.115 +    }
   1.116      break;
   1.117  
   1.118    // bkk
   1.119 @@ -848,7 +870,7 @@
   1.120    case Bytecodes::_ldc2_w:
   1.121    case Bytecodes::_checkcast:
   1.122      assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bkk, "wrong bytecode format");
   1.123 -    assert((short) index == index, "index does not fit in 16-bit");
   1.124 +    assert((unsigned short) index == index, "index does not fit in 16-bit");
   1.125      _bytecode.push(op);
   1.126      _bytecode.push(index >> 8);
   1.127      _bytecode.push(index);
   1.128 @@ -859,12 +881,23 @@
   1.129    case Bytecodes::_invokespecial:
   1.130    case Bytecodes::_invokevirtual:
   1.131      assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format");
   1.132 -    assert((short) index == index, "index does not fit in 16-bit");
   1.133 +    assert((unsigned short) index == index, "index does not fit in 16-bit");
   1.134      _bytecode.push(op);
   1.135      _bytecode.push(index >> 8);
   1.136      _bytecode.push(index);
   1.137      break;
   1.138  
   1.139 +  case Bytecodes::_invokeinterface:
   1.140 +    assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format");
   1.141 +    assert((unsigned short) index == index, "index does not fit in 16-bit");
   1.142 +    assert(args_size > 0, "valid args_size");
   1.143 +    _bytecode.push(op);
   1.144 +    _bytecode.push(index >> 8);
   1.145 +    _bytecode.push(index);
   1.146 +    _bytecode.push(args_size);
   1.147 +    _bytecode.push(0);
   1.148 +    break;
   1.149 +
   1.150    default:
   1.151      ShouldNotReachHere();
   1.152    }
   1.153 @@ -983,7 +1016,8 @@
   1.154                                        const ArgToken& src, TRAPS) {
   1.155  
   1.156    BasicType srctype = src.basic_type();
   1.157 -  int index = src.index();
   1.158 +  TokenType tt = src.token_type();
   1.159 +  int index = -1;
   1.160  
   1.161    switch (op) {
   1.162    case Bytecodes::_i2l:
   1.163 @@ -1004,18 +1038,31 @@
   1.164    case Bytecodes::_d2i:
   1.165    case Bytecodes::_d2l:
   1.166    case Bytecodes::_d2f:
   1.167 -    emit_load(srctype, index);
   1.168 +    if (tt == tt_constant) {
   1.169 +      emit_load_constant(src);
   1.170 +    } else {
   1.171 +      emit_load(srctype, src.index());
   1.172 +    }
   1.173      stack_pop(srctype);  // pop the src type
   1.174      emit_bc(op);
   1.175      stack_push(type);    // push the dest value
   1.176 -    if (srctype != type)
   1.177 +    if (tt != tt_constant)
   1.178 +      index = src.index();
   1.179 +    if (srctype != type || index == -1)
   1.180        index = new_local_index(type);
   1.181      emit_store(type, index);
   1.182      break;
   1.183  
   1.184    case Bytecodes::_checkcast:
   1.185 -    emit_load(srctype, index);
   1.186 +    if (tt == tt_constant) {
   1.187 +      emit_load_constant(src);
   1.188 +    } else {
   1.189 +      emit_load(srctype, src.index());
   1.190 +      index = src.index();
   1.191 +    }
   1.192      emit_bc(op, cpool_klass_put(tk));
   1.193 +    if (index == -1)
   1.194 +      index = new_local_index(type);
   1.195      emit_store(srctype, index);
   1.196      break;
   1.197  
   1.198 @@ -1058,6 +1105,11 @@
   1.199    Symbol*  name      = m->name();
   1.200    Symbol*  signature = m->signature();
   1.201  
   1.202 +  // Count the number of arguments, not the size
   1.203 +  ArgumentCount asc(signature);
   1.204 +  assert(argc == asc.size() + ((op == Bytecodes::_invokestatic || op == Bytecodes::_invokedynamic) ? 0 : 1),
   1.205 +         "argc mismatch");
   1.206 +
   1.207    if (tailcall) {
   1.208      // Actually, in order to make these methods more recognizable,
   1.209      // let's put them in holder class MethodHandle.  That way stack
   1.210 @@ -1106,9 +1158,13 @@
   1.211    case Bytecodes::_invokevirtual:
   1.212      emit_bc(op, methodref_index);
   1.213      break;
   1.214 -  case Bytecodes::_invokeinterface:
   1.215 -    Unimplemented();
   1.216 +
   1.217 +  case Bytecodes::_invokeinterface: {
   1.218 +    ArgumentSizeComputer asc(signature);
   1.219 +    emit_bc(op, methodref_index, asc.size() + 1);
   1.220      break;
   1.221 +  }
   1.222 +
   1.223    default:
   1.224      ShouldNotReachHere();
   1.225    }
   1.226 @@ -1117,6 +1173,7 @@
   1.227    // Otherwise, make a recursive call to some helper routine.
   1.228    BasicType rbt = m->result_type();
   1.229    if (rbt == T_ARRAY)  rbt = T_OBJECT;
   1.230 +  stack_push(rbt);  // The return value is already pushed onto the stack.
   1.231    ArgToken ret;
   1.232    if (tailcall) {
   1.233      if (rbt != _rtype) {
   1.234 @@ -1171,7 +1228,6 @@
   1.235      ret = ArgToken();  // Dummy return value.
   1.236    }
   1.237    else {
   1.238 -    stack_push(rbt);  // The return value is already pushed onto the stack.
   1.239      int index = new_local_index(rbt);
   1.240      switch (rbt) {
   1.241      case T_BOOLEAN: case T_BYTE: case T_CHAR:  case T_SHORT:
   1.242 @@ -1196,8 +1252,32 @@
   1.243                                   const MethodHandleWalker::ArgToken& base,
   1.244                                   const MethodHandleWalker::ArgToken& offset,
   1.245                                   TRAPS) {
   1.246 -  Unimplemented();
   1.247 -  return ArgToken();
   1.248 +  switch (base.token_type()) {
   1.249 +    case tt_parameter:
   1.250 +    case tt_temporary:
   1.251 +      emit_load(base.basic_type(), base.index());
   1.252 +      break;
   1.253 +    case tt_constant:
   1.254 +      emit_load_constant(base);
   1.255 +      break;
   1.256 +    default:
   1.257 +      ShouldNotReachHere();
   1.258 +  }
   1.259 +  switch (offset.token_type()) {
   1.260 +    case tt_parameter:
   1.261 +    case tt_temporary:
   1.262 +      emit_load(offset.basic_type(), offset.index());
   1.263 +      break;
   1.264 +    case tt_constant:
   1.265 +      emit_load_constant(offset);
   1.266 +      break;
   1.267 +    default:
   1.268 +      ShouldNotReachHere();
   1.269 +  }
   1.270 +  emit_bc(op);
   1.271 +  int index = new_local_index(type);
   1.272 +  emit_store(type, index);
   1.273 +  return ArgToken(tt_temporary, type, index);
   1.274  }
   1.275  
   1.276  
   1.277 @@ -1372,12 +1452,10 @@
   1.278      return s;
   1.279    }
   1.280    ArgToken token(const char* str) {
   1.281 -    jvalue string_con;
   1.282 -    string_con.j = (intptr_t) str;
   1.283 -    return ArgToken(tt_symbolic, T_LONG, string_con);
   1.284 +    return ArgToken(str);
   1.285    }
   1.286    const char* string(ArgToken token) {
   1.287 -    return (const char*) (intptr_t) token.get_jlong();
   1.288 +    return token.str();
   1.289    }
   1.290    void start_params() {
   1.291      _param_state <<= 1;

mercurial