comparison src/share/vm/graal/graalCodeInstaller.cpp @ 5000:b5dc2403c1e7

add option to inline VTable stubs
author Lukas Stadler <lukas.stadler@jku.at>
date Thu, 01 Mar 2012 12:11:19 +0100
parents e29339f342de
children 9ec2917fd0de 51111665eda6
comparison
equal deleted inserted replaced
4999:71bcf0a9e875 5000:b5dc2403c1e7
603 603
604 assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); 604 assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type");
605 605
606 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); 606 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
607 jint next_pc_offset = 0x0; 607 jint next_pc_offset = 0x0;
608 bool is_call_reg = false;
608 if (inst->is_call() || inst->is_jump()) { 609 if (inst->is_call() || inst->is_jump()) {
609 assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); 610 assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
610 next_pc_offset = pc_offset + NativeCall::instruction_size; 611 next_pc_offset = pc_offset + NativeCall::instruction_size;
611 } else if (inst->is_mov_literal64()) { 612 } else if (inst->is_mov_literal64()) {
612 // mov+call instruction pair 613 // mov+call instruction pair
613 next_pc_offset = pc_offset + NativeMovConstReg::instruction_size; 614 next_pc_offset = pc_offset + NativeMovConstReg::instruction_size;
614 u_char* call = (u_char*) (_instructions->start() + next_pc_offset); 615 u_char* call = (u_char*) (_instructions->start() + next_pc_offset);
615 assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); 616 assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
616 next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */ 617 next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */
618 } else if (inst->is_call_reg()) {
619 // the inlined vtable stub contains a "call register" instruction, which isn't recognized here
620 assert(hotspot_method != NULL, "only valid for virtual calls");
621 is_call_reg = true;
622 next_pc_offset = pc_offset + NativeCallReg::instruction_size;
617 } else { 623 } else {
618 runtime_call->print(); 624 runtime_call->print();
619 fatal("unsupported type of instruction for call site"); 625 fatal("unsupported type of instruction for call site");
620 } 626 }
621 627
663 nativeJump_at((address)inst)->set_jump_destination(VmIds::getStub(global_stub)); 669 nativeJump_at((address)inst)->set_jump_destination(VmIds::getStub(global_stub));
664 } 670 }
665 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); 671 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
666 TRACE_graal_3("relocating (stub) at %016x", inst); 672 TRACE_graal_3("relocating (stub) at %016x", inst);
667 } else { // method != NULL 673 } else { // method != NULL
668 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
669 assert(hotspot_method != NULL, "unexpected RiMethod"); 674 assert(hotspot_method != NULL, "unexpected RiMethod");
670 assert(debug_info != NULL, "debug info expected"); 675 assert(debug_info != NULL, "debug info expected");
671 676
672 methodOop method = NULL; 677 methodOop method = NULL;
673 // we need to check, this might also be an unresolved method 678 // we need to check, this might also be an unresolved method
678 assert(debug_info != NULL, "debug info expected"); 683 assert(debug_info != NULL, "debug info expected");
679 684
680 TRACE_graal_3("method call"); 685 TRACE_graal_3("method call");
681 switch (_next_call_type) { 686 switch (_next_call_type) {
682 case MARK_INVOKEVIRTUAL: 687 case MARK_INVOKEVIRTUAL:
688 if (is_call_reg) {
689 break;
690 }
683 case MARK_INVOKEINTERFACE: { 691 case MARK_INVOKEINTERFACE: {
684 assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); 692 assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
685 693
694 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
686 call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); 695 call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
687 _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); 696 _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
688 break; 697 break;
689 } 698 }
690 case MARK_INVOKESTATIC: { 699 case MARK_INVOKESTATIC: {
691 assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); 700 assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
692 701
702 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
693 call->set_destination(SharedRuntime::get_resolve_static_call_stub()); 703 call->set_destination(SharedRuntime::get_resolve_static_call_stub());
694 _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); 704 _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand);
695 break; 705 break;
696 } 706 }
697 case MARK_INVOKESPECIAL: { 707 case MARK_INVOKESPECIAL: {
698 assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); 708 assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
699 709
710 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
700 call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); 711 call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
701 _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); 712 _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand);
702 break; 713 break;
703 } 714 }
704 case MARK_INVOKE_INVALID: 715 case MARK_INVOKE_INVALID: