Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/macroAssembler_x86.cpp @ 14422:2b8e28fdf503
Merge
author | kvn |
---|---|
date | Tue, 05 Nov 2013 17:38:04 -0800 |
parents | 209aa13ab8c0 |
children | be525e91f65b |
comparison
equal
deleted
inserted
replaced
14421:3068270ba476 | 14422:2b8e28fdf503 |
---|---|
1633 assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); | 1633 assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); |
1634 LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); | 1634 LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); |
1635 #ifdef ASSERT | 1635 #ifdef ASSERT |
1636 // TraceBytecodes does not use r12 but saves it over the call, so don't verify | 1636 // TraceBytecodes does not use r12 but saves it over the call, so don't verify |
1637 // r12 is the heapbase. | 1637 // r12 is the heapbase. |
1638 LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) | 1638 LP64_ONLY(if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) |
1639 #endif // ASSERT | 1639 #endif // ASSERT |
1640 | 1640 |
1641 assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); | 1641 assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); |
1642 assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); | 1642 assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); |
1643 | 1643 |
3387 | 3387 |
3388 Address index(noreg, card_index, Address::times_1); | 3388 Address index(noreg, card_index, Address::times_1); |
3389 const Register card_addr = tmp; | 3389 const Register card_addr = tmp; |
3390 lea(card_addr, as_Address(ArrayAddress(cardtable, index))); | 3390 lea(card_addr, as_Address(ArrayAddress(cardtable, index))); |
3391 #endif | 3391 #endif |
3392 cmpb(Address(card_addr, 0), 0); | 3392 cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val()); |
3393 jcc(Assembler::equal, done); | 3393 jcc(Assembler::equal, done); |
3394 | |
3395 membar(Assembler::Membar_mask_bits(Assembler::StoreLoad)); | |
3396 cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val()); | |
3397 jcc(Assembler::equal, done); | |
3398 | |
3394 | 3399 |
3395 // storing a region crossing, non-NULL oop, card is clean. | 3400 // storing a region crossing, non-NULL oop, card is clean. |
3396 // dirty card and log. | 3401 // dirty card and log. |
3397 | 3402 |
3398 movb(Address(card_addr, 0), 0); | 3403 movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val()); |
3399 | 3404 |
3400 cmpl(queue_index, 0); | 3405 cmpl(queue_index, 0); |
3401 jcc(Assembler::equal, runtime); | 3406 jcc(Assembler::equal, runtime); |
3402 subl(queue_index, wordSize); | 3407 subl(queue_index, wordSize); |
3403 movptr(tmp2, buffer); | 3408 movptr(tmp2, buffer); |
4800 } | 4805 } |
4801 | 4806 |
4802 | 4807 |
4803 void MacroAssembler::load_klass(Register dst, Register src) { | 4808 void MacroAssembler::load_klass(Register dst, Register src) { |
4804 #ifdef _LP64 | 4809 #ifdef _LP64 |
4805 if (UseCompressedKlassPointers) { | 4810 if (UseCompressedClassPointers) { |
4806 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 4811 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
4807 decode_klass_not_null(dst); | 4812 decode_klass_not_null(dst); |
4808 } else | 4813 } else |
4809 #endif | 4814 #endif |
4810 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 4815 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
4815 movptr(dst, Address(dst, Klass::prototype_header_offset())); | 4820 movptr(dst, Address(dst, Klass::prototype_header_offset())); |
4816 } | 4821 } |
4817 | 4822 |
4818 void MacroAssembler::store_klass(Register dst, Register src) { | 4823 void MacroAssembler::store_klass(Register dst, Register src) { |
4819 #ifdef _LP64 | 4824 #ifdef _LP64 |
4820 if (UseCompressedKlassPointers) { | 4825 if (UseCompressedClassPointers) { |
4821 encode_klass_not_null(src); | 4826 encode_klass_not_null(src); |
4822 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); | 4827 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); |
4823 } else | 4828 } else |
4824 #endif | 4829 #endif |
4825 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); | 4830 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); |
4890 #endif | 4895 #endif |
4891 } | 4896 } |
4892 | 4897 |
4893 #ifdef _LP64 | 4898 #ifdef _LP64 |
4894 void MacroAssembler::store_klass_gap(Register dst, Register src) { | 4899 void MacroAssembler::store_klass_gap(Register dst, Register src) { |
4895 if (UseCompressedKlassPointers) { | 4900 if (UseCompressedClassPointers) { |
4896 // Store to klass gap in destination | 4901 // Store to klass gap in destination |
4897 movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); | 4902 movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); |
4898 } | 4903 } |
4899 } | 4904 } |
4900 | 4905 |
5042 } | 5047 } |
5043 } | 5048 } |
5044 } | 5049 } |
5045 | 5050 |
5046 void MacroAssembler::encode_klass_not_null(Register r) { | 5051 void MacroAssembler::encode_klass_not_null(Register r) { |
5047 assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); | 5052 if (Universe::narrow_klass_base() != NULL) { |
5048 // Use r12 as a scratch register in which to temporarily load the narrow_klass_base. | 5053 // Use r12 as a scratch register in which to temporarily load the narrow_klass_base. |
5049 assert(r != r12_heapbase, "Encoding a klass in r12"); | 5054 assert(r != r12_heapbase, "Encoding a klass in r12"); |
5050 mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base()); | 5055 mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base()); |
5051 subq(r, r12_heapbase); | 5056 subq(r, r12_heapbase); |
5057 } | |
5052 if (Universe::narrow_klass_shift() != 0) { | 5058 if (Universe::narrow_klass_shift() != 0) { |
5053 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5059 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5054 shrq(r, LogKlassAlignmentInBytes); | 5060 shrq(r, LogKlassAlignmentInBytes); |
5055 } | 5061 } |
5056 reinit_heapbase(); | 5062 if (Universe::narrow_klass_base() != NULL) { |
5063 reinit_heapbase(); | |
5064 } | |
5057 } | 5065 } |
5058 | 5066 |
5059 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { | 5067 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { |
5060 if (dst == src) { | 5068 if (dst == src) { |
5061 encode_klass_not_null(src); | 5069 encode_klass_not_null(src); |
5062 } else { | 5070 } else { |
5063 mov64(dst, (int64_t)Universe::narrow_klass_base()); | 5071 if (Universe::narrow_klass_base() != NULL) { |
5064 negq(dst); | 5072 mov64(dst, (int64_t)Universe::narrow_klass_base()); |
5065 addq(dst, src); | 5073 negq(dst); |
5074 addq(dst, src); | |
5075 } else { | |
5076 movptr(dst, src); | |
5077 } | |
5066 if (Universe::narrow_klass_shift() != 0) { | 5078 if (Universe::narrow_klass_shift() != 0) { |
5067 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5079 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5068 shrq(dst, LogKlassAlignmentInBytes); | 5080 shrq(dst, LogKlassAlignmentInBytes); |
5069 } | 5081 } |
5070 } | 5082 } |
5073 // Function instr_size_for_decode_klass_not_null() counts the instructions | 5085 // Function instr_size_for_decode_klass_not_null() counts the instructions |
5074 // generated by decode_klass_not_null(register r) and reinit_heapbase(), | 5086 // generated by decode_klass_not_null(register r) and reinit_heapbase(), |
5075 // when (Universe::heap() != NULL). Hence, if the instructions they | 5087 // when (Universe::heap() != NULL). Hence, if the instructions they |
5076 // generate change, then this method needs to be updated. | 5088 // generate change, then this method needs to be updated. |
5077 int MacroAssembler::instr_size_for_decode_klass_not_null() { | 5089 int MacroAssembler::instr_size_for_decode_klass_not_null() { |
5078 assert (UseCompressedKlassPointers, "only for compressed klass ptrs"); | 5090 assert (UseCompressedClassPointers, "only for compressed klass ptrs"); |
5079 // mov64 + addq + shlq? + mov64 (for reinit_heapbase()). | 5091 if (Universe::narrow_klass_base() != NULL) { |
5080 return (Universe::narrow_klass_shift() == 0 ? 20 : 24); | 5092 // mov64 + addq + shlq? + mov64 (for reinit_heapbase()). |
5093 return (Universe::narrow_klass_shift() == 0 ? 20 : 24); | |
5094 } else { | |
5095 // longest load decode klass function, mov64, leaq | |
5096 return 16; | |
5097 } | |
5081 } | 5098 } |
5082 | 5099 |
5083 // !!! If the instructions that get generated here change then function | 5100 // !!! If the instructions that get generated here change then function |
5084 // instr_size_for_decode_klass_not_null() needs to get updated. | 5101 // instr_size_for_decode_klass_not_null() needs to get updated. |
5085 void MacroAssembler::decode_klass_not_null(Register r) { | 5102 void MacroAssembler::decode_klass_not_null(Register r) { |
5086 // Note: it will change flags | 5103 // Note: it will change flags |
5087 assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); | 5104 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
5088 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | |
5089 assert(r != r12_heapbase, "Decoding a klass in r12"); | 5105 assert(r != r12_heapbase, "Decoding a klass in r12"); |
5090 // Cannot assert, unverified entry point counts instructions (see .ad file) | 5106 // Cannot assert, unverified entry point counts instructions (see .ad file) |
5091 // vtableStubs also counts instructions in pd_code_size_limit. | 5107 // vtableStubs also counts instructions in pd_code_size_limit. |
5092 // Also do not verify_oop as this is called by verify_oop. | 5108 // Also do not verify_oop as this is called by verify_oop. |
5093 if (Universe::narrow_klass_shift() != 0) { | 5109 if (Universe::narrow_klass_shift() != 0) { |
5094 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5110 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5095 shlq(r, LogKlassAlignmentInBytes); | 5111 shlq(r, LogKlassAlignmentInBytes); |
5096 } | 5112 } |
5097 // Use r12 as a scratch register in which to temporarily load the narrow_klass_base. | 5113 // Use r12 as a scratch register in which to temporarily load the narrow_klass_base. |
5098 mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base()); | 5114 if (Universe::narrow_klass_base() != NULL) { |
5099 addq(r, r12_heapbase); | 5115 mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base()); |
5100 reinit_heapbase(); | 5116 addq(r, r12_heapbase); |
5117 reinit_heapbase(); | |
5118 } | |
5101 } | 5119 } |
5102 | 5120 |
5103 void MacroAssembler::decode_klass_not_null(Register dst, Register src) { | 5121 void MacroAssembler::decode_klass_not_null(Register dst, Register src) { |
5104 // Note: it will change flags | 5122 // Note: it will change flags |
5105 assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); | 5123 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
5106 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | |
5107 if (dst == src) { | 5124 if (dst == src) { |
5108 decode_klass_not_null(dst); | 5125 decode_klass_not_null(dst); |
5109 } else { | 5126 } else { |
5110 // Cannot assert, unverified entry point counts instructions (see .ad file) | 5127 // Cannot assert, unverified entry point counts instructions (see .ad file) |
5111 // vtableStubs also counts instructions in pd_code_size_limit. | 5128 // vtableStubs also counts instructions in pd_code_size_limit. |
5112 // Also do not verify_oop as this is called by verify_oop. | 5129 // Also do not verify_oop as this is called by verify_oop. |
5113 | |
5114 mov64(dst, (int64_t)Universe::narrow_klass_base()); | 5130 mov64(dst, (int64_t)Universe::narrow_klass_base()); |
5115 if (Universe::narrow_klass_shift() != 0) { | 5131 if (Universe::narrow_klass_shift() != 0) { |
5116 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5132 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5117 assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?"); | 5133 assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?"); |
5118 leaq(dst, Address(dst, src, Address::times_8, 0)); | 5134 leaq(dst, Address(dst, src, Address::times_8, 0)); |
5139 RelocationHolder rspec = oop_Relocation::spec(oop_index); | 5155 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
5140 mov_narrow_oop(dst, oop_index, rspec); | 5156 mov_narrow_oop(dst, oop_index, rspec); |
5141 } | 5157 } |
5142 | 5158 |
5143 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { | 5159 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { |
5144 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5160 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
5145 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5161 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5146 int klass_index = oop_recorder()->find_index(k); | 5162 int klass_index = oop_recorder()->find_index(k); |
5147 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5163 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5148 mov_narrow_oop(dst, Klass::encode_klass(k), rspec); | 5164 mov_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5149 } | 5165 } |
5150 | 5166 |
5151 void MacroAssembler::set_narrow_klass(Address dst, Klass* k) { | 5167 void MacroAssembler::set_narrow_klass(Address dst, Klass* k) { |
5152 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5168 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
5153 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5169 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5154 int klass_index = oop_recorder()->find_index(k); | 5170 int klass_index = oop_recorder()->find_index(k); |
5155 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5171 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5156 mov_narrow_oop(dst, Klass::encode_klass(k), rspec); | 5172 mov_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5157 } | 5173 } |
5173 RelocationHolder rspec = oop_Relocation::spec(oop_index); | 5189 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
5174 Assembler::cmp_narrow_oop(dst, oop_index, rspec); | 5190 Assembler::cmp_narrow_oop(dst, oop_index, rspec); |
5175 } | 5191 } |
5176 | 5192 |
5177 void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { | 5193 void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { |
5178 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5194 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
5179 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5195 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5180 int klass_index = oop_recorder()->find_index(k); | 5196 int klass_index = oop_recorder()->find_index(k); |
5181 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5197 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5182 Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec); | 5198 Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5183 } | 5199 } |
5184 | 5200 |
5185 void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { | 5201 void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { |
5186 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5202 assert (UseCompressedClassPointers, "should only be used for compressed headers"); |
5187 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5203 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5188 int klass_index = oop_recorder()->find_index(k); | 5204 int klass_index = oop_recorder()->find_index(k); |
5189 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5205 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5190 Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec); | 5206 Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5191 } | 5207 } |
5192 | 5208 |
5193 void MacroAssembler::reinit_heapbase() { | 5209 void MacroAssembler::reinit_heapbase() { |
5194 if (UseCompressedOops || UseCompressedKlassPointers) { | 5210 if (UseCompressedOops || UseCompressedClassPointers) { |
5195 if (Universe::heap() != NULL) { | 5211 if (Universe::heap() != NULL) { |
5196 if (Universe::narrow_oop_base() == NULL) { | 5212 if (Universe::narrow_oop_base() == NULL) { |
5197 MacroAssembler::xorptr(r12_heapbase, r12_heapbase); | 5213 MacroAssembler::xorptr(r12_heapbase, r12_heapbase); |
5198 } else { | 5214 } else { |
5199 mov64(r12_heapbase, (int64_t)Universe::narrow_ptrs_base()); | 5215 mov64(r12_heapbase, (int64_t)Universe::narrow_ptrs_base()); |