217 // Generate a subtype check: branch to ok_is_subtype if sub_klass is |
217 // Generate a subtype check: branch to ok_is_subtype if sub_klass is |
218 // a subtype of super_klass. EAX holds the super_klass. Blows ECX. |
218 // a subtype of super_klass. EAX holds the super_klass. Blows ECX. |
219 // Resets EDI to locals. Register sub_klass cannot be any of the above. |
219 // Resets EDI to locals. Register sub_klass cannot be any of the above. |
220 void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) { |
220 void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) { |
221 assert( Rsub_klass != rax, "rax, holds superklass" ); |
221 assert( Rsub_klass != rax, "rax, holds superklass" ); |
222 assert( Rsub_klass != rcx, "rcx holds 2ndary super array length" ); |
222 assert( Rsub_klass != rcx, "used as a temp" ); |
223 assert( Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr" ); |
223 assert( Rsub_klass != rdi, "used as a temp, restored from locals" ); |
224 Label not_subtype, loop; |
|
225 |
224 |
226 // Profile the not-null value's klass. |
225 // Profile the not-null value's klass. |
227 profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi |
226 profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, reloads rdi |
228 |
227 |
229 // Load the super-klass's check offset into ECX |
228 // Do the check. |
230 movl( rcx, Address(rax, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes() ) ); |
229 check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx |
231 // Load from the sub-klass's super-class display list, or a 1-word cache of |
230 |
232 // the secondary superclass list, or a failing value with a sentinel offset |
231 // Profile the failure of the check. |
233 // if the super-klass is an interface or exceptionally deep in the Java |
|
234 // hierarchy and we have to scan the secondary superclass list the hard way. |
|
235 // See if we get an immediate positive hit |
|
236 cmpptr( rax, Address(Rsub_klass,rcx,Address::times_1) ); |
|
237 jcc( Assembler::equal,ok_is_subtype ); |
|
238 |
|
239 // Check for immediate negative hit |
|
240 cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); |
|
241 jcc( Assembler::notEqual, not_subtype ); |
|
242 // Check for self |
|
243 cmpptr( Rsub_klass, rax ); |
|
244 jcc( Assembler::equal, ok_is_subtype ); |
|
245 |
|
246 // Now do a linear scan of the secondary super-klass chain. |
|
247 movptr( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); |
|
248 // EDI holds the objArrayOop of secondary supers. |
|
249 movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length |
|
250 // Skip to start of data; also clear Z flag incase ECX is zero |
|
251 addptr( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); |
|
252 // Scan ECX words at [EDI] for occurance of EAX |
|
253 // Set NZ/Z based on last compare |
|
254 repne_scan(); |
|
255 restore_locals(); // Restore EDI; Must not blow flags |
|
256 // Not equal? |
|
257 jcc( Assembler::notEqual, not_subtype ); |
|
258 // Must be equal but missed in cache. Update cache. |
|
259 movptr( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); |
|
260 jmp( ok_is_subtype ); |
|
261 |
|
262 bind(not_subtype); |
|
263 profile_typecheck_failed(rcx); // blows rcx |
232 profile_typecheck_failed(rcx); // blows rcx |
264 } |
233 } |
265 |
234 |
266 void InterpreterMacroAssembler::f2ieee() { |
235 void InterpreterMacroAssembler::f2ieee() { |
267 if (IEEEPrecision) { |
236 if (IEEEPrecision) { |