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) {