comparison src/share/vm/prims/methodHandleWalk.cpp @ 3740:5ac411b3b8fc

7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly Reviewed-by: kvn, jrose
author never
date Thu, 26 May 2011 14:44:41 -0700
parents a80577f854f9
children 96c891ebe56a cba7b5c2d53f
comparison
equal deleted inserted replaced
3738:c7c81f18c834 3740:5ac411b3b8fc
139 } 139 }
140 140
141 141
142 void MethodHandleChain::lose(const char* msg, TRAPS) { 142 void MethodHandleChain::lose(const char* msg, TRAPS) {
143 _lose_message = msg; 143 _lose_message = msg;
144 #ifdef ASSERT
145 if (Verbose) {
146 tty->print_cr(INTPTR_FORMAT " lose: %s", _method_handle(), msg);
147 print();
148 }
149 #endif
144 if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) { 150 if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) {
145 // throw a preallocated exception 151 // throw a preallocated exception
146 THROW_OOP(Universe::virtual_machine_error_instance()); 152 THROW_OOP(Universe::virtual_machine_error_instance());
147 } 153 }
148 THROW_MSG(vmSymbols::java_lang_InternalError(), msg); 154 THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
149 } 155 }
156
157
158 #ifdef ASSERT
159 static const char* adapter_ops[] = {
160 "retype_only" ,
161 "retype_raw" ,
162 "check_cast" ,
163 "prim_to_prim" ,
164 "ref_to_prim" ,
165 "prim_to_ref" ,
166 "swap_args" ,
167 "rot_args" ,
168 "dup_args" ,
169 "drop_args" ,
170 "collect_args" ,
171 "spread_args" ,
172 "fold_args"
173 };
174
175 static const char* adapter_op_to_string(int op) {
176 if (op >= 0 && op < (int)ARRAY_SIZE(adapter_ops))
177 return adapter_ops[op];
178 return "unknown_op";
179 }
180
181
182 void MethodHandleChain::print(Handle mh) {
183 EXCEPTION_MARK;
184 MethodHandleChain mhc(mh, THREAD);
185 if (HAS_PENDING_EXCEPTION) {
186 oop ex = THREAD->pending_exception();
187 CLEAR_PENDING_EXCEPTION;
188 ex->print();
189 return;
190 }
191 mhc.print();
192 }
193
194
195 void MethodHandleChain::print() {
196 EXCEPTION_MARK;
197 print_impl(THREAD);
198 if (HAS_PENDING_EXCEPTION) {
199 oop ex = THREAD->pending_exception();
200 CLEAR_PENDING_EXCEPTION;
201 ex->print();
202 }
203 }
204
205 void MethodHandleChain::print_impl(TRAPS) {
206 ResourceMark rm;
207
208 MethodHandleChain chain(_root, CHECK);
209 for (;;) {
210 tty->print(INTPTR_FORMAT ": ", chain.method_handle()());
211 if (chain.is_bound()) {
212 tty->print("bound: arg_type %s arg_slot %d",
213 type2name(chain.bound_arg_type()),
214 chain.bound_arg_slot());
215 oop o = chain.bound_arg_oop();
216 if (o != NULL) {
217 if (o->is_instance()) {
218 tty->print(" instance %s", o->klass()->klass_part()->internal_name());
219 } else {
220 o->print();
221 }
222 }
223 } else if (chain.is_adapter()) {
224 tty->print("adapter: arg_slot %d conversion op %s",
225 chain.adapter_arg_slot(),
226 adapter_op_to_string(chain.adapter_conversion_op()));
227 switch (chain.adapter_conversion_op()) {
228 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
229 case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW:
230 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
231 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
232 case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM:
233 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF:
234 break;
235
236 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS:
237 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
238 int dest_arg_slot = chain.adapter_conversion_vminfo();
239 tty->print(" dest_arg_slot %d type %s", dest_arg_slot, type2name(chain.adapter_conversion_src_type()));
240 break;
241 }
242
243 case java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS:
244 case java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS: {
245 int dup_slots = chain.adapter_conversion_stack_pushes();
246 tty->print(" pushes %d", dup_slots);
247 break;
248 }
249
250 case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS:
251 case java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS: {
252 int coll_slots = chain.MethodHandle_vmslots();
253 tty->print(" coll_slots %d", coll_slots);
254 break;
255 }
256
257 case java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS: {
258 // Check the required length.
259 int spread_slots = 1 + chain.adapter_conversion_stack_pushes();
260 tty->print(" spread_slots %d", spread_slots);
261 break;
262 }
263
264 default:
265 tty->print_cr("bad adapter conversion");
266 break;
267 }
268 } else {
269 // DMH
270 tty->print("direct: ");
271 chain.last_method_oop()->print_short_name(tty);
272 }
273
274 tty->print(" (");
275 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(chain.method_type_oop());
276 for (int i = ptypes->length() - 1; i >= 0; i--) {
277 BasicType t = java_lang_Class::as_BasicType(ptypes->obj_at(i));
278 if (t == T_ARRAY) t = T_OBJECT;
279 tty->print("%c", type2char(t));
280 if (t == T_LONG || t == T_DOUBLE) tty->print("_");
281 }
282 tty->print(")");
283 BasicType rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(chain.method_type_oop()));
284 if (rtype == T_ARRAY) rtype = T_OBJECT;
285 tty->print("%c", type2char(rtype));
286 tty->cr();
287 if (!chain.is_last()) {
288 chain.next(CHECK);
289 } else {
290 break;
291 }
292 }
293 }
294 #endif
150 295
151 296
152 // ----------------------------------------------------------------------------- 297 // -----------------------------------------------------------------------------
153 // MethodHandleWalker 298 // MethodHandleWalker
154 299
203 assert(_outgoing_argc == argument_count_slow(), "empty slots under control"); 348 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
204 349
205 if (chain().is_adapter()) { 350 if (chain().is_adapter()) {
206 int conv_op = chain().adapter_conversion_op(); 351 int conv_op = chain().adapter_conversion_op();
207 int arg_slot = chain().adapter_arg_slot(); 352 int arg_slot = chain().adapter_arg_slot();
208 SlotState* arg_state = slot_state(arg_slot); 353
209 if (arg_state == NULL 354 // Check that the arg_slot is valid. In most cases it must be
210 && conv_op > java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) { 355 // within range of the current arguments but there are some
211 lose("bad argument index", CHECK_(empty)); 356 // exceptions. Those are sanity checked in their implemention
357 // below.
358 if ((arg_slot < 0 || arg_slot >= _outgoing.length()) &&
359 conv_op > java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW &&
360 conv_op != java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS &&
361 conv_op != java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS) {
362 lose(err_msg("bad argument index %d", arg_slot), CHECK_(empty));
212 } 363 }
213 364
214 bool retain_original_args = false; // used by fold/collect logic 365 bool retain_original_args = false; // used by fold/collect logic
215 366
216 // perform the adapter action 367 // perform the adapter action
235 if (nptypes != java_lang_invoke_MethodType::ptype_count(incoming_mtype())) 386 if (nptypes != java_lang_invoke_MethodType::ptype_count(incoming_mtype()))
236 lose("incoming and outgoing parameter count do not agree", CHECK_(empty)); 387 lose("incoming and outgoing parameter count do not agree", CHECK_(empty));
237 388
238 // Argument types. 389 // Argument types.
239 for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) { 390 for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) {
240 SlotState* arg_state = slot_state(slot); 391 if (arg_type(slot) == T_VOID) continue;
241 if (arg_state->_type == T_VOID) continue;
242 392
243 klassOop src_klass = NULL; 393 klassOop src_klass = NULL;
244 klassOop dst_klass = NULL; 394 klassOop dst_klass = NULL;
245 BasicType src = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(incoming_mtype(), i), &src_klass); 395 BasicType src = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(incoming_mtype(), i), &src_klass);
246 BasicType dst = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(outgoing_mtype(), i), &dst_klass); 396 BasicType dst = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(outgoing_mtype(), i), &dst_klass);
260 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: { 410 case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: {
261 // checkcast the Nth outgoing argument in place 411 // checkcast the Nth outgoing argument in place
262 klassOop dest_klass = NULL; 412 klassOop dest_klass = NULL;
263 BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass); 413 BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass);
264 assert(dest == T_OBJECT, ""); 414 assert(dest == T_OBJECT, "");
265 assert(dest == arg_state->_type, ""); 415 ArgToken arg = _outgoing.at(arg_slot);
266 ArgToken arg = arg_state->_arg; 416 assert(dest == arg.basic_type(), "");
267 ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty)); 417 ArgToken new_arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty));
268 assert(!arg.has_index() || arg.index() == new_arg.index(), "should be the same index"); 418 assert(!arg.has_index() || arg.index() == new_arg.index(), "should be the same index");
269 debug_only(dest_klass = (klassOop)badOop); 419 debug_only(dest_klass = (klassOop)badOop);
270 break; 420 break;
271 } 421 }
272 422
273 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: { 423 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: {
274 // i2l, etc., on the Nth outgoing argument in place 424 // i2l, etc., on the Nth outgoing argument in place
275 BasicType src = chain().adapter_conversion_src_type(), 425 BasicType src = chain().adapter_conversion_src_type(),
276 dest = chain().adapter_conversion_dest_type(); 426 dest = chain().adapter_conversion_dest_type();
427 ArgToken arg = _outgoing.at(arg_slot);
277 Bytecodes::Code bc = conversion_code(src, dest); 428 Bytecodes::Code bc = conversion_code(src, dest);
278 ArgToken arg = arg_state->_arg;
279 if (bc == Bytecodes::_nop) { 429 if (bc == Bytecodes::_nop) {
280 break; 430 break;
281 } else if (bc != Bytecodes::_illegal) { 431 } else if (bc != Bytecodes::_illegal) {
282 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty)); 432 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
283 } else if (is_subword_type(dest)) { 433 } else if (is_subword_type(dest)) {
287 bc = conversion_code(T_INT, dest); 437 bc = conversion_code(T_INT, dest);
288 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty)); 438 arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
289 } 439 }
290 } 440 }
291 if (bc == Bytecodes::_illegal) { 441 if (bc == Bytecodes::_illegal) {
292 lose("bad primitive conversion", CHECK_(empty)); 442 lose(err_msg("bad primitive conversion for %s -> %s", type2name(src), type2name(dest)), CHECK_(empty));
293 } 443 }
294 change_argument(src, arg_slot, dest, arg); 444 change_argument(src, arg_slot, dest, arg);
295 break; 445 break;
296 } 446 }
297 447
298 case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM: { 448 case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM: {
299 // checkcast to wrapper type & call intValue, etc. 449 // checkcast to wrapper type & call intValue, etc.
300 BasicType dest = chain().adapter_conversion_dest_type(); 450 BasicType dest = chain().adapter_conversion_dest_type();
301 ArgToken arg = arg_state->_arg; 451 ArgToken arg = _outgoing.at(arg_slot);
302 arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest), 452 arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest),
303 Bytecodes::_checkcast, arg, CHECK_(empty)); 453 Bytecodes::_checkcast, arg, CHECK_(empty));
304 vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest); 454 vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest);
305 if (unboxer == vmIntrinsics::_none) { 455 if (unboxer == vmIntrinsics::_none) {
306 lose("no unboxing method", CHECK_(empty)); 456 lose("no unboxing method", CHECK_(empty));
314 } 464 }
315 465
316 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: { 466 case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: {
317 // call wrapper type.valueOf 467 // call wrapper type.valueOf
318 BasicType src = chain().adapter_conversion_src_type(); 468 BasicType src = chain().adapter_conversion_src_type();
319 ArgToken arg = arg_state->_arg;
320 vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src); 469 vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src);
321 if (boxer == vmIntrinsics::_none) { 470 if (boxer == vmIntrinsics::_none) {
322 lose("no boxing method", CHECK_(empty)); 471 lose("no boxing method", CHECK_(empty));
323 } 472 }
473 ArgToken arg = _outgoing.at(arg_slot);
324 ArgToken arglist[2]; 474 ArgToken arglist[2];
325 arglist[0] = arg; // outgoing value 475 arglist[0] = arg; // outgoing value
326 arglist[1] = ArgToken(); // sentinel 476 arglist[1] = ArgToken(); // sentinel
327 arg = make_invoke(NULL, boxer, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty)); 477 arg = make_invoke(NULL, boxer, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
328 change_argument(src, arg_slot, T_OBJECT, arg); 478 change_argument(src, arg_slot, T_OBJECT, arg);
329 break; 479 break;
330 } 480 }
331 481
332 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: { 482 case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: {
333 int dest_arg_slot = chain().adapter_conversion_vminfo(); 483 int dest_arg_slot = chain().adapter_conversion_vminfo();
334 if (!slot_has_argument(dest_arg_slot)) { 484 if (!has_argument(dest_arg_slot)) {
335 lose("bad swap index", CHECK_(empty)); 485 lose("bad swap index", CHECK_(empty));
336 } 486 }
337 // a simple swap between two arguments 487 // a simple swap between two arguments
338 SlotState* dest_arg_state = slot_state(dest_arg_slot); 488 if (arg_slot > dest_arg_slot) {
339 SlotState temp = (*dest_arg_state); 489 int tmp = arg_slot;
340 (*dest_arg_state) = (*arg_state); 490 arg_slot = dest_arg_slot;
341 (*arg_state) = temp; 491 dest_arg_slot = tmp;
492 }
493 ArgToken a1 = _outgoing.at(arg_slot);
494 ArgToken a2 = _outgoing.at(dest_arg_slot);
495 change_argument(a2.basic_type(), dest_arg_slot, a1);
496 change_argument(a1.basic_type(), arg_slot, a2);
342 break; 497 break;
343 } 498 }
344 499
345 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: { 500 case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
346 int dest_arg_slot = chain().adapter_conversion_vminfo(); 501 int dest_arg_slot = chain().adapter_conversion_vminfo();
347 if (!slot_has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) { 502 if (!has_argument(dest_arg_slot) || arg_slot == dest_arg_slot) {
348 lose("bad rotate index", CHECK_(empty)); 503 lose("bad rotate index", CHECK_(empty));
349 } 504 }
350 SlotState* dest_arg_state = slot_state(dest_arg_slot);
351 // Rotate the source argument (plus following N slots) into the 505 // Rotate the source argument (plus following N slots) into the
352 // position occupied by the dest argument (plus following N slots). 506 // position occupied by the dest argument (plus following N slots).
353 int rotate_count = type2size[dest_arg_state->_type]; 507 int rotate_count = type2size[chain().adapter_conversion_src_type()];
354 // (no other rotate counts are currently supported) 508 // (no other rotate counts are currently supported)
355 if (arg_slot < dest_arg_slot) { 509 if (arg_slot < dest_arg_slot) {
356 for (int i = 0; i < rotate_count; i++) { 510 for (int i = 0; i < rotate_count; i++) {
357 SlotState temp = _outgoing.at(arg_slot); 511 ArgToken temp = _outgoing.at(arg_slot);
358 _outgoing.remove_at(arg_slot); 512 _outgoing.remove_at(arg_slot);
359 _outgoing.insert_before(dest_arg_slot + rotate_count - 1, temp); 513 _outgoing.insert_before(dest_arg_slot + rotate_count - 1, temp);
360 } 514 }
361 } else { // arg_slot > dest_arg_slot 515 } else { // arg_slot > dest_arg_slot
362 for (int i = 0; i < rotate_count; i++) { 516 for (int i = 0; i < rotate_count; i++) {
363 SlotState temp = _outgoing.at(arg_slot + rotate_count - 1); 517 ArgToken temp = _outgoing.at(arg_slot + rotate_count - 1);
364 _outgoing.remove_at(arg_slot + rotate_count - 1); 518 _outgoing.remove_at(arg_slot + rotate_count - 1);
365 _outgoing.insert_before(dest_arg_slot, temp); 519 _outgoing.insert_before(dest_arg_slot, temp);
366 } 520 }
367 } 521 }
522 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
368 break; 523 break;
369 } 524 }
370 525
371 case java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS: { 526 case java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS: {
372 int dup_slots = chain().adapter_conversion_stack_pushes(); 527 int dup_slots = chain().adapter_conversion_stack_pushes();
373 if (dup_slots <= 0) { 528 if (dup_slots <= 0) {
374 lose("bad dup count", CHECK_(empty)); 529 lose("bad dup count", CHECK_(empty));
375 } 530 }
376 for (int i = 0; i < dup_slots; i++) { 531 for (int i = 0; i < dup_slots; i++) {
377 SlotState* dup = slot_state(arg_slot + 2*i); 532 ArgToken dup = _outgoing.at(arg_slot + 2*i);
378 if (dup == NULL) break; // safety net 533 if (dup.basic_type() != T_VOID) _outgoing_argc += 1;
379 if (dup->_type != T_VOID) _outgoing_argc += 1; 534 _outgoing.insert_before(i, dup);
380 _outgoing.insert_before(i, (*dup)); 535 }
381 } 536 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
382 break; 537 break;
383 } 538 }
384 539
385 case java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS: { 540 case java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS: {
386 int drop_slots = -chain().adapter_conversion_stack_pushes(); 541 int drop_slots = -chain().adapter_conversion_stack_pushes();
387 if (drop_slots <= 0) { 542 if (drop_slots <= 0) {
388 lose("bad drop count", CHECK_(empty)); 543 lose("bad drop count", CHECK_(empty));
389 } 544 }
390 for (int i = 0; i < drop_slots; i++) { 545 for (int i = 0; i < drop_slots; i++) {
391 SlotState* drop = slot_state(arg_slot); 546 ArgToken drop = _outgoing.at(arg_slot);
392 if (drop == NULL) break; // safety net 547 if (drop.basic_type() != T_VOID) _outgoing_argc -= 1;
393 if (drop->_type != T_VOID) _outgoing_argc -= 1;
394 _outgoing.remove_at(arg_slot); 548 _outgoing.remove_at(arg_slot);
395 } 549 }
550 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
396 break; 551 break;
397 } 552 }
398 553
399 case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS: 554 case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS:
400 retain_original_args = true; // and fall through: 555 retain_original_args = true; // and fall through:
413 arglist[0] = make_oop_constant(recursive_mh(), CHECK_(empty)); 568 arglist[0] = make_oop_constant(recursive_mh(), CHECK_(empty));
414 if (arg_slot < 0 || coll_slots < 0 || arg_slot + coll_slots > _outgoing.length()) { 569 if (arg_slot < 0 || coll_slots < 0 || arg_slot + coll_slots > _outgoing.length()) {
415 lose("bad fold/collect arg slot", CHECK_(empty)); 570 lose("bad fold/collect arg slot", CHECK_(empty));
416 } 571 }
417 for (int i = 0, slot = arg_slot + coll_slots - 1; slot >= arg_slot; slot--) { 572 for (int i = 0, slot = arg_slot + coll_slots - 1; slot >= arg_slot; slot--) {
418 SlotState* arg_state = slot_state(slot); 573 ArgToken arg_state = _outgoing.at(slot);
419 BasicType arg_type = arg_state->_type; 574 BasicType arg_type = arg_state.basic_type();
420 if (arg_type == T_VOID) continue; 575 if (arg_type == T_VOID) continue;
421 ArgToken arg = _outgoing.at(slot)._arg; 576 ArgToken arg = _outgoing.at(slot);
422 if (i >= argc) { lose("bad fold/collect arg", CHECK_(empty)); } 577 if (i >= argc) { lose("bad fold/collect arg", CHECK_(empty)); }
423 arglist[1+i] = arg; 578 arglist[1+i] = arg;
424 if (!retain_original_args) 579 if (!retain_original_args)
425 change_argument(arg_type, slot, T_VOID, ArgToken(tt_void)); 580 change_argument(arg_type, slot, T_VOID, ArgToken(tt_void));
426 i++; 581 i++;
464 &element_klass_oop); 619 &element_klass_oop);
465 KlassHandle element_klass(THREAD, element_klass_oop); 620 KlassHandle element_klass(THREAD, element_klass_oop);
466 debug_only(element_klass_oop = (klassOop)badOop); 621 debug_only(element_klass_oop = (klassOop)badOop);
467 622
468 // Fetch the argument, which we will cast to the required array type. 623 // Fetch the argument, which we will cast to the required array type.
469 assert(arg_state->_type == T_OBJECT, ""); 624 ArgToken arg = _outgoing.at(arg_slot);
470 ArgToken array_arg = arg_state->_arg; 625 assert(arg.basic_type() == T_OBJECT, "");
626 ArgToken array_arg = arg;
471 array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_(empty)); 627 array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_(empty));
472 change_argument(T_OBJECT, arg_slot, T_VOID, ArgToken(tt_void)); 628 change_argument(T_OBJECT, arg_slot, T_VOID, ArgToken(tt_void));
473 629
474 // Check the required length. 630 // Check the required length.
475 int spread_slots = 1 + chain().adapter_conversion_stack_pushes(); 631 int spread_slots = 1 + chain().adapter_conversion_stack_pushes();
532 if (arg_type == T_OBJECT) { 688 if (arg_type == T_OBJECT) {
533 arg = make_oop_constant(arg_oop, CHECK_(empty)); 689 arg = make_oop_constant(arg_oop, CHECK_(empty));
534 } else { 690 } else {
535 jvalue arg_value; 691 jvalue arg_value;
536 BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value); 692 BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value);
537 if (bt == arg_type) { 693 if (bt == arg_type || (bt == T_INT && is_subword_type(arg_type))) {
538 arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty)); 694 arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty));
539 } else { 695 } else {
540 lose("bad bound value", CHECK_(empty)); 696 lose(err_msg("bad bound value: arg_type %s boxing %s", type2name(arg_type), type2name(bt)), CHECK_(empty));
541 } 697 }
542 } 698 }
543 DEBUG_ONLY(arg_oop = badOop); 699 DEBUG_ONLY(arg_oop = badOop);
544 change_argument(T_VOID, arg_slot, arg_type, arg); 700 change_argument(T_VOID, arg_slot, arg_type, arg);
545 } 701 }
555 // finish the sequence with a tail-call to the ultimate target 711 // finish the sequence with a tail-call to the ultimate target
556 // parameters are passed in logical order (recv 1st), not slot order 712 // parameters are passed in logical order (recv 1st), not slot order
557 ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, _outgoing.length() + 1); 713 ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, _outgoing.length() + 1);
558 int ap = 0; 714 int ap = 0;
559 for (int i = _outgoing.length() - 1; i >= 0; i--) { 715 for (int i = _outgoing.length() - 1; i >= 0; i--) {
560 SlotState* arg_state = slot_state(i); 716 ArgToken arg_state = _outgoing.at(i);
561 if (arg_state->_type == T_VOID) continue; 717 if (arg_state.basic_type() == T_VOID) continue;
562 arglist[ap++] = _outgoing.at(i)._arg; 718 arglist[ap++] = _outgoing.at(i);
563 } 719 }
564 assert(ap == _outgoing_argc, ""); 720 assert(ap == _outgoing_argc, "");
565 arglist[ap] = ArgToken(); // add a sentinel, for the sake of asserts 721 arglist[ap] = ArgToken(); // add a sentinel, for the sake of asserts
566 return make_invoke(chain().last_method_oop(), 722 return make_invoke(chain().last_method_oop(),
567 vmIntrinsics::_none, 723 vmIntrinsics::_none,
577 Handle mtype(THREAD, chain().method_type_oop()); 733 Handle mtype(THREAD, chain().method_type_oop());
578 int nptypes = java_lang_invoke_MethodType::ptype_count(mtype()); 734 int nptypes = java_lang_invoke_MethodType::ptype_count(mtype());
579 _outgoing_argc = nptypes; 735 _outgoing_argc = nptypes;
580 int argp = nptypes - 1; 736 int argp = nptypes - 1;
581 if (argp >= 0) { 737 if (argp >= 0) {
582 _outgoing.at_grow(argp, make_state(T_VOID, ArgToken(tt_void))); // presize 738 _outgoing.at_grow(argp, ArgToken(tt_void)); // presize
583 } 739 }
584 for (int i = 0; i < nptypes; i++) { 740 for (int i = 0; i < nptypes; i++) {
585 klassOop arg_type_klass = NULL; 741 klassOop arg_type_klass = NULL;
586 BasicType arg_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(mtype(), i), &arg_type_klass); 742 BasicType arg_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(mtype(), i), &arg_type_klass);
587 int index = new_local_index(arg_type); 743 int index = new_local_index(arg_type);
588 ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK); 744 ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK);
589 DEBUG_ONLY(arg_type_klass = (klassOop) NULL); 745 DEBUG_ONLY(arg_type_klass = (klassOop) NULL);
590 _outgoing.at_put(argp, make_state(arg_type, arg)); 746 _outgoing.at_put(argp, arg);
591 if (type2size[arg_type] == 2) { 747 if (type2size[arg_type] == 2) {
592 // add the extra slot, so we can model the JVM stack 748 // add the extra slot, so we can model the JVM stack
593 _outgoing.insert_before(argp+1, make_state(T_VOID, ArgToken(tt_void))); 749 _outgoing.insert_before(argp+1, ArgToken(tt_void));
594 } 750 }
595 --argp; 751 --argp;
596 } 752 }
597 // call make_parameter at the end of the list for the return type 753 // call make_parameter at the end of the list for the return type
598 klassOop ret_type_klass = NULL; 754 klassOop ret_type_klass = NULL;
599 BasicType ret_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(mtype()), &ret_type_klass); 755 BasicType ret_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(mtype()), &ret_type_klass);
600 ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK); 756 ArgToken ret = make_parameter(ret_type, ret_type_klass, -1, CHECK);
601 // ignore ret; client can catch it if needed 757 // ignore ret; client can catch it if needed
602 } 758
759 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
760
761 verify_args_and_signature(CHECK);
762 }
763
764
765 #ifdef ASSERT
766 void MethodHandleWalker::verify_args_and_signature(TRAPS) {
767 int index = _outgoing.length() - 1;
768 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(chain().method_type_oop());
769 for (int i = 0, limit = ptypes->length(); i < limit; i++) {
770 BasicType t = java_lang_Class::as_BasicType(ptypes->obj_at(i));
771 if (t == T_ARRAY) t = T_OBJECT;
772 if (t == T_LONG || t == T_DOUBLE) {
773 assert(T_VOID == _outgoing.at(index).basic_type(), "types must match");
774 index--;
775 }
776 assert(t == _outgoing.at(index).basic_type(), "types must match");
777 index--;
778 }
779 }
780 #endif
603 781
604 782
605 // ----------------------------------------------------------------------------- 783 // -----------------------------------------------------------------------------
606 // MethodHandleWalker::change_argument 784 // MethodHandleWalker::change_argument
607 // 785 //
608 // This is messy because some kinds of arguments are paired with 786 // This is messy because some kinds of arguments are paired with
609 // companion slots containing an empty value. 787 // companion slots containing an empty value.
610 void MethodHandleWalker::change_argument(BasicType old_type, int slot, BasicType new_type, 788 void MethodHandleWalker::change_argument(BasicType old_type, int slot, const ArgToken& new_arg) {
611 const ArgToken& new_arg) { 789 BasicType new_type = new_arg.basic_type();
612 int old_size = type2size[old_type]; 790 int old_size = type2size[old_type];
613 int new_size = type2size[new_type]; 791 int new_size = type2size[new_type];
614 if (old_size == new_size) { 792 if (old_size == new_size) {
615 // simple case first 793 // simple case first
616 _outgoing.at_put(slot, make_state(new_type, new_arg)); 794 _outgoing.at_put(slot, new_arg);
617 } else if (old_size > new_size) { 795 } else if (old_size > new_size) {
618 for (int i = old_size - 1; i >= new_size; i--) { 796 for (int i = old_size - 1; i >= new_size; i--) {
619 assert((i != 0) == (_outgoing.at(slot + i)._type == T_VOID), ""); 797 assert((i != 0) == (_outgoing.at(slot + i).basic_type() == T_VOID), "");
620 _outgoing.remove_at(slot + i); 798 _outgoing.remove_at(slot + i);
621 } 799 }
622 if (new_size > 0) 800 if (new_size > 0)
623 _outgoing.at_put(slot, make_state(new_type, new_arg)); 801 _outgoing.at_put(slot, new_arg);
624 else 802 else
625 _outgoing_argc -= 1; // deleted a real argument 803 _outgoing_argc -= 1; // deleted a real argument
626 } else { 804 } else {
627 for (int i = old_size; i < new_size; i++) { 805 for (int i = old_size; i < new_size; i++) {
628 _outgoing.insert_before(slot + i, make_state(T_VOID, ArgToken(tt_void))); 806 _outgoing.insert_before(slot + i, ArgToken(tt_void));
629 } 807 }
630 _outgoing.at_put(slot, make_state(new_type, new_arg)); 808 _outgoing.at_put(slot, new_arg);
631 if (old_size == 0) 809 if (old_size == 0)
632 _outgoing_argc += 1; // inserted a real argument 810 _outgoing_argc += 1; // inserted a real argument
633 } 811 }
812 assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
634 } 813 }
635 814
636 815
637 #ifdef ASSERT 816 #ifdef ASSERT
638 int MethodHandleWalker::argument_count_slow() { 817 int MethodHandleWalker::argument_count_slow() {
639 int args_seen = 0; 818 int args_seen = 0;
640 for (int i = _outgoing.length() - 1; i >= 0; i--) { 819 for (int i = _outgoing.length() - 1; i >= 0; i--) {
641 if (_outgoing.at(i)._type != T_VOID) { 820 if (_outgoing.at(i).basic_type() != T_VOID) {
642 ++args_seen; 821 ++args_seen;
822 if (_outgoing.at(i).basic_type() == T_LONG ||
823 _outgoing.at(i).basic_type() == T_DOUBLE) {
824 assert(_outgoing.at(i + 1).basic_type() == T_VOID, "should only follow two word");
825 }
826 } else {
827 assert(_outgoing.at(i - 1).basic_type() == T_LONG ||
828 _outgoing.at(i - 1).basic_type() == T_DOUBLE, "should only follow two word");
643 } 829 }
644 } 830 }
645 return args_seen; 831 return args_seen;
646 } 832 }
647 #endif 833 #endif
661 lose("no raw conversion method", CHECK); 847 lose("no raw conversion method", CHECK);
662 } 848 }
663 ArgToken arglist[2]; 849 ArgToken arglist[2];
664 if (!for_return) { 850 if (!for_return) {
665 // argument type conversion 851 // argument type conversion
666 ArgToken arg = _outgoing.at(slot)._arg; 852 ArgToken arg = _outgoing.at(slot);
667 assert(arg.token_type() >= tt_symbolic || src == arg.basic_type(), "sanity"); 853 assert(arg.token_type() >= tt_symbolic || src == arg.basic_type(), "sanity");
668 arglist[0] = arg; // outgoing 'this' 854 arglist[0] = arg; // outgoing 'this'
669 arglist[1] = ArgToken(); // sentinel 855 arglist[1] = ArgToken(); // sentinel
670 arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK); 856 arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
671 change_argument(src, slot, dst, arg); 857 change_argument(src, slot, dst, arg);
681 } 867 }
682 } else if (src == T_OBJECT && is_java_primitive(dst)) { 868 } else if (src == T_OBJECT && is_java_primitive(dst)) {
683 // ref-to-prim: discard ref, push zero 869 // ref-to-prim: discard ref, push zero
684 lose("requested ref-to-prim conversion not expected", CHECK); 870 lose("requested ref-to-prim conversion not expected", CHECK);
685 } else { 871 } else {
686 lose("requested raw conversion not allowed", CHECK); 872 lose(err_msg("requested raw conversion not allowed: %s -> %s", type2name(src), type2name(dst)), CHECK);
687 } 873 }
688 } 874 }
689 } 875 }
690 876
691 877
961 } 1147 }
962 1148
963 1149
964 void MethodHandleCompiler::emit_load_constant(ArgToken arg) { 1150 void MethodHandleCompiler::emit_load_constant(ArgToken arg) {
965 BasicType bt = arg.basic_type(); 1151 BasicType bt = arg.basic_type();
1152 if (is_subword_type(bt)) bt = T_INT;
966 switch (bt) { 1153 switch (bt) {
967 case T_INT: { 1154 case T_INT: {
968 jint value = arg.get_jint(); 1155 jint value = arg.get_jint();
969 if (-1 <= value && value <= 5) 1156 if (-1 <= value && value <= 5)
970 emit_bc(Bytecodes::cast(Bytecodes::_iconst_0 + value)); 1157 emit_bc(Bytecodes::cast(Bytecodes::_iconst_0 + value));
1064 if (index == -1) 1251 if (index == -1)
1065 index = new_local_index(type); 1252 index = new_local_index(type);
1066 emit_store(srctype, index); 1253 emit_store(srctype, index);
1067 break; 1254 break;
1068 1255
1256 case Bytecodes::_nop:
1257 // nothing to do
1258 return src;
1259
1069 default: 1260 default:
1070 if (op == Bytecodes::_illegal) 1261 if (op == Bytecodes::_illegal)
1071 lose("no such primitive conversion", THREAD); 1262 lose(err_msg("no such primitive conversion: %s -> %s", type2name(src.basic_type()), type2name(type)), THREAD);
1072 else 1263 else
1073 lose("bad primitive conversion op", THREAD); 1264 lose(err_msg("bad primitive conversion op: %s", Bytecodes::name(op)), THREAD);
1074 return make_prim_constant(type, &zero_jvalue, THREAD); 1265 return make_prim_constant(type, &zero_jvalue, THREAD);
1075 } 1266 }
1076 1267
1077 return make_parameter(type, tk, index, THREAD); 1268 return make_parameter(type, tk, index, THREAD);
1078 } 1269 }
1298 bt = T_INT; 1489 bt = T_INT;
1299 } 1490 }
1300 1491
1301 // for (int i = 1, imax = _constants.length(); i < imax; i++) { 1492 // for (int i = 1, imax = _constants.length(); i < imax; i++) {
1302 // ConstantValue* con = _constants.at(i); 1493 // ConstantValue* con = _constants.at(i);
1303 // if (con != NULL && con->is_primitive() && con->_type == bt) { 1494 // if (con != NULL && con->is_primitive() && con.basic_type() == bt) {
1304 // bool match = false; 1495 // bool match = false;
1305 // switch (type2size[bt]) { 1496 // switch (type2size[bt]) {
1306 // case 1: if (pcon->_value.i == con->i) match = true; break; 1497 // case 1: if (pcon->_value.i == con->i) match = true; break;
1307 // case 2: if (pcon->_value.j == con->j) match = true; break; 1498 // case 2: if (pcon->_value.j == con->j) match = true; break;
1308 // } 1499 // }
1449 const char* strbuf() { 1640 const char* strbuf() {
1450 const char* s = _strbuf.as_string(); 1641 const char* s = _strbuf.as_string();
1451 _strbuf.reset(); 1642 _strbuf.reset();
1452 return s; 1643 return s;
1453 } 1644 }
1454 ArgToken token(const char* str) { 1645 ArgToken token(const char* str, BasicType type) {
1455 return ArgToken(str); 1646 return ArgToken(str, type);
1456 } 1647 }
1457 const char* string(ArgToken token) { 1648 const char* string(ArgToken token) {
1458 return token.str(); 1649 return token.str();
1459 } 1650 }
1460 void start_params() { 1651 void start_params() {
1472 kname = Klass::cast(tk)->external_name(); 1663 kname = Klass::cast(tk)->external_name();
1473 s->print("%s", (kname != NULL) ? kname : type2name(type)); 1664 s->print("%s", (kname != NULL) ? kname : type2name(type));
1474 } 1665 }
1475 ArgToken maybe_make_temp(const char* statement_op, BasicType type, const char* temp_name) { 1666 ArgToken maybe_make_temp(const char* statement_op, BasicType type, const char* temp_name) {
1476 const char* value = strbuf(); 1667 const char* value = strbuf();
1477 if (!_verbose) return token(value); 1668 if (!_verbose) return token(value, type);
1478 // make an explicit binding for each separate value 1669 // make an explicit binding for each separate value
1479 _strbuf.print("%s%d", temp_name, ++_temp_num); 1670 _strbuf.print("%s%d", temp_name, ++_temp_num);
1480 const char* temp = strbuf(); 1671 const char* temp = strbuf();
1481 _out->print("\n %s %s %s = %s;", statement_op, type2name(type), temp, value); 1672 _out->print("\n %s %s %s = %s;", statement_op, type2name(type), temp, value);
1482 return token(temp); 1673 return token(temp, type);
1483 } 1674 }
1484 1675
1485 public: 1676 public:
1486 MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS) 1677 MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS)
1487 : MethodHandleWalker(root, false, THREAD), 1678 : MethodHandleWalker(root, false, THREAD),
1493 start_params(); 1684 start_params();
1494 } 1685 }
1495 virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) { 1686 virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) {
1496 if (argnum < 0) { 1687 if (argnum < 0) {
1497 end_params(); 1688 end_params();
1498 return token("return"); 1689 return token("return", type);
1499 } 1690 }
1500 if ((_param_state & 1) == 0) { 1691 if ((_param_state & 1) == 0) {
1501 _param_state |= 1; 1692 _param_state |= 1;
1502 _out->print(_verbose ? "\n " : ""); 1693 _out->print(_verbose ? "\n " : "");
1503 } else { 1694 } else {
1508 // generate an argument name 1699 // generate an argument name
1509 _strbuf.print("a%d", argnum); 1700 _strbuf.print("a%d", argnum);
1510 const char* arg = strbuf(); 1701 const char* arg = strbuf();
1511 put_type_name(type, tk, _out); 1702 put_type_name(type, tk, _out);
1512 _out->print(" %s", arg); 1703 _out->print(" %s", arg);
1513 return token(arg); 1704 return token(arg, type);
1514 } 1705 }
1515 virtual ArgToken make_oop_constant(oop con, TRAPS) { 1706 virtual ArgToken make_oop_constant(oop con, TRAPS) {
1516 if (con == NULL) 1707 if (con == NULL)
1517 _strbuf.print("null"); 1708 _strbuf.print("null");
1518 else 1709 else
1595 MethodHandlePrinter printer(root, verbose, out, CHECK); 1786 MethodHandlePrinter printer(root, verbose, out, CHECK);
1596 printer.walk(CHECK); 1787 printer.walk(CHECK);
1597 out->print("\n"); 1788 out->print("\n");
1598 } 1789 }
1599 static void print(Handle root, bool verbose = Verbose, outputStream* out = tty) { 1790 static void print(Handle root, bool verbose = Verbose, outputStream* out = tty) {
1600 EXCEPTION_MARK; 1791 Thread* THREAD = Thread::current();
1601 ResourceMark rm; 1792 ResourceMark rm;
1602 MethodHandlePrinter printer(root, verbose, out, THREAD); 1793 MethodHandlePrinter printer(root, verbose, out, THREAD);
1603 if (!HAS_PENDING_EXCEPTION) 1794 if (!HAS_PENDING_EXCEPTION)
1604 printer.walk(THREAD); 1795 printer.walk(THREAD);
1605 if (HAS_PENDING_EXCEPTION) { 1796 if (HAS_PENDING_EXCEPTION) {