Mercurial > hg > truffle
comparison src/share/vm/graal/graalCodeInstaller.cpp @ 9983:13384d19fec0
Merge
author | Christos Kotselidis <christos.kotselidis@oracle.com> |
---|---|
date | Tue, 11 Jun 2013 00:00:40 +0200 |
parents | 91c16dff3fc1 0f7ca53be929 |
children | 9062da84cd75 |
comparison
equal
deleted
inserted
replaced
9982:06e176eff527 | 9983:13384d19fec0 |
---|---|
33 #include "asm/register.hpp" | 33 #include "asm/register.hpp" |
34 #include "classfile/vmSymbols.hpp" | 34 #include "classfile/vmSymbols.hpp" |
35 #include "code/vmreg.hpp" | 35 #include "code/vmreg.hpp" |
36 | 36 |
37 #ifdef TARGET_ARCH_x86 | 37 #ifdef TARGET_ARCH_x86 |
38 # include "codeInstaller_x86.hpp" | |
38 # include "vmreg_x86.inline.hpp" | 39 # include "vmreg_x86.inline.hpp" |
39 #endif | 40 #endif |
40 #ifdef TARGET_ARCH_sparc | 41 #ifdef TARGET_ARCH_sparc |
42 # include "codeInstaller_sparc.hpp" | |
41 # include "vmreg_sparc.inline.hpp" | 43 # include "vmreg_sparc.inline.hpp" |
42 #endif | 44 #endif |
43 #ifdef TARGET_ARCH_zero | 45 #ifdef TARGET_ARCH_zero |
46 # include "codeInstaller_zero.hpp" | |
44 # include "vmreg_zero.inline.hpp" | 47 # include "vmreg_zero.inline.hpp" |
45 #endif | 48 #endif |
46 #ifdef TARGET_ARCH_arm | 49 #ifdef TARGET_ARCH_arm |
50 # include "codeInstaller_arm.hpp" | |
47 # include "vmreg_arm.inline.hpp" | 51 # include "vmreg_arm.inline.hpp" |
48 #endif | 52 #endif |
49 #ifdef TARGET_ARCH_ppc | 53 #ifdef TARGET_ARCH_ppc |
54 # include "codeInstaller_ppc.hpp" | |
50 # include "vmreg_ppc.inline.hpp" | 55 # include "vmreg_ppc.inline.hpp" |
51 #endif | 56 #endif |
52 | 57 |
53 // convert Graal register indices (as used in oop maps) to HotSpot registers | 58 // convert Graal register indices (as used in oop maps) to HotSpot registers |
54 VMReg get_hotspot_reg(jint graal_reg) { | 59 VMReg get_hotspot_reg(jint graal_reg) { |
197 if (type == T_DOUBLE) { | 202 if (type == T_DOUBLE) { |
198 second = value; | 203 second = value; |
199 } | 204 } |
200 return value; | 205 return value; |
201 #else | 206 #else |
207 #ifdef TARGET_ARCH_sparc | |
208 ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(number)->as_VMReg())); | |
209 if (type == T_DOUBLE) { | |
210 second = value; | |
211 } | |
212 return value; | |
213 #else | |
202 ShouldNotReachHere("Platform currently does not support floating point values."); | 214 ShouldNotReachHere("Platform currently does not support floating point values."); |
215 #endif | |
203 #endif | 216 #endif |
204 } | 217 } |
205 } else if (value->is_a(StackSlot::klass())) { | 218 } else if (value->is_a(StackSlot::klass())) { |
206 if (type == T_DOUBLE) { | 219 if (type == T_DOUBLE) { |
207 locationType = Location::dbl; | 220 locationType = Location::dbl; |
672 oop debug_info = CompilationResult_Call::debugInfo(site); | 685 oop debug_info = CompilationResult_Call::debugInfo(site); |
673 | 686 |
674 assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type"); | 687 assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type"); |
675 | 688 |
676 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); | 689 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); |
677 jint next_pc_offset = 0x0; | 690 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); |
678 if (inst->is_call() || inst->is_jump()) { | 691 |
679 assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); | |
680 next_pc_offset = pc_offset + NativeCall::instruction_size; | |
681 } else if (inst->is_mov_literal64()) { | |
682 // mov+call instruction pair | |
683 next_pc_offset = pc_offset + NativeMovConstReg::instruction_size; | |
684 u_char* call = (u_char*) (_instructions->start() + next_pc_offset); | |
685 assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); | |
686 next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */ | |
687 } else if (inst->is_call_reg()) { | |
688 // the inlined vtable stub contains a "call register" instruction | |
689 assert(hotspot_method != NULL, "only valid for virtual calls"); | |
690 next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset(); | |
691 } else { | |
692 fatal("unsupported type of instruction for call site"); | |
693 } | |
694 | |
695 if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) { | 692 if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) { |
696 assert(inst->is_jump(), "jump expected"); | 693 assert(inst->is_jump(), "jump expected"); |
697 | 694 |
698 CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target); | 695 CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target); |
699 assert(cb != NULL, "npe"); | 696 assert(cb != NULL, "npe"); |
700 if (cb->is_nmethod()) { | 697 |
701 nmethod* nm = (nmethod*) cb; | 698 CodeInstaller::pd_relocate_CodeBlob(cb, inst); |
702 nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); | |
703 } else { | |
704 nativeJump_at((address)inst)->set_jump_destination(cb->code_begin()); | |
705 } | |
706 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); | |
707 | 699 |
708 return; | 700 return; |
709 } | 701 } |
710 | 702 |
711 if (debug_info != NULL) { | 703 if (debug_info != NULL) { |
718 } | 710 } |
719 } | 711 } |
720 | 712 |
721 if (foreign_call != NULL) { | 713 if (foreign_call != NULL) { |
722 jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call); | 714 jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call); |
723 if (inst->is_call()) { | 715 |
724 // NOTE: for call without a mov, the offset must fit a 32-bit immediate | 716 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination); |
725 // see also CompilerToVM.getMaxCallTargetOffset() | |
726 NativeCall* call = nativeCall_at((address) (inst)); | |
727 call->set_destination((address) foreign_call_destination); | |
728 _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); | |
729 } else if (inst->is_mov_literal64()) { | |
730 NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst)); | |
731 mov->set_data((intptr_t) foreign_call_destination); | |
732 _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); | |
733 } else { | |
734 NativeJump* jump = nativeJump_at((address) (inst)); | |
735 jump->set_jump_destination((address) foreign_call_destination); | |
736 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); | |
737 } | |
738 TRACE_graal_3("relocating (foreign call) at %p", inst); | |
739 } else { // method != NULL | 717 } else { // method != NULL |
740 assert(hotspot_method != NULL, "unexpected JavaMethod"); | 718 assert(hotspot_method != NULL, "unexpected JavaMethod"); |
741 #ifdef ASSERT | |
742 Method* method = NULL; | |
743 // we need to check, this might also be an unresolved method | |
744 if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { | |
745 method = getMethodFromHotSpotMethod(hotspot_method); | |
746 } | |
747 #endif | |
748 assert(debug_info != NULL, "debug info expected"); | 719 assert(debug_info != NULL, "debug info expected"); |
749 | 720 |
750 TRACE_graal_3("method call"); | 721 TRACE_graal_3("method call"); |
751 switch (_next_call_type) { | 722 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); |
752 case MARK_INLINE_INVOKE: | |
753 break; | |
754 case MARK_INVOKEVIRTUAL: | |
755 case MARK_INVOKEINTERFACE: { | |
756 assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); | |
757 | |
758 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | |
759 call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); | |
760 _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); | |
761 break; | |
762 } | |
763 case MARK_INVOKESTATIC: { | |
764 assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); | |
765 | |
766 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | |
767 call->set_destination(SharedRuntime::get_resolve_static_call_stub()); | |
768 _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); | |
769 break; | |
770 } | |
771 case MARK_INVOKESPECIAL: { | |
772 assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); | |
773 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | |
774 call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); | |
775 _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); | |
776 break; | |
777 } | |
778 default: | |
779 fatal("invalid _next_call_type value"); | |
780 break; | |
781 } | |
782 } | 723 } |
783 _next_call_type = MARK_INVOKE_INVALID; | 724 _next_call_type = MARK_INVOKE_INVALID; |
784 if (debug_info != NULL) { | 725 if (debug_info != NULL) { |
785 _debug_recorder->end_safepoint(next_pc_offset); | 726 _debug_recorder->end_safepoint(next_pc_offset); |
786 } | 727 } |
791 int alignment = CompilationResult_DataPatch::alignment(site); | 732 int alignment = CompilationResult_DataPatch::alignment(site); |
792 bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; | 733 bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; |
793 oop kind = Constant::kind(constant); | 734 oop kind = Constant::kind(constant); |
794 | 735 |
795 address instruction = _instructions->start() + pc_offset; | 736 address instruction = _instructions->start() + pc_offset; |
796 | |
797 char typeChar = Kind::typeChar(kind); | 737 char typeChar = Kind::typeChar(kind); |
798 switch (typeChar) { | 738 switch (typeChar) { |
799 case 'z': | |
800 case 'b': | |
801 case 's': | |
802 case 'c': | |
803 case 'i': | |
804 fatal("int-sized values not expected in DataPatch"); | |
805 break; | |
806 case 'f': | 739 case 'f': |
807 case 'j': | 740 case 'j': |
808 case 'd': { | 741 case 'd': |
809 record_metadata_in_constant(constant, _oop_recorder); | 742 record_metadata_in_constant(constant, _oop_recorder); |
810 if (inlined) { | |
811 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | |
812 *((jlong*) operand) = Constant::primitive(constant); | |
813 } else { | |
814 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); | |
815 address next_instruction = Assembler::locate_next_instruction(instruction); | |
816 int size = _constants->size(); | |
817 if (alignment > 0) { | |
818 guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); | |
819 size = align_size_up(size, alignment); | |
820 } | |
821 // we don't care if this is a long/double/etc., the primitive field contains the right bits | |
822 address dest = _constants->start() + size; | |
823 _constants->set_end(dest + BytesPerLong); | |
824 *(jlong*) dest = Constant::primitive(constant); | |
825 | |
826 long disp = dest - next_instruction; | |
827 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); | |
828 *((jint*) operand) = (jint) disp; | |
829 | |
830 _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); | |
831 TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); | |
832 } | |
833 break; | 743 break; |
834 } | 744 } |
835 case 'a': { | 745 CodeInstaller::pd_site_DataPatch(constant, kind, inlined, instruction, alignment, typeChar); |
836 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | |
837 Handle obj = Constant::object(constant); | |
838 | |
839 jobject value = JNIHandles::make_local(obj()); | |
840 *((jobject*) operand) = value; | |
841 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | |
842 TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); | |
843 break; | |
844 } | |
845 default: | |
846 fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); | |
847 break; | |
848 } | |
849 } | 746 } |
850 | 747 |
851 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { | 748 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { |
852 oop id_obj = CompilationResult_Mark::id(site); | 749 oop id_obj = CompilationResult_Mark::id(site); |
853 arrayOop references = (arrayOop) CompilationResult_Mark::references(site); | 750 arrayOop references = (arrayOop) CompilationResult_Mark::references(site); |
888 _next_call_type = (MarkId) id; | 785 _next_call_type = (MarkId) id; |
889 _invoke_mark_pc = instruction; | 786 _invoke_mark_pc = instruction; |
890 break; | 787 break; |
891 case MARK_POLL_NEAR: { | 788 case MARK_POLL_NEAR: { |
892 NativeInstruction* ni = nativeInstruction_at(instruction); | 789 NativeInstruction* ni = nativeInstruction_at(instruction); |
893 int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | 790 int32_t* disp = (int32_t*) pd_locate_operand(instruction); |
791 // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | |
894 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand | 792 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand |
895 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; | 793 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; |
896 *disp = (int32_t)new_disp; | 794 *disp = (int32_t)new_disp; |
897 } | 795 } |
898 case MARK_POLL_FAR: | 796 case MARK_POLL_FAR: |
899 _instructions->relocate(instruction, relocInfo::poll_type); | 797 _instructions->relocate(instruction, relocInfo::poll_type); |
900 break; | 798 break; |
901 case MARK_POLL_RETURN_NEAR: { | 799 case MARK_POLL_RETURN_NEAR: { |
902 NativeInstruction* ni = nativeInstruction_at(instruction); | 800 NativeInstruction* ni = nativeInstruction_at(instruction); |
903 int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | 801 int32_t* disp = (int32_t*) pd_locate_operand(instruction); |
802 // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | |
904 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand | 803 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand |
905 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; | 804 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; |
906 *disp = (int32_t)new_disp; | 805 *disp = (int32_t)new_disp; |
907 } | 806 } |
908 case MARK_POLL_RETURN_FAR: | 807 case MARK_POLL_RETURN_FAR: |