Mercurial > hg > graal-compiler
comparison src/share/vm/graal/graalCodeInstaller.cpp @ 9934:0f7ca53be929
CR-806: Changes to build Graal for SPARC
author | Morris Meyer <morris.meyer@oracle.com> |
---|---|
date | Fri, 07 Jun 2013 15:43:00 -0400 |
parents | 558c73d8bdc0 |
children | 13384d19fec0 |
comparison
equal
deleted
inserted
replaced
9933:78a1232be418 | 9934:0f7ca53be929 |
---|---|
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; |
702 oop debug_info = CompilationResult_Call::debugInfo(site); | 715 oop debug_info = CompilationResult_Call::debugInfo(site); |
703 | 716 |
704 assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type"); | 717 assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type"); |
705 | 718 |
706 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); | 719 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); |
707 jint next_pc_offset = 0x0; | 720 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); |
708 if (inst->is_call() || inst->is_jump()) { | 721 |
709 assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); | |
710 next_pc_offset = pc_offset + NativeCall::instruction_size; | |
711 } else if (inst->is_mov_literal64()) { | |
712 // mov+call instruction pair | |
713 next_pc_offset = pc_offset + NativeMovConstReg::instruction_size; | |
714 u_char* call = (u_char*) (_instructions->start() + next_pc_offset); | |
715 assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); | |
716 next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */ | |
717 } else if (inst->is_call_reg()) { | |
718 // the inlined vtable stub contains a "call register" instruction | |
719 assert(hotspot_method != NULL, "only valid for virtual calls"); | |
720 next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset(); | |
721 } else { | |
722 fatal("unsupported type of instruction for call site"); | |
723 } | |
724 | |
725 if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) { | 722 if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) { |
726 assert(inst->is_jump(), "jump expected"); | 723 assert(inst->is_jump(), "jump expected"); |
727 | 724 |
728 CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target); | 725 CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target); |
729 assert(cb != NULL, "npe"); | 726 assert(cb != NULL, "npe"); |
730 if (cb->is_nmethod()) { | 727 |
731 nmethod* nm = (nmethod*) cb; | 728 CodeInstaller::pd_relocate_CodeBlob(cb, inst); |
732 nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); | |
733 } else { | |
734 nativeJump_at((address)inst)->set_jump_destination(cb->code_begin()); | |
735 } | |
736 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); | |
737 | 729 |
738 return; | 730 return; |
739 } | 731 } |
740 | 732 |
741 if (debug_info != NULL) { | 733 if (debug_info != NULL) { |
748 } | 740 } |
749 } | 741 } |
750 | 742 |
751 if (foreign_call != NULL) { | 743 if (foreign_call != NULL) { |
752 jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call); | 744 jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call); |
753 if (inst->is_call()) { | 745 |
754 // NOTE: for call without a mov, the offset must fit a 32-bit immediate | 746 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination); |
755 // see also CompilerToVM.getMaxCallTargetOffset() | |
756 NativeCall* call = nativeCall_at((address) (inst)); | |
757 call->set_destination((address) foreign_call_destination); | |
758 _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); | |
759 } else if (inst->is_mov_literal64()) { | |
760 NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst)); | |
761 mov->set_data((intptr_t) foreign_call_destination); | |
762 _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); | |
763 } else { | |
764 NativeJump* jump = nativeJump_at((address) (inst)); | |
765 jump->set_jump_destination((address) foreign_call_destination); | |
766 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); | |
767 } | |
768 TRACE_graal_3("relocating (foreign call) at %p", inst); | |
769 } else { // method != NULL | 747 } else { // method != NULL |
770 assert(hotspot_method != NULL, "unexpected JavaMethod"); | 748 assert(hotspot_method != NULL, "unexpected JavaMethod"); |
771 #ifdef ASSERT | |
772 Method* method = NULL; | |
773 // we need to check, this might also be an unresolved method | |
774 if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { | |
775 method = getMethodFromHotSpotMethod(hotspot_method); | |
776 } | |
777 #endif | |
778 assert(debug_info != NULL, "debug info expected"); | 749 assert(debug_info != NULL, "debug info expected"); |
779 | 750 |
780 TRACE_graal_3("method call"); | 751 TRACE_graal_3("method call"); |
781 switch (_next_call_type) { | 752 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); |
782 case MARK_INLINE_INVOKE: | |
783 break; | |
784 case MARK_INVOKEVIRTUAL: | |
785 case MARK_INVOKEINTERFACE: { | |
786 assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); | |
787 | |
788 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | |
789 call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); | |
790 _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); | |
791 break; | |
792 } | |
793 case MARK_INVOKESTATIC: { | |
794 assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); | |
795 | |
796 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | |
797 call->set_destination(SharedRuntime::get_resolve_static_call_stub()); | |
798 _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); | |
799 break; | |
800 } | |
801 case MARK_INVOKESPECIAL: { | |
802 assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); | |
803 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | |
804 call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); | |
805 _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); | |
806 break; | |
807 } | |
808 default: | |
809 fatal("invalid _next_call_type value"); | |
810 break; | |
811 } | |
812 } | 753 } |
813 _next_call_type = MARK_INVOKE_INVALID; | 754 _next_call_type = MARK_INVOKE_INVALID; |
814 if (debug_info != NULL) { | 755 if (debug_info != NULL) { |
815 _debug_recorder->end_safepoint(next_pc_offset); | 756 _debug_recorder->end_safepoint(next_pc_offset); |
816 } | 757 } |
821 int alignment = CompilationResult_DataPatch::alignment(site); | 762 int alignment = CompilationResult_DataPatch::alignment(site); |
822 bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; | 763 bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; |
823 oop kind = Constant::kind(constant); | 764 oop kind = Constant::kind(constant); |
824 | 765 |
825 address instruction = _instructions->start() + pc_offset; | 766 address instruction = _instructions->start() + pc_offset; |
826 | |
827 char typeChar = Kind::typeChar(kind); | 767 char typeChar = Kind::typeChar(kind); |
828 switch (typeChar) { | 768 switch (typeChar) { |
829 case 'z': | |
830 case 'b': | |
831 case 's': | |
832 case 'c': | |
833 case 'i': | |
834 fatal("int-sized values not expected in DataPatch"); | |
835 break; | |
836 case 'f': | 769 case 'f': |
837 case 'j': | 770 case 'j': |
838 case 'd': { | 771 case 'd': |
839 record_metadata_in_constant(constant, _oop_recorder); | 772 record_metadata_in_constant(constant, _oop_recorder); |
840 if (inlined) { | |
841 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | |
842 *((jlong*) operand) = Constant::primitive(constant); | |
843 } else { | |
844 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); | |
845 address next_instruction = Assembler::locate_next_instruction(instruction); | |
846 int size = _constants->size(); | |
847 if (alignment > 0) { | |
848 guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); | |
849 size = align_size_up(size, alignment); | |
850 } | |
851 // we don't care if this is a long/double/etc., the primitive field contains the right bits | |
852 address dest = _constants->start() + size; | |
853 _constants->set_end(dest + BytesPerLong); | |
854 *(jlong*) dest = Constant::primitive(constant); | |
855 | |
856 long disp = dest - next_instruction; | |
857 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); | |
858 *((jint*) operand) = (jint) disp; | |
859 | |
860 _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); | |
861 TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); | |
862 } | |
863 break; | 773 break; |
864 } | 774 } |
865 case 'a': { | 775 CodeInstaller::pd_site_DataPatch(constant, kind, inlined, instruction, alignment, typeChar); |
866 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | |
867 Handle obj = Constant::object(constant); | |
868 | |
869 jobject value = JNIHandles::make_local(obj()); | |
870 *((jobject*) operand) = value; | |
871 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | |
872 TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); | |
873 break; | |
874 } | |
875 default: | |
876 fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); | |
877 break; | |
878 } | |
879 } | 776 } |
880 | 777 |
881 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { | 778 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { |
882 oop id_obj = CompilationResult_Mark::id(site); | 779 oop id_obj = CompilationResult_Mark::id(site); |
883 arrayOop references = (arrayOop) CompilationResult_Mark::references(site); | 780 arrayOop references = (arrayOop) CompilationResult_Mark::references(site); |
918 _next_call_type = (MarkId) id; | 815 _next_call_type = (MarkId) id; |
919 _invoke_mark_pc = instruction; | 816 _invoke_mark_pc = instruction; |
920 break; | 817 break; |
921 case MARK_POLL_NEAR: { | 818 case MARK_POLL_NEAR: { |
922 NativeInstruction* ni = nativeInstruction_at(instruction); | 819 NativeInstruction* ni = nativeInstruction_at(instruction); |
923 int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | 820 int32_t* disp = (int32_t*) pd_locate_operand(instruction); |
821 // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | |
924 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand | 822 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand |
925 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; | 823 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; |
926 *disp = (int32_t)new_disp; | 824 *disp = (int32_t)new_disp; |
927 } | 825 } |
928 case MARK_POLL_FAR: | 826 case MARK_POLL_FAR: |
929 _instructions->relocate(instruction, relocInfo::poll_type); | 827 _instructions->relocate(instruction, relocInfo::poll_type); |
930 break; | 828 break; |
931 case MARK_POLL_RETURN_NEAR: { | 829 case MARK_POLL_RETURN_NEAR: { |
932 NativeInstruction* ni = nativeInstruction_at(instruction); | 830 NativeInstruction* ni = nativeInstruction_at(instruction); |
933 int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | 831 int32_t* disp = (int32_t*) pd_locate_operand(instruction); |
832 // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); | |
934 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand | 833 int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand |
935 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; | 834 intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; |
936 *disp = (int32_t)new_disp; | 835 *disp = (int32_t)new_disp; |
937 } | 836 } |
938 case MARK_POLL_RETURN_FAR: | 837 case MARK_POLL_RETURN_FAR: |