35 #include "memory/resourceArea.hpp" |
35 #include "memory/resourceArea.hpp" |
36 #include "memory/universe.hpp" |
36 #include "memory/universe.hpp" |
37 #include "oops/accessDecorators.hpp" |
37 #include "oops/accessDecorators.hpp" |
38 #include "oops/compressedOops.inline.hpp" |
38 #include "oops/compressedOops.inline.hpp" |
39 #include "oops/klass.inline.hpp" |
39 #include "oops/klass.inline.hpp" |
|
40 #ifdef COMPILER2 |
40 #include "opto/compile.hpp" |
41 #include "opto/compile.hpp" |
41 #include "opto/intrinsicnode.hpp" |
42 #include "opto/intrinsicnode.hpp" |
42 #include "opto/matcher.hpp" |
43 #include "opto/matcher.hpp" |
|
44 #endif |
43 #include "prims/methodHandles.hpp" |
45 #include "prims/methodHandles.hpp" |
44 #include "registerSaver_s390.hpp" |
46 #include "registerSaver_s390.hpp" |
45 #include "runtime/biasedLocking.hpp" |
47 #include "runtime/biasedLocking.hpp" |
46 #include "runtime/icache.hpp" |
48 #include "runtime/icache.hpp" |
47 #include "runtime/interfaceSupport.inline.hpp" |
49 #include "runtime/interfaceSupport.inline.hpp" |
6146 |
6149 |
6147 Label retry; |
6150 Label retry; |
6148 bind(retry); |
6151 bind(retry); |
6149 Assembler::z_trtt(r1, r2, m3); |
6152 Assembler::z_trtt(r1, r2, m3); |
6150 Assembler::z_brc(Assembler::bcondOverflow /* CC==3 (iterate) */, retry); |
6153 Assembler::z_brc(Assembler::bcondOverflow /* CC==3 (iterate) */, retry); |
6151 } |
|
6152 |
|
6153 |
|
6154 void MacroAssembler::generate_type_profiling(const Register Rdata, |
|
6155 const Register Rreceiver_klass, |
|
6156 const Register Rwanted_receiver_klass, |
|
6157 const Register Rmatching_row, |
|
6158 bool is_virtual_call) { |
|
6159 const int row_size = in_bytes(ReceiverTypeData::receiver_offset(1)) - |
|
6160 in_bytes(ReceiverTypeData::receiver_offset(0)); |
|
6161 const int num_rows = ReceiverTypeData::row_limit(); |
|
6162 NearLabel found_free_row; |
|
6163 NearLabel do_increment; |
|
6164 NearLabel found_no_slot; |
|
6165 |
|
6166 BLOCK_COMMENT("type profiling {"); |
|
6167 |
|
6168 // search for: |
|
6169 // a) The type given in Rwanted_receiver_klass. |
|
6170 // b) The *first* empty row. |
|
6171 |
|
6172 // First search for a) only, just running over b) with no regard. |
|
6173 // This is possible because |
|
6174 // wanted_receiver_class == receiver_class && wanted_receiver_class == 0 |
|
6175 // is never true (receiver_class can't be zero). |
|
6176 for (int row_num = 0; row_num < num_rows; row_num++) { |
|
6177 // Row_offset should be a well-behaved positive number. The generated code relies |
|
6178 // on that wrt constant code size. Add2reg can handle all row_offset values, but |
|
6179 // will have to vary generated code size. |
|
6180 int row_offset = in_bytes(ReceiverTypeData::receiver_offset(row_num)); |
|
6181 assert(Displacement::is_shortDisp(row_offset), "Limitation of generated code"); |
|
6182 |
|
6183 // Is Rwanted_receiver_klass in this row? |
|
6184 if (VM_Version::has_CompareBranch()) { |
|
6185 z_lg(Rwanted_receiver_klass, row_offset, Z_R0, Rdata); |
|
6186 // Rmatching_row = Rdata + row_offset; |
|
6187 add2reg(Rmatching_row, row_offset, Rdata); |
|
6188 // if (*row_recv == (intptr_t) receiver_klass) goto fill_existing_slot; |
|
6189 compare64_and_branch(Rwanted_receiver_klass, Rreceiver_klass, Assembler::bcondEqual, do_increment); |
|
6190 } else { |
|
6191 add2reg(Rmatching_row, row_offset, Rdata); |
|
6192 z_cg(Rreceiver_klass, row_offset, Z_R0, Rdata); |
|
6193 z_bre(do_increment); |
|
6194 } |
|
6195 } |
|
6196 |
|
6197 // Now that we did not find a match, let's search for b). |
|
6198 |
|
6199 // We could save the first calculation of Rmatching_row if we woud search for a) in reverse order. |
|
6200 // We would then end up here with Rmatching_row containing the value for row_num == 0. |
|
6201 // We would not see much benefit, if any at all, because the CPU can schedule |
|
6202 // two instructions together with a branch anyway. |
|
6203 for (int row_num = 0; row_num < num_rows; row_num++) { |
|
6204 int row_offset = in_bytes(ReceiverTypeData::receiver_offset(row_num)); |
|
6205 |
|
6206 // Has this row a zero receiver_klass, i.e. is it empty? |
|
6207 if (VM_Version::has_CompareBranch()) { |
|
6208 z_lg(Rwanted_receiver_klass, row_offset, Z_R0, Rdata); |
|
6209 // Rmatching_row = Rdata + row_offset |
|
6210 add2reg(Rmatching_row, row_offset, Rdata); |
|
6211 // if (*row_recv == (intptr_t) 0) goto found_free_row |
|
6212 compare64_and_branch(Rwanted_receiver_klass, (intptr_t)0, Assembler::bcondEqual, found_free_row); |
|
6213 } else { |
|
6214 add2reg(Rmatching_row, row_offset, Rdata); |
|
6215 load_and_test_long(Rwanted_receiver_klass, Address(Rdata, row_offset)); |
|
6216 z_bre(found_free_row); // zero -> Found a free row. |
|
6217 } |
|
6218 } |
|
6219 |
|
6220 // No match, no empty row found. |
|
6221 // Increment total counter to indicate polymorphic case. |
|
6222 if (is_virtual_call) { |
|
6223 add2mem_64(Address(Rdata, CounterData::count_offset()), 1, Rmatching_row); |
|
6224 } |
|
6225 z_bru(found_no_slot); |
|
6226 |
|
6227 // Here we found an empty row, but we have not found Rwanted_receiver_klass. |
|
6228 // Rmatching_row holds the address to the first empty row. |
|
6229 bind(found_free_row); |
|
6230 // Store receiver_klass into empty slot. |
|
6231 z_stg(Rreceiver_klass, 0, Z_R0, Rmatching_row); |
|
6232 |
|
6233 // Increment the counter of Rmatching_row. |
|
6234 bind(do_increment); |
|
6235 ByteSize counter_offset = ReceiverTypeData::receiver_count_offset(0) - ReceiverTypeData::receiver_offset(0); |
|
6236 add2mem_64(Address(Rmatching_row, counter_offset), 1, Rdata); |
|
6237 |
|
6238 bind(found_no_slot); |
|
6239 |
|
6240 BLOCK_COMMENT("} type profiling"); |
|
6241 } |
6154 } |
6242 |
6155 |
6243 //--------------------------------------- |
6156 //--------------------------------------- |
6244 // Helpers for Intrinsic Emitters |
6157 // Helpers for Intrinsic Emitters |
6245 //--------------------------------------- |
6158 //--------------------------------------- |