src/hotspot/cpu/s390/macroAssembler_s390.cpp
changeset 58959 b7b170ba3ba9
parent 57777 90ead0febf56
equal deleted inserted replaced
58958:7bfe7df764a2 58959:b7b170ba3ba9
    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"
  2923   BLOCK_COMMENT("} IC miss handler");
  2925   BLOCK_COMMENT("} IC miss handler");
  2924   return labelOffset;
  2926   return labelOffset;
  2925 }
  2927 }
  2926 
  2928 
  2927 void MacroAssembler::nmethod_UEP(Label& ic_miss) {
  2929 void MacroAssembler::nmethod_UEP(Label& ic_miss) {
  2928   Register ic_reg       = as_Register(Matcher::inline_cache_reg_encode());
  2930   Register ic_reg       = Z_inline_cache;
  2929   int      klass_offset = oopDesc::klass_offset_in_bytes();
  2931   int      klass_offset = oopDesc::klass_offset_in_bytes();
  2930   if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) {
  2932   if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) {
  2931     if (VM_Version::has_CompareBranch()) {
  2933     if (VM_Version::has_CompareBranch()) {
  2932       z_cgij(Z_ARG1, 0, Assembler::bcondEqual, ic_miss);
  2934       z_cgij(Z_ARG1, 0, Assembler::bcondEqual, ic_miss);
  2933     } else {
  2935     } else {
  4588 
  4590 
  4589   int block_end = offset();
  4591   int block_end = offset();
  4590   return block_end - block_start;
  4592   return block_end - block_start;
  4591 }
  4593 }
  4592 
  4594 
       
  4595 #ifdef COMPILER2
  4593 //------------------------------------------------------
  4596 //------------------------------------------------------
  4594 //   Special String Intrinsics. Implementation
  4597 //   Special String Intrinsics. Implementation
  4595 //------------------------------------------------------
  4598 //------------------------------------------------------
  4596 
  4599 
  4597 // Intrinsics for CompactStrings
  4600 // Intrinsics for CompactStrings
  5835   }
  5838   }
  5836   BLOCK_COMMENT("} string_indexof_char");
  5839   BLOCK_COMMENT("} string_indexof_char");
  5837 
  5840 
  5838   return offset() - block_start;
  5841   return offset() - block_start;
  5839 }
  5842 }
  5840 
  5843 #endif
  5841 
  5844 
  5842 //-------------------------------------------------
  5845 //-------------------------------------------------
  5843 //   Constants (scalar and oop) in constant pool
  5846 //   Constants (scalar and oop) in constant pool
  5844 //-------------------------------------------------
  5847 //-------------------------------------------------
  5845 
  5848 
  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 //---------------------------------------