Mercurial > hg > truffle
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 |