450 // restore sp |
450 // restore sp |
451 __ mov(rsp, r13); |
451 __ mov(rsp, r13); |
452 __ bind(L); |
452 __ bind(L); |
453 } |
453 } |
454 |
454 |
455 // Helper function to put tags in interpreter stack. |
|
456 static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) { |
|
457 if (TaggedStackInterpreter) { |
|
458 int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); |
|
459 if (sig == T_OBJECT || sig == T_ARRAY) { |
|
460 __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagReference); |
|
461 } else if (sig == T_LONG || sig == T_DOUBLE) { |
|
462 int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); |
|
463 __ movptr(Address(rsp, next_tag_offset), (int32_t) frame::TagValue); |
|
464 __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue); |
|
465 } else { |
|
466 __ movptr(Address(rsp, tag_offset), (int32_t) frame::TagValue); |
|
467 } |
|
468 } |
|
469 } |
|
470 |
|
471 |
455 |
472 static void gen_c2i_adapter(MacroAssembler *masm, |
456 static void gen_c2i_adapter(MacroAssembler *masm, |
473 int total_args_passed, |
457 int total_args_passed, |
474 int comp_args_on_stack, |
458 int comp_args_on_stack, |
475 const BasicType *sig_bt, |
459 const BasicType *sig_bt, |
487 // Since all args are passed on the stack, total_args_passed * |
471 // Since all args are passed on the stack, total_args_passed * |
488 // Interpreter::stackElementSize is the space we need. Plus 1 because |
472 // Interpreter::stackElementSize is the space we need. Plus 1 because |
489 // we also account for the return address location since |
473 // we also account for the return address location since |
490 // we store it first rather than hold it in rax across all the shuffling |
474 // we store it first rather than hold it in rax across all the shuffling |
491 |
475 |
492 int extraspace = (total_args_passed * Interpreter::stackElementSize()) + wordSize; |
476 int extraspace = (total_args_passed * Interpreter::stackElementSize) + wordSize; |
493 |
477 |
494 // stack is aligned, keep it that way |
478 // stack is aligned, keep it that way |
495 extraspace = round_to(extraspace, 2*wordSize); |
479 extraspace = round_to(extraspace, 2*wordSize); |
496 |
480 |
497 // Get return address |
481 // Get return address |
511 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); |
495 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); |
512 continue; |
496 continue; |
513 } |
497 } |
514 |
498 |
515 // offset to start parameters |
499 // offset to start parameters |
516 int st_off = (total_args_passed - i) * Interpreter::stackElementSize() + |
500 int st_off = (total_args_passed - i) * Interpreter::stackElementSize; |
517 Interpreter::value_offset_in_bytes(); |
501 int next_off = st_off - Interpreter::stackElementSize; |
518 int next_off = st_off - Interpreter::stackElementSize(); |
|
519 |
502 |
520 // Say 4 args: |
503 // Say 4 args: |
521 // i st_off |
504 // i st_off |
522 // 0 32 T_LONG |
505 // 0 32 T_LONG |
523 // 1 24 T_VOID |
506 // 1 24 T_VOID |
541 int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; |
524 int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; |
542 if (!r_2->is_valid()) { |
525 if (!r_2->is_valid()) { |
543 // sign extend?? |
526 // sign extend?? |
544 __ movl(rax, Address(rsp, ld_off)); |
527 __ movl(rax, Address(rsp, ld_off)); |
545 __ movptr(Address(rsp, st_off), rax); |
528 __ movptr(Address(rsp, st_off), rax); |
546 tag_stack(masm, sig_bt[i], st_off); |
|
547 |
529 |
548 } else { |
530 } else { |
549 |
531 |
550 __ movq(rax, Address(rsp, ld_off)); |
532 __ movq(rax, Address(rsp, ld_off)); |
551 |
533 |
558 #ifdef ASSERT |
540 #ifdef ASSERT |
559 // Overwrite the unused slot with known junk |
541 // Overwrite the unused slot with known junk |
560 __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); |
542 __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); |
561 __ movptr(Address(rsp, st_off), rax); |
543 __ movptr(Address(rsp, st_off), rax); |
562 #endif /* ASSERT */ |
544 #endif /* ASSERT */ |
563 tag_stack(masm, sig_bt[i], next_off); |
|
564 } else { |
545 } else { |
565 __ movq(Address(rsp, st_off), rax); |
546 __ movq(Address(rsp, st_off), rax); |
566 tag_stack(masm, sig_bt[i], st_off); |
|
567 } |
547 } |
568 } |
548 } |
569 } else if (r_1->is_Register()) { |
549 } else if (r_1->is_Register()) { |
570 Register r = r_1->as_Register(); |
550 Register r = r_1->as_Register(); |
571 if (!r_2->is_valid()) { |
551 if (!r_2->is_valid()) { |
572 // must be only an int (or less ) so move only 32bits to slot |
552 // must be only an int (or less ) so move only 32bits to slot |
573 // why not sign extend?? |
553 // why not sign extend?? |
574 __ movl(Address(rsp, st_off), r); |
554 __ movl(Address(rsp, st_off), r); |
575 tag_stack(masm, sig_bt[i], st_off); |
|
576 } else { |
555 } else { |
577 // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG |
556 // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG |
578 // T_DOUBLE and T_LONG use two slots in the interpreter |
557 // T_DOUBLE and T_LONG use two slots in the interpreter |
579 if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { |
558 if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { |
580 // long/double in gpr |
559 // long/double in gpr |
582 // Overwrite the unused slot with known junk |
561 // Overwrite the unused slot with known junk |
583 __ mov64(rax, CONST64(0xdeadffffdeadaaab)); |
562 __ mov64(rax, CONST64(0xdeadffffdeadaaab)); |
584 __ movptr(Address(rsp, st_off), rax); |
563 __ movptr(Address(rsp, st_off), rax); |
585 #endif /* ASSERT */ |
564 #endif /* ASSERT */ |
586 __ movq(Address(rsp, next_off), r); |
565 __ movq(Address(rsp, next_off), r); |
587 tag_stack(masm, sig_bt[i], next_off); |
|
588 } else { |
566 } else { |
589 __ movptr(Address(rsp, st_off), r); |
567 __ movptr(Address(rsp, st_off), r); |
590 tag_stack(masm, sig_bt[i], st_off); |
|
591 } |
568 } |
592 } |
569 } |
593 } else { |
570 } else { |
594 assert(r_1->is_XMMRegister(), ""); |
571 assert(r_1->is_XMMRegister(), ""); |
595 if (!r_2->is_valid()) { |
572 if (!r_2->is_valid()) { |
596 // only a float use just part of the slot |
573 // only a float use just part of the slot |
597 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); |
574 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); |
598 tag_stack(masm, sig_bt[i], st_off); |
|
599 } else { |
575 } else { |
600 #ifdef ASSERT |
576 #ifdef ASSERT |
601 // Overwrite the unused slot with known junk |
577 // Overwrite the unused slot with known junk |
602 __ mov64(rax, CONST64(0xdeadffffdeadaaac)); |
578 __ mov64(rax, CONST64(0xdeadffffdeadaaac)); |
603 __ movptr(Address(rsp, st_off), rax); |
579 __ movptr(Address(rsp, st_off), rax); |
604 #endif /* ASSERT */ |
580 #endif /* ASSERT */ |
605 __ movdbl(Address(rsp, next_off), r_1->as_XMMRegister()); |
581 __ movdbl(Address(rsp, next_off), r_1->as_XMMRegister()); |
606 tag_stack(masm, sig_bt[i], next_off); |
|
607 } |
582 } |
608 } |
583 } |
609 } |
584 } |
610 |
585 |
611 // Schedule the branch target address early. |
586 // Schedule the branch target address early. |
686 // Pick up 0, 1 or 2 words from SP+offset. |
661 // Pick up 0, 1 or 2 words from SP+offset. |
687 |
662 |
688 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), |
663 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), |
689 "scrambled load targets?"); |
664 "scrambled load targets?"); |
690 // Load in argument order going down. |
665 // Load in argument order going down. |
691 int ld_off = (total_args_passed - i)*Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); |
666 int ld_off = (total_args_passed - i)*Interpreter::stackElementSize; |
692 // Point to interpreter value (vs. tag) |
667 // Point to interpreter value (vs. tag) |
693 int next_off = ld_off - Interpreter::stackElementSize(); |
668 int next_off = ld_off - Interpreter::stackElementSize; |
694 // |
669 // |
695 // |
670 // |
696 // |
671 // |
697 VMReg r_1 = regs[i].first(); |
672 VMReg r_1 = regs[i].first(); |
698 VMReg r_2 = regs[i].second(); |
673 VMReg r_2 = regs[i].second(); |
2533 #endif // HAVE_DTRACE_H |
2508 #endif // HAVE_DTRACE_H |
2534 |
2509 |
2535 // this function returns the adjust size (in number of words) to a c2i adapter |
2510 // this function returns the adjust size (in number of words) to a c2i adapter |
2536 // activation for use during deoptimization |
2511 // activation for use during deoptimization |
2537 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { |
2512 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { |
2538 return (callee_locals - callee_parameters) * Interpreter::stackElementWords(); |
2513 return (callee_locals - callee_parameters) * Interpreter::stackElementWords; |
2539 } |
2514 } |
2540 |
2515 |
2541 |
2516 |
2542 uint SharedRuntime::out_preserve_stack_slots() { |
2517 uint SharedRuntime::out_preserve_stack_slots() { |
2543 return 0; |
2518 return 0; |