Mercurial > hg > truffle
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: |