Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/assembler_x86.cpp @ 642:660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
Summary: Use zero based compressed oops if java heap is below 32gb and unscaled compressed oops if java heap is below 4gb.
Reviewed-by: never, twisti, jcoomes, coleenp
author | kvn |
---|---|
date | Thu, 12 Mar 2009 10:37:46 -0700 |
parents | 337400e7a5dd |
children | c771b7f43bbf |
comparison
equal
deleted
inserted
replaced
641:6af0a709d52b | 642:660978a2a31a |
---|---|
725 if (which == end_pc_operand) { | 725 if (which == end_pc_operand) { |
726 return ip + tail_size; | 726 return ip + tail_size; |
727 } | 727 } |
728 | 728 |
729 #ifdef _LP64 | 729 #ifdef _LP64 |
730 assert(false, "fix locate_operand"); | 730 assert(which == narrow_oop_operand && !is_64bit, "instruction is not a movl adr, imm32"); |
731 #else | 731 #else |
732 assert(which == imm_operand, "instruction has only an imm field"); | 732 assert(which == imm_operand, "instruction has only an imm field"); |
733 #endif // LP64 | 733 #endif // LP64 |
734 return ip; | 734 return ip; |
735 } | 735 } |
3222 void Assembler::fyl2x() { | 3222 void Assembler::fyl2x() { |
3223 emit_byte(0xD9); | 3223 emit_byte(0xD9); |
3224 emit_byte(0xF1); | 3224 emit_byte(0xF1); |
3225 } | 3225 } |
3226 | 3226 |
3227 void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format) { | |
3228 InstructionMark im(this); | |
3229 int encode = prefix_and_encode(dst->encoding()); | |
3230 emit_byte(0xB8 | encode); | |
3231 emit_data((int)imm32, rspec, format); | |
3232 } | |
3233 | 3227 |
3234 #ifndef _LP64 | 3228 #ifndef _LP64 |
3235 | 3229 |
3236 void Assembler::incl(Register dst) { | 3230 void Assembler::incl(Register dst) { |
3237 // Don't use it directly. Use MacroAssembler::incrementl() instead. | 3231 // Don't use it directly. Use MacroAssembler::incrementl() instead. |
3247 emit_byte(0xC7); | 3241 emit_byte(0xC7); |
3248 emit_operand(rax, dst); | 3242 emit_operand(rax, dst); |
3249 emit_data((int)imm32, rspec, 0); | 3243 emit_data((int)imm32, rspec, 0); |
3250 } | 3244 } |
3251 | 3245 |
3246 void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) { | |
3247 InstructionMark im(this); | |
3248 int encode = prefix_and_encode(dst->encoding()); | |
3249 emit_byte(0xB8 | encode); | |
3250 emit_data((int)imm32, rspec, 0); | |
3251 } | |
3252 | 3252 |
3253 void Assembler::popa() { // 32bit | 3253 void Assembler::popa() { // 32bit |
3254 emit_byte(0x61); | 3254 emit_byte(0x61); |
3255 } | 3255 } |
3256 | 3256 |
3853 void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { | 3853 void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { |
3854 InstructionMark im(this); | 3854 InstructionMark im(this); |
3855 int encode = prefixq_and_encode(dst->encoding()); | 3855 int encode = prefixq_and_encode(dst->encoding()); |
3856 emit_byte(0xB8 | encode); | 3856 emit_byte(0xB8 | encode); |
3857 emit_data64(imm64, rspec); | 3857 emit_data64(imm64, rspec); |
3858 } | |
3859 | |
3860 void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) { | |
3861 InstructionMark im(this); | |
3862 int encode = prefix_and_encode(dst->encoding()); | |
3863 emit_byte(0xB8 | encode); | |
3864 emit_data((int)imm32, rspec, narrow_oop_operand); | |
3865 } | |
3866 | |
3867 void Assembler::mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec) { | |
3868 InstructionMark im(this); | |
3869 prefix(dst); | |
3870 emit_byte(0xC7); | |
3871 emit_operand(rax, dst, 4); | |
3872 emit_data((int)imm32, rspec, narrow_oop_operand); | |
3873 } | |
3874 | |
3875 void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) { | |
3876 InstructionMark im(this); | |
3877 int encode = prefix_and_encode(src1->encoding()); | |
3878 emit_byte(0x81); | |
3879 emit_byte(0xF8 | encode); | |
3880 emit_data((int)imm32, rspec, narrow_oop_operand); | |
3881 } | |
3882 | |
3883 void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) { | |
3884 InstructionMark im(this); | |
3885 prefix(src1); | |
3886 emit_byte(0x81); | |
3887 emit_operand(rax, src1, 4); | |
3888 emit_data((int)imm32, rspec, narrow_oop_operand); | |
3858 } | 3889 } |
3859 | 3890 |
3860 void Assembler::movdq(XMMRegister dst, Register src) { | 3891 void Assembler::movdq(XMMRegister dst, Register src) { |
3861 // table D-1 says MMX/SSE2 | 3892 // table D-1 says MMX/SSE2 |
3862 NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), "")); | 3893 NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), "")); |
7708 } | 7739 } |
7709 | 7740 |
7710 void MacroAssembler::load_prototype_header(Register dst, Register src) { | 7741 void MacroAssembler::load_prototype_header(Register dst, Register src) { |
7711 #ifdef _LP64 | 7742 #ifdef _LP64 |
7712 if (UseCompressedOops) { | 7743 if (UseCompressedOops) { |
7744 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7713 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 7745 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
7714 movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); | 7746 if (Universe::narrow_oop_shift() != 0) { |
7747 assert(Address::times_8 == LogMinObjAlignmentInBytes && | |
7748 Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7749 movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); | |
7750 } else { | |
7751 movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); | |
7752 } | |
7715 } else | 7753 } else |
7716 #endif | 7754 #endif |
7717 { | 7755 { |
7718 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 7756 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
7719 movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); | 7757 movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); |
7720 } | 7758 } |
7721 } | 7759 } |
7722 | 7760 |
7723 void MacroAssembler::store_klass(Register dst, Register src) { | 7761 void MacroAssembler::store_klass(Register dst, Register src) { |
7724 #ifdef _LP64 | 7762 #ifdef _LP64 |
7725 if (UseCompressedOops) { | 7763 if (UseCompressedOops) { |
7758 } | 7796 } |
7759 | 7797 |
7760 // Algorithm must match oop.inline.hpp encode_heap_oop. | 7798 // Algorithm must match oop.inline.hpp encode_heap_oop. |
7761 void MacroAssembler::encode_heap_oop(Register r) { | 7799 void MacroAssembler::encode_heap_oop(Register r) { |
7762 assert (UseCompressedOops, "should be compressed"); | 7800 assert (UseCompressedOops, "should be compressed"); |
7801 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7802 if (Universe::narrow_oop_base() == NULL) { | |
7803 verify_oop(r, "broken oop in encode_heap_oop"); | |
7804 if (Universe::narrow_oop_shift() != 0) { | |
7805 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7806 shrq(r, LogMinObjAlignmentInBytes); | |
7807 } | |
7808 return; | |
7809 } | |
7763 #ifdef ASSERT | 7810 #ifdef ASSERT |
7764 if (CheckCompressedOops) { | 7811 if (CheckCompressedOops) { |
7765 Label ok; | 7812 Label ok; |
7766 push(rscratch1); // cmpptr trashes rscratch1 | 7813 push(rscratch1); // cmpptr trashes rscratch1 |
7767 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); | 7814 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); |
7768 jcc(Assembler::equal, ok); | 7815 jcc(Assembler::equal, ok); |
7769 stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); | 7816 stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); |
7770 bind(ok); | 7817 bind(ok); |
7771 pop(rscratch1); | 7818 pop(rscratch1); |
7772 } | 7819 } |
7778 shrq(r, LogMinObjAlignmentInBytes); | 7825 shrq(r, LogMinObjAlignmentInBytes); |
7779 } | 7826 } |
7780 | 7827 |
7781 void MacroAssembler::encode_heap_oop_not_null(Register r) { | 7828 void MacroAssembler::encode_heap_oop_not_null(Register r) { |
7782 assert (UseCompressedOops, "should be compressed"); | 7829 assert (UseCompressedOops, "should be compressed"); |
7830 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7783 #ifdef ASSERT | 7831 #ifdef ASSERT |
7784 if (CheckCompressedOops) { | 7832 if (CheckCompressedOops) { |
7785 Label ok; | 7833 Label ok; |
7786 testq(r, r); | 7834 testq(r, r); |
7787 jcc(Assembler::notEqual, ok); | 7835 jcc(Assembler::notEqual, ok); |
7788 stop("null oop passed to encode_heap_oop_not_null"); | 7836 stop("null oop passed to encode_heap_oop_not_null"); |
7789 bind(ok); | 7837 bind(ok); |
7790 } | 7838 } |
7791 #endif | 7839 #endif |
7792 verify_oop(r, "broken oop in encode_heap_oop_not_null"); | 7840 verify_oop(r, "broken oop in encode_heap_oop_not_null"); |
7793 subq(r, r12_heapbase); | 7841 if (Universe::narrow_oop_base() != NULL) { |
7794 shrq(r, LogMinObjAlignmentInBytes); | 7842 subq(r, r12_heapbase); |
7843 } | |
7844 if (Universe::narrow_oop_shift() != 0) { | |
7845 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7846 shrq(r, LogMinObjAlignmentInBytes); | |
7847 } | |
7795 } | 7848 } |
7796 | 7849 |
7797 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { | 7850 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { |
7798 assert (UseCompressedOops, "should be compressed"); | 7851 assert (UseCompressedOops, "should be compressed"); |
7852 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7799 #ifdef ASSERT | 7853 #ifdef ASSERT |
7800 if (CheckCompressedOops) { | 7854 if (CheckCompressedOops) { |
7801 Label ok; | 7855 Label ok; |
7802 testq(src, src); | 7856 testq(src, src); |
7803 jcc(Assembler::notEqual, ok); | 7857 jcc(Assembler::notEqual, ok); |
7807 #endif | 7861 #endif |
7808 verify_oop(src, "broken oop in encode_heap_oop_not_null2"); | 7862 verify_oop(src, "broken oop in encode_heap_oop_not_null2"); |
7809 if (dst != src) { | 7863 if (dst != src) { |
7810 movq(dst, src); | 7864 movq(dst, src); |
7811 } | 7865 } |
7812 subq(dst, r12_heapbase); | 7866 if (Universe::narrow_oop_base() != NULL) { |
7813 shrq(dst, LogMinObjAlignmentInBytes); | 7867 subq(dst, r12_heapbase); |
7868 } | |
7869 if (Universe::narrow_oop_shift() != 0) { | |
7870 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7871 shrq(dst, LogMinObjAlignmentInBytes); | |
7872 } | |
7814 } | 7873 } |
7815 | 7874 |
7816 void MacroAssembler::decode_heap_oop(Register r) { | 7875 void MacroAssembler::decode_heap_oop(Register r) { |
7817 assert (UseCompressedOops, "should be compressed"); | 7876 assert (UseCompressedOops, "should be compressed"); |
7877 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7878 if (Universe::narrow_oop_base() == NULL) { | |
7879 if (Universe::narrow_oop_shift() != 0) { | |
7880 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7881 shlq(r, LogMinObjAlignmentInBytes); | |
7882 } | |
7883 verify_oop(r, "broken oop in decode_heap_oop"); | |
7884 return; | |
7885 } | |
7818 #ifdef ASSERT | 7886 #ifdef ASSERT |
7819 if (CheckCompressedOops) { | 7887 if (CheckCompressedOops) { |
7820 Label ok; | 7888 Label ok; |
7821 push(rscratch1); | 7889 push(rscratch1); |
7822 cmpptr(r12_heapbase, | 7890 cmpptr(r12_heapbase, |
7823 ExternalAddress((address)Universe::heap_base_addr())); | 7891 ExternalAddress((address)Universe::narrow_oop_base_addr())); |
7824 jcc(Assembler::equal, ok); | 7892 jcc(Assembler::equal, ok); |
7825 stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); | 7893 stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); |
7826 bind(ok); | 7894 bind(ok); |
7827 pop(rscratch1); | 7895 pop(rscratch1); |
7828 } | 7896 } |
7842 verify_oop(r, "broken oop in decode_heap_oop"); | 7910 verify_oop(r, "broken oop in decode_heap_oop"); |
7843 } | 7911 } |
7844 | 7912 |
7845 void MacroAssembler::decode_heap_oop_not_null(Register r) { | 7913 void MacroAssembler::decode_heap_oop_not_null(Register r) { |
7846 assert (UseCompressedOops, "should only be used for compressed headers"); | 7914 assert (UseCompressedOops, "should only be used for compressed headers"); |
7915 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7847 // Cannot assert, unverified entry point counts instructions (see .ad file) | 7916 // Cannot assert, unverified entry point counts instructions (see .ad file) |
7848 // vtableStubs also counts instructions in pd_code_size_limit. | 7917 // vtableStubs also counts instructions in pd_code_size_limit. |
7849 // Also do not verify_oop as this is called by verify_oop. | 7918 // Also do not verify_oop as this is called by verify_oop. |
7850 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); | 7919 if (Universe::narrow_oop_base() == NULL) { |
7851 leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); | 7920 if (Universe::narrow_oop_shift() != 0) { |
7921 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7922 shlq(r, LogMinObjAlignmentInBytes); | |
7923 } | |
7924 } else { | |
7925 assert (Address::times_8 == LogMinObjAlignmentInBytes && | |
7926 Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7927 leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); | |
7928 } | |
7852 } | 7929 } |
7853 | 7930 |
7854 void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { | 7931 void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { |
7855 assert (UseCompressedOops, "should only be used for compressed headers"); | 7932 assert (UseCompressedOops, "should only be used for compressed headers"); |
7933 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7856 // Cannot assert, unverified entry point counts instructions (see .ad file) | 7934 // Cannot assert, unverified entry point counts instructions (see .ad file) |
7857 // vtableStubs also counts instructions in pd_code_size_limit. | 7935 // vtableStubs also counts instructions in pd_code_size_limit. |
7858 // Also do not verify_oop as this is called by verify_oop. | 7936 // Also do not verify_oop as this is called by verify_oop. |
7859 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); | 7937 if (Universe::narrow_oop_shift() != 0) { |
7860 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); | 7938 assert (Address::times_8 == LogMinObjAlignmentInBytes && |
7939 Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong"); | |
7940 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); | |
7941 } else if (dst != src) { | |
7942 movq(dst, src); | |
7943 } | |
7861 } | 7944 } |
7862 | 7945 |
7863 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { | 7946 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { |
7864 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 7947 assert (UseCompressedOops, "should only be used for compressed headers"); |
7948 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7949 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | |
7865 int oop_index = oop_recorder()->find_index(obj); | 7950 int oop_index = oop_recorder()->find_index(obj); |
7866 RelocationHolder rspec = oop_Relocation::spec(oop_index); | 7951 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
7867 mov_literal32(dst, oop_index, rspec, narrow_oop_operand); | 7952 mov_narrow_oop(dst, oop_index, rspec); |
7953 } | |
7954 | |
7955 void MacroAssembler::set_narrow_oop(Address dst, jobject obj) { | |
7956 assert (UseCompressedOops, "should only be used for compressed headers"); | |
7957 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7958 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | |
7959 int oop_index = oop_recorder()->find_index(obj); | |
7960 RelocationHolder rspec = oop_Relocation::spec(oop_index); | |
7961 mov_narrow_oop(dst, oop_index, rspec); | |
7962 } | |
7963 | |
7964 void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) { | |
7965 assert (UseCompressedOops, "should only be used for compressed headers"); | |
7966 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7967 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | |
7968 int oop_index = oop_recorder()->find_index(obj); | |
7969 RelocationHolder rspec = oop_Relocation::spec(oop_index); | |
7970 Assembler::cmp_narrow_oop(dst, oop_index, rspec); | |
7971 } | |
7972 | |
7973 void MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) { | |
7974 assert (UseCompressedOops, "should only be used for compressed headers"); | |
7975 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
7976 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | |
7977 int oop_index = oop_recorder()->find_index(obj); | |
7978 RelocationHolder rspec = oop_Relocation::spec(oop_index); | |
7979 Assembler::cmp_narrow_oop(dst, oop_index, rspec); | |
7868 } | 7980 } |
7869 | 7981 |
7870 void MacroAssembler::reinit_heapbase() { | 7982 void MacroAssembler::reinit_heapbase() { |
7871 if (UseCompressedOops) { | 7983 if (UseCompressedOops) { |
7872 movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); | 7984 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); |
7873 } | 7985 } |
7874 } | 7986 } |
7875 #endif // _LP64 | 7987 #endif // _LP64 |
7876 | 7988 |
7877 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { | 7989 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { |