Mercurial > hg > truffle
comparison src/cpu/x86/vm/vtableStubs_x86_64.cpp @ 304:dc7f315e41f7
5108146: Merge i486 and amd64 cpu directories
6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up
Reviewed-by: kvn
author | never |
---|---|
date | Wed, 27 Aug 2008 00:21:55 -0700 |
parents | d1605aabd0a1 |
children | 9adddb8c0fc8 |
comparison
equal
deleted
inserted
replaced
303:fa4d1d240383 | 304:dc7f315e41f7 |
---|---|
77 #endif // PRODUCT | 77 #endif // PRODUCT |
78 | 78 |
79 // load methodOop and target address | 79 // load methodOop and target address |
80 const Register method = rbx; | 80 const Register method = rbx; |
81 | 81 |
82 __ movq(method, Address(rax, | 82 __ movptr(method, Address(rax, |
83 entry_offset * wordSize + | 83 entry_offset * wordSize + |
84 vtableEntry::method_offset_in_bytes())); | 84 vtableEntry::method_offset_in_bytes())); |
85 if (DebugVtables) { | 85 if (DebugVtables) { |
86 Label L; | 86 Label L; |
87 __ cmpq(method, (int)NULL); | 87 __ cmpptr(method, (int32_t)NULL_WORD); |
88 __ jcc(Assembler::equal, L); | 88 __ jcc(Assembler::equal, L); |
89 __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); | 89 __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); |
90 __ jcc(Assembler::notZero, L); | 90 __ jcc(Assembler::notZero, L); |
91 __ stop("Vtable entry is NULL"); | 91 __ stop("Vtable entry is NULL"); |
92 __ bind(L); | 92 __ bind(L); |
93 } | 93 } |
94 // rax: receiver klass | 94 // rax: receiver klass |
136 // If we take a trap while this arg is on the stack we will not | 136 // If we take a trap while this arg is on the stack we will not |
137 // be able to walk the stack properly. This is not an issue except | 137 // be able to walk the stack properly. This is not an issue except |
138 // when there are mistakes in this assembly code that could generate | 138 // when there are mistakes in this assembly code that could generate |
139 // a spurious fault. Ask me how I know... | 139 // a spurious fault. Ask me how I know... |
140 | 140 |
141 __ pushq(j_rarg1); // Most registers are in use, so save one | 141 __ push(j_rarg1); // Most registers are in use, so save one |
142 | 142 |
143 // compute itable entry offset (in words) | 143 // compute itable entry offset (in words) |
144 const int base = instanceKlass::vtable_start_offset() * wordSize; | 144 const int base = instanceKlass::vtable_start_offset() * wordSize; |
145 assert(vtableEntry::size() * wordSize == 8, | 145 assert(vtableEntry::size() * wordSize == 8, |
146 "adjust the scaling in the code below"); | 146 "adjust the scaling in the code below"); |
147 // Get length of vtable | 147 // Get length of vtable |
148 __ movl(j_rarg1, | 148 __ movl(j_rarg1, |
149 Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); | 149 Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); |
150 __ leaq(rbx, Address(rbx, j_rarg1, Address::times_8, base)); | 150 __ lea(rbx, Address(rbx, j_rarg1, Address::times_8, base)); |
151 | 151 |
152 if (HeapWordsPerLong > 1) { | 152 if (HeapWordsPerLong > 1) { |
153 // Round up to align_object_offset boundary | 153 // Round up to align_object_offset boundary |
154 __ round_to_q(rbx, BytesPerLong); | 154 __ round_to(rbx, BytesPerLong); |
155 } | 155 } |
156 Label hit, next, entry, throw_icce; | 156 Label hit, next, entry, throw_icce; |
157 | 157 |
158 __ jmpb(entry); | 158 __ jmpb(entry); |
159 | 159 |
160 __ bind(next); | 160 __ bind(next); |
161 __ addq(rbx, itableOffsetEntry::size() * wordSize); | 161 __ addptr(rbx, itableOffsetEntry::size() * wordSize); |
162 | 162 |
163 __ bind(entry); | 163 __ bind(entry); |
164 | 164 |
165 // If the entry is NULL then we've reached the end of the table | 165 // If the entry is NULL then we've reached the end of the table |
166 // without finding the expected interface, so throw an exception | 166 // without finding the expected interface, so throw an exception |
167 __ movq(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); | 167 __ movptr(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); |
168 __ testq(j_rarg1, j_rarg1); | 168 __ testptr(j_rarg1, j_rarg1); |
169 __ jcc(Assembler::zero, throw_icce); | 169 __ jcc(Assembler::zero, throw_icce); |
170 __ cmpq(rax, j_rarg1); | 170 __ cmpptr(rax, j_rarg1); |
171 __ jccb(Assembler::notEqual, next); | 171 __ jccb(Assembler::notEqual, next); |
172 | 172 |
173 // We found a hit, move offset into j_rarg1 | 173 // We found a hit, move offset into j_rarg1 |
174 __ movl(j_rarg1, Address(rbx, itableOffsetEntry::offset_offset_in_bytes())); | 174 __ movl(j_rarg1, Address(rbx, itableOffsetEntry::offset_offset_in_bytes())); |
175 | 175 |
182 | 182 |
183 // Get klass pointer again | 183 // Get klass pointer again |
184 __ load_klass(rax, j_rarg0); | 184 __ load_klass(rax, j_rarg0); |
185 | 185 |
186 const Register method = rbx; | 186 const Register method = rbx; |
187 __ movq(method, Address(rax, j_rarg1, Address::times_1, method_offset)); | 187 __ movptr(method, Address(rax, j_rarg1, Address::times_1, method_offset)); |
188 | 188 |
189 // Restore saved register, before possible trap. | 189 // Restore saved register, before possible trap. |
190 __ popq(j_rarg1); | 190 __ pop(j_rarg1); |
191 | 191 |
192 // method (rbx): methodOop | 192 // method (rbx): methodOop |
193 // j_rarg0: receiver | 193 // j_rarg0: receiver |
194 | 194 |
195 | 195 |
196 #ifdef ASSERT | 196 #ifdef ASSERT |
197 if (DebugVtables) { | 197 if (DebugVtables) { |
198 Label L2; | 198 Label L2; |
199 __ cmpq(method, (int)NULL); | 199 __ cmpptr(method, (int32_t)NULL_WORD); |
200 __ jcc(Assembler::equal, L2); | 200 __ jcc(Assembler::equal, L2); |
201 __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); | 201 __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); |
202 __ jcc(Assembler::notZero, L2); | 202 __ jcc(Assembler::notZero, L2); |
203 __ stop("compiler entrypoint is null"); | 203 __ stop("compiler entrypoint is null"); |
204 __ bind(L2); | 204 __ bind(L2); |
205 } | 205 } |
206 #endif // ASSERT | 206 #endif // ASSERT |
210 address ame_addr = __ pc(); | 210 address ame_addr = __ pc(); |
211 __ jmp(Address(method, methodOopDesc::from_compiled_offset())); | 211 __ jmp(Address(method, methodOopDesc::from_compiled_offset())); |
212 | 212 |
213 __ bind(throw_icce); | 213 __ bind(throw_icce); |
214 // Restore saved register | 214 // Restore saved register |
215 __ popq(j_rarg1); | 215 __ pop(j_rarg1); |
216 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); | 216 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); |
217 | 217 |
218 __ flush(); | 218 __ flush(); |
219 | 219 |
220 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); | 220 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); |