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;