Mercurial > hg > truffle
comparison src/cpu/x86/vm/macroAssembler_x86.cpp @ 12057:58fc8e2b7b6d
Merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Thu, 10 Oct 2013 17:22:25 +0200 |
parents | 6b0fd0964b87 740e263c80c6 |
children | cefad50507d8 |
comparison
equal
deleted
inserted
replaced
12041:7e5cf369559f | 12057:58fc8e2b7b6d |
---|---|
28 #include "compiler/disassembler.hpp" | 28 #include "compiler/disassembler.hpp" |
29 #include "gc_interface/collectedHeap.inline.hpp" | 29 #include "gc_interface/collectedHeap.inline.hpp" |
30 #include "interpreter/interpreter.hpp" | 30 #include "interpreter/interpreter.hpp" |
31 #include "memory/cardTableModRefBS.hpp" | 31 #include "memory/cardTableModRefBS.hpp" |
32 #include "memory/resourceArea.hpp" | 32 #include "memory/resourceArea.hpp" |
33 #include "memory/universe.hpp" | |
33 #include "prims/methodHandles.hpp" | 34 #include "prims/methodHandles.hpp" |
34 #include "runtime/biasedLocking.hpp" | 35 #include "runtime/biasedLocking.hpp" |
35 #include "runtime/interfaceSupport.hpp" | 36 #include "runtime/interfaceSupport.hpp" |
36 #include "runtime/objectMonitor.hpp" | 37 #include "runtime/objectMonitor.hpp" |
37 #include "runtime/os.hpp" | 38 #include "runtime/os.hpp" |
4808 #endif | 4809 #endif |
4809 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 4810 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
4810 } | 4811 } |
4811 | 4812 |
4812 void MacroAssembler::load_prototype_header(Register dst, Register src) { | 4813 void MacroAssembler::load_prototype_header(Register dst, Register src) { |
4813 #ifdef _LP64 | 4814 load_klass(dst, src); |
4814 if (UseCompressedKlassPointers) { | 4815 movptr(dst, Address(dst, Klass::prototype_header_offset())); |
4815 assert (Universe::heap() != NULL, "java heap should be initialized"); | |
4816 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); | |
4817 if (Universe::narrow_klass_shift() != 0) { | |
4818 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | |
4819 assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?"); | |
4820 movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset())); | |
4821 } else { | |
4822 movq(dst, Address(dst, Klass::prototype_header_offset())); | |
4823 } | |
4824 } else | |
4825 #endif | |
4826 { | |
4827 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); | |
4828 movptr(dst, Address(dst, Klass::prototype_header_offset())); | |
4829 } | |
4830 } | 4816 } |
4831 | 4817 |
4832 void MacroAssembler::store_klass(Register dst, Register src) { | 4818 void MacroAssembler::store_klass(Register dst, Register src) { |
4833 #ifdef _LP64 | 4819 #ifdef _LP64 |
4834 if (UseCompressedKlassPointers) { | 4820 if (UseCompressedKlassPointers) { |
4912 } | 4898 } |
4913 } | 4899 } |
4914 | 4900 |
4915 #ifdef ASSERT | 4901 #ifdef ASSERT |
4916 void MacroAssembler::verify_heapbase(const char* msg) { | 4902 void MacroAssembler::verify_heapbase(const char* msg) { |
4917 assert (UseCompressedOops || UseCompressedKlassPointers, "should be compressed"); | 4903 assert (UseCompressedOops, "should be compressed"); |
4918 assert (Universe::heap() != NULL, "java heap should be initialized"); | 4904 assert (Universe::heap() != NULL, "java heap should be initialized"); |
4919 if (CheckCompressedOops) { | 4905 if (CheckCompressedOops) { |
4920 Label ok; | 4906 Label ok; |
4921 push(rscratch1); // cmpptr trashes rscratch1 | 4907 push(rscratch1); // cmpptr trashes rscratch1 |
4922 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr())); | 4908 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr())); |
5056 } | 5042 } |
5057 } | 5043 } |
5058 } | 5044 } |
5059 | 5045 |
5060 void MacroAssembler::encode_klass_not_null(Register r) { | 5046 void MacroAssembler::encode_klass_not_null(Register r) { |
5061 assert(Metaspace::is_initialized(), "metaspace should be initialized"); | 5047 assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); |
5062 #ifdef ASSERT | 5048 // Use r12 as a scratch register in which to temporarily load the narrow_klass_base. |
5063 verify_heapbase("MacroAssembler::encode_klass_not_null: heap base corrupted?"); | 5049 assert(r != r12_heapbase, "Encoding a klass in r12"); |
5064 #endif | 5050 mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base()); |
5065 if (Universe::narrow_klass_base() != NULL) { | 5051 subq(r, r12_heapbase); |
5066 subq(r, r12_heapbase); | |
5067 } | |
5068 if (Universe::narrow_klass_shift() != 0) { | 5052 if (Universe::narrow_klass_shift() != 0) { |
5069 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5053 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5070 shrq(r, LogKlassAlignmentInBytes); | 5054 shrq(r, LogKlassAlignmentInBytes); |
5071 } | 5055 } |
5056 reinit_heapbase(); | |
5072 } | 5057 } |
5073 | 5058 |
5074 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { | 5059 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { |
5075 assert(Metaspace::is_initialized(), "metaspace should be initialized"); | 5060 if (dst == src) { |
5076 #ifdef ASSERT | 5061 encode_klass_not_null(src); |
5077 verify_heapbase("MacroAssembler::encode_klass_not_null2: heap base corrupted?"); | 5062 } else { |
5078 #endif | 5063 mov64(dst, (int64_t)Universe::narrow_klass_base()); |
5079 if (dst != src) { | 5064 negq(dst); |
5080 movq(dst, src); | 5065 addq(dst, src); |
5081 } | 5066 if (Universe::narrow_klass_shift() != 0) { |
5082 if (Universe::narrow_klass_base() != NULL) { | 5067 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5083 subq(dst, r12_heapbase); | 5068 shrq(dst, LogKlassAlignmentInBytes); |
5084 } | 5069 } |
5085 if (Universe::narrow_klass_shift() != 0) { | 5070 } |
5086 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5071 } |
5087 shrq(dst, LogKlassAlignmentInBytes); | 5072 |
5088 } | 5073 // Function instr_size_for_decode_klass_not_null() counts the instructions |
5089 } | 5074 // generated by decode_klass_not_null(register r) and reinit_heapbase(), |
5090 | 5075 // when (Universe::heap() != NULL). Hence, if the instructions they |
5076 // generate change, then this method needs to be updated. | |
5077 int MacroAssembler::instr_size_for_decode_klass_not_null() { | |
5078 assert (UseCompressedKlassPointers, "only for compressed klass ptrs"); | |
5079 // mov64 + addq + shlq? + mov64 (for reinit_heapbase()). | |
5080 return (Universe::narrow_klass_shift() == 0 ? 20 : 24); | |
5081 } | |
5082 | |
5083 // !!! If the instructions that get generated here change then function | |
5084 // instr_size_for_decode_klass_not_null() needs to get updated. | |
5091 void MacroAssembler::decode_klass_not_null(Register r) { | 5085 void MacroAssembler::decode_klass_not_null(Register r) { |
5092 assert(Metaspace::is_initialized(), "metaspace should be initialized"); | |
5093 // Note: it will change flags | 5086 // Note: it will change flags |
5087 assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); | |
5094 assert (UseCompressedKlassPointers, "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"); | |
5095 // Cannot assert, unverified entry point counts instructions (see .ad file) | 5090 // Cannot assert, unverified entry point counts instructions (see .ad file) |
5096 // vtableStubs also counts instructions in pd_code_size_limit. | 5091 // vtableStubs also counts instructions in pd_code_size_limit. |
5097 // Also do not verify_oop as this is called by verify_oop. | 5092 // Also do not verify_oop as this is called by verify_oop. |
5098 if (Universe::narrow_klass_shift() != 0) { | 5093 if (Universe::narrow_klass_shift() != 0) { |
5099 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5094 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5100 shlq(r, LogKlassAlignmentInBytes); | 5095 shlq(r, LogKlassAlignmentInBytes); |
5101 if (Universe::narrow_klass_base() != NULL) { | 5096 } |
5102 addq(r, r12_heapbase); | 5097 // Use r12 as a scratch register in which to temporarily load the narrow_klass_base. |
5103 } | 5098 mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base()); |
5104 } else { | 5099 addq(r, r12_heapbase); |
5105 assert (Universe::narrow_klass_base() == NULL, "sanity"); | 5100 reinit_heapbase(); |
5106 } | |
5107 } | 5101 } |
5108 | 5102 |
5109 void MacroAssembler::decode_klass_not_null(Register dst, Register src) { | 5103 void MacroAssembler::decode_klass_not_null(Register dst, Register src) { |
5110 assert(Metaspace::is_initialized(), "metaspace should be initialized"); | |
5111 // Note: it will change flags | 5104 // Note: it will change flags |
5105 assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); | |
5112 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5106 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); |
5113 // Cannot assert, unverified entry point counts instructions (see .ad file) | 5107 if (dst == src) { |
5114 // vtableStubs also counts instructions in pd_code_size_limit. | 5108 decode_klass_not_null(dst); |
5115 // Also do not verify_oop as this is called by verify_oop. | 5109 } else { |
5116 if (Universe::narrow_klass_shift() != 0) { | 5110 // Cannot assert, unverified entry point counts instructions (see .ad file) |
5117 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); | 5111 // vtableStubs also counts instructions in pd_code_size_limit. |
5118 assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?"); | 5112 // Also do not verify_oop as this is called by verify_oop. |
5119 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); | 5113 |
5120 } else { | 5114 mov64(dst, (int64_t)Universe::narrow_klass_base()); |
5121 assert (Universe::narrow_klass_base() == NULL, "sanity"); | 5115 if (Universe::narrow_klass_shift() != 0) { |
5122 if (dst != src) { | 5116 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
5123 movq(dst, src); | 5117 assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?"); |
5118 leaq(dst, Address(dst, src, Address::times_8, 0)); | |
5119 } else { | |
5120 addq(dst, src); | |
5124 } | 5121 } |
5125 } | 5122 } |
5126 } | 5123 } |
5127 | 5124 |
5128 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { | 5125 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { |
5146 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { | 5143 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { |
5147 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5144 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); |
5148 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5145 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5149 int klass_index = oop_recorder()->find_index(k); | 5146 int klass_index = oop_recorder()->find_index(k); |
5150 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5147 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5151 mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec); | 5148 mov_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5152 } | 5149 } |
5153 | 5150 |
5154 void MacroAssembler::set_narrow_klass(Address dst, Klass* k) { | 5151 void MacroAssembler::set_narrow_klass(Address dst, Klass* k) { |
5155 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5152 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); |
5156 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5153 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5157 int klass_index = oop_recorder()->find_index(k); | 5154 int klass_index = oop_recorder()->find_index(k); |
5158 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5155 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5159 mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec); | 5156 mov_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5160 } | 5157 } |
5161 | 5158 |
5162 void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) { | 5159 void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) { |
5163 assert (UseCompressedOops, "should only be used for compressed headers"); | 5160 assert (UseCompressedOops, "should only be used for compressed headers"); |
5164 assert (Universe::heap() != NULL, "java heap should be initialized"); | 5161 assert (Universe::heap() != NULL, "java heap should be initialized"); |
5180 void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { | 5177 void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { |
5181 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5178 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); |
5182 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5179 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5183 int klass_index = oop_recorder()->find_index(k); | 5180 int klass_index = oop_recorder()->find_index(k); |
5184 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5181 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5185 Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec); | 5182 Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5186 } | 5183 } |
5187 | 5184 |
5188 void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { | 5185 void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { |
5189 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); | 5186 assert (UseCompressedKlassPointers, "should only be used for compressed headers"); |
5190 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 5187 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
5191 int klass_index = oop_recorder()->find_index(k); | 5188 int klass_index = oop_recorder()->find_index(k); |
5192 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 5189 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
5193 Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec); | 5190 Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec); |
5194 } | 5191 } |
5195 | 5192 |
5196 void MacroAssembler::reinit_heapbase() { | 5193 void MacroAssembler::reinit_heapbase() { |
5197 if (UseCompressedOops || UseCompressedKlassPointers) { | 5194 if (UseCompressedOops || UseCompressedKlassPointers) { |
5198 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr())); | 5195 if (Universe::heap() != NULL) { |
5199 } | 5196 if (Universe::narrow_oop_base() == NULL) { |
5200 } | 5197 MacroAssembler::xorptr(r12_heapbase, r12_heapbase); |
5198 } else { | |
5199 mov64(r12_heapbase, (int64_t)Universe::narrow_ptrs_base()); | |
5200 } | |
5201 } else { | |
5202 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr())); | |
5203 } | |
5204 } | |
5205 } | |
5206 | |
5201 #endif // _LP64 | 5207 #endif // _LP64 |
5202 | 5208 |
5203 | 5209 |
5204 // C2 compiled method's prolog code. | 5210 // C2 compiled method's prolog code. |
5205 void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) { | 5211 void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) { |