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 |