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");