comparison src/cpu/x86/vm/stubGenerator_x86_64.cpp @ 644:c517646eef23

6813212: factor duplicated assembly code for general subclass check (for 6655638) Summary: Code in interp_masm, stubGenerator, c1_LIRAssembler, and AD files moved into MacroAssembler. Reviewed-by: kvn
author jrose
date Fri, 13 Mar 2009 18:39:22 -0700
parents db4caa99ef11
children bd441136a5ce
comparison
equal deleted inserted replaced
643:c771b7f43bbf 644:c517646eef23
2089 2089
2090 BLOCK_COMMENT("type_check:"); 2090 BLOCK_COMMENT("type_check:");
2091 2091
2092 Label L_miss; 2092 Label L_miss;
2093 2093
2094 // a couple of useful fields in sub_klass: 2094 __ check_klass_subtype_fast_path(sub_klass, super_klass, noreg, &L_success, &L_miss, NULL,
2095 int ss_offset = (klassOopDesc::header_size() * HeapWordSize + 2095 super_check_offset);
2096 Klass::secondary_supers_offset_in_bytes()); 2096 __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg, &L_success, NULL);
2097 int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
2098 Klass::secondary_super_cache_offset_in_bytes());
2099 Address secondary_supers_addr(sub_klass, ss_offset);
2100 Address super_cache_addr( sub_klass, sc_offset);
2101
2102 // if the pointers are equal, we are done (e.g., String[] elements)
2103 __ cmpptr(super_klass, sub_klass);
2104 __ jcc(Assembler::equal, L_success);
2105
2106 // check the supertype display:
2107 Address super_check_addr(sub_klass, super_check_offset, Address::times_1, 0);
2108 __ cmpptr(super_klass, super_check_addr); // test the super type
2109 __ jcc(Assembler::equal, L_success);
2110
2111 // if it was a primary super, we can just fail immediately
2112 __ cmpl(super_check_offset, sc_offset);
2113 __ jcc(Assembler::notEqual, L_miss);
2114
2115 // Now do a linear scan of the secondary super-klass chain.
2116 // The repne_scan instruction uses fixed registers, which we must spill.
2117 // (We need a couple more temps in any case.)
2118 // This code is rarely used, so simplicity is a virtue here.
2119 inc_counter_np(SharedRuntime::_partial_subtype_ctr);
2120 {
2121 __ push(rax);
2122 __ push(rcx);
2123 __ push(rdi);
2124 assert_different_registers(sub_klass, super_klass, rax, rcx, rdi);
2125
2126 __ movptr(rdi, secondary_supers_addr);
2127 // Load the array length.
2128 __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
2129 // Skip to start of data.
2130 __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
2131 // Scan rcx words at [rdi] for occurance of rax
2132 // Set NZ/Z based on last compare
2133 __ movptr(rax, super_klass);
2134 if (UseCompressedOops) {
2135 // Compare against compressed form. Don't need to uncompress because
2136 // looks like orig rax is restored in popq below.
2137 __ encode_heap_oop(rax);
2138 __ repne_scanl();
2139 } else {
2140 __ repne_scan();
2141 }
2142
2143 // Unspill the temp. registers:
2144 __ pop(rdi);
2145 __ pop(rcx);
2146 __ pop(rax);
2147
2148 __ jcc(Assembler::notEqual, L_miss);
2149 }
2150
2151 // Success. Cache the super we found and proceed in triumph.
2152 __ movptr(super_cache_addr, super_klass); // note: rax is dead
2153 __ jmp(L_success);
2154 2097
2155 // Fall through on failure! 2098 // Fall through on failure!
2156 __ BIND(L_miss); 2099 __ BIND(L_miss);
2157 } 2100 }
2158 2101