230 assert(Rsub_klass != r14, "r14 holds locals"); |
230 assert(Rsub_klass != r14, "r14 holds locals"); |
231 assert(Rsub_klass != r13, "r13 holds bcp"); |
231 assert(Rsub_klass != r13, "r13 holds bcp"); |
232 assert(Rsub_klass != rcx, "rcx holds 2ndary super array length"); |
232 assert(Rsub_klass != rcx, "rcx holds 2ndary super array length"); |
233 assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr"); |
233 assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr"); |
234 |
234 |
235 Label not_subtype, not_subtype_pop, loop; |
|
236 |
|
237 // Profile the not-null value's klass. |
235 // Profile the not-null value's klass. |
238 profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi |
236 profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, reloads rdi |
239 |
237 |
240 // Load the super-klass's check offset into rcx |
238 // Do the check. |
241 movl(rcx, Address(rax, sizeof(oopDesc) + |
239 check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx |
242 Klass::super_check_offset_offset_in_bytes())); |
240 |
243 // Load from the sub-klass's super-class display list, or a 1-word |
241 // Profile the failure of the check. |
244 // cache of the secondary superclass list, or a failing value with a |
|
245 // sentinel offset if the super-klass is an interface or |
|
246 // exceptionally deep in the Java hierarchy and we have to scan the |
|
247 // secondary superclass list the hard way. See if we get an |
|
248 // immediate positive hit |
|
249 cmpptr(rax, Address(Rsub_klass, rcx, Address::times_1)); |
|
250 jcc(Assembler::equal,ok_is_subtype); |
|
251 |
|
252 // Check for immediate negative hit |
|
253 cmpl(rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); |
|
254 jcc( Assembler::notEqual, not_subtype ); |
|
255 // Check for self |
|
256 cmpptr(Rsub_klass, rax); |
|
257 jcc(Assembler::equal, ok_is_subtype); |
|
258 |
|
259 // Now do a linear scan of the secondary super-klass chain. |
|
260 movptr(rdi, Address(Rsub_klass, sizeof(oopDesc) + |
|
261 Klass::secondary_supers_offset_in_bytes())); |
|
262 // rdi holds the objArrayOop of secondary supers. |
|
263 // Load the array length |
|
264 movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); |
|
265 // Skip to start of data; also clear Z flag incase rcx is zero |
|
266 addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
|
267 // Scan rcx words at [rdi] for occurance of rax |
|
268 // Set NZ/Z based on last compare |
|
269 |
|
270 // this part is kind tricky, as values in supers array could be 32 or 64 bit wide |
|
271 // and we store values in objArrays always encoded, thus we need to encode value |
|
272 // before repne |
|
273 if (UseCompressedOops) { |
|
274 push(rax); |
|
275 encode_heap_oop(rax); |
|
276 repne_scanl(); |
|
277 // Not equal? |
|
278 jcc(Assembler::notEqual, not_subtype_pop); |
|
279 // restore heap oop here for movq |
|
280 pop(rax); |
|
281 } else { |
|
282 repne_scan(); |
|
283 jcc(Assembler::notEqual, not_subtype); |
|
284 } |
|
285 // Must be equal but missed in cache. Update cache. |
|
286 movptr(Address(Rsub_klass, sizeof(oopDesc) + |
|
287 Klass::secondary_super_cache_offset_in_bytes()), rax); |
|
288 jmp(ok_is_subtype); |
|
289 |
|
290 bind(not_subtype_pop); |
|
291 // restore heap oop here for miss |
|
292 if (UseCompressedOops) pop(rax); |
|
293 bind(not_subtype); |
|
294 profile_typecheck_failed(rcx); // blows rcx |
242 profile_typecheck_failed(rcx); // blows rcx |
295 } |
243 } |
296 |
244 |
297 |
245 |
298 |
246 |