diff -r c771b7f43bbf -r c517646eef23 src/cpu/x86/vm/interp_masm_x86_32.cpp --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Fri Mar 13 11:35:17 2009 -0700 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Fri Mar 13 18:39:22 2009 -0700 @@ -219,47 +219,16 @@ // Resets EDI to locals. Register sub_klass cannot be any of the above. void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) { assert( Rsub_klass != rax, "rax, holds superklass" ); - assert( Rsub_klass != rcx, "rcx holds 2ndary super array length" ); - assert( Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr" ); - Label not_subtype, loop; + assert( Rsub_klass != rcx, "used as a temp" ); + assert( Rsub_klass != rdi, "used as a temp, restored from locals" ); // Profile the not-null value's klass. - profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi + profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, reloads rdi - // Load the super-klass's check offset into ECX - movl( rcx, Address(rax, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes() ) ); - // Load from the sub-klass's super-class display list, or a 1-word cache of - // the secondary superclass list, or a failing value with a sentinel offset - // if the super-klass is an interface or exceptionally deep in the Java - // hierarchy and we have to scan the secondary superclass list the hard way. - // See if we get an immediate positive hit - cmpptr( rax, Address(Rsub_klass,rcx,Address::times_1) ); - jcc( Assembler::equal,ok_is_subtype ); + // Do the check. + check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx - // Check for immediate negative hit - cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); - jcc( Assembler::notEqual, not_subtype ); - // Check for self - cmpptr( Rsub_klass, rax ); - jcc( Assembler::equal, ok_is_subtype ); - - // Now do a linear scan of the secondary super-klass chain. - movptr( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); - // EDI holds the objArrayOop of secondary supers. - movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length - // Skip to start of data; also clear Z flag incase ECX is zero - addptr( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); - // Scan ECX words at [EDI] for occurance of EAX - // Set NZ/Z based on last compare - repne_scan(); - restore_locals(); // Restore EDI; Must not blow flags - // Not equal? - jcc( Assembler::notEqual, not_subtype ); - // Must be equal but missed in cache. Update cache. - movptr( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); - jmp( ok_is_subtype ); - - bind(not_subtype); + // Profile the failure of the check. profile_typecheck_failed(rcx); // blows rcx }