< prev index next >

src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp

Print this page




  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "c1/c1_MacroAssembler.hpp"
  29 #include "c1/c1_Runtime1.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 #include "oops/arrayOop.hpp"
  34 #include "oops/markWord.hpp"
  35 #include "runtime/basicLock.hpp"
  36 #include "runtime/biasedLocking.hpp"
  37 #include "runtime/os.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/stubRoutines.hpp"
  40 
  41 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
  42   Label ic_miss, ic_hit;
  43   verify_oop(receiver);
  44   int klass_offset = oopDesc::klass_offset_in_bytes();
  45 
  46   if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) {
  47     if (VM_Version::has_CompareBranch()) {
  48       z_cgij(receiver, 0, Assembler::bcondEqual, ic_miss);
  49     } else {
  50       z_ltgr(receiver, receiver);
  51       z_bre(ic_miss);
  52     }
  53   }
  54 


  79 }
  80 
  81 void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
  82   const int hdr_offset = oopDesc::mark_offset_in_bytes();
  83   assert_different_registers(hdr, obj, disp_hdr);
  84   NearLabel done;
  85 
  86   verify_oop(obj);
  87 
  88   // Load object header.
  89   z_lg(hdr, Address(obj, hdr_offset));
  90 
  91   // Save object being locked into the BasicObjectLock...
  92   z_stg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
  93 
  94   if (UseBiasedLocking) {
  95     biased_locking_enter(obj, hdr, Z_R1_scratch, Z_R0_scratch, done, &slow_case);
  96   }
  97 
  98   // and mark it as unlocked.
  99   z_oill(hdr, markWord::unlocked_value);
 100   // Save unlocked object header into the displaced header location on the stack.
 101   z_stg(hdr, Address(disp_hdr, (intptr_t)0));
 102   // Test if object header is still the same (i.e. unlocked), and if so, store the
 103   // displaced header address in the object header. If it is not the same, get the
 104   // object header instead.
 105   z_csg(hdr, disp_hdr, hdr_offset, obj);
 106   // If the object header was the same, we're done.
 107   if (PrintBiasedLockingStatistics) {
 108     Unimplemented();
 109 #if 0
 110     cond_inc32(Assembler::equal,
 111                ExternalAddress((address)BiasedLocking::fast_path_entry_count_addr()));
 112 #endif
 113   }
 114   branch_optimized(Assembler::bcondEqual, done);
 115   // If the object header was not the same, it is now in the hdr register.
 116   // => Test if it is a stack pointer into the same stack (recursive locking), i.e.:
 117   //
 118   // 1) (hdr & markWord::lock_mask_in_place) == 0
 119   // 2) rsp <= hdr
 120   // 3) hdr <= rsp + page_size
 121   //
 122   // These 3 tests can be done by evaluating the following expression:
 123   //
 124   // (hdr - Z_SP) & (~(page_size-1) | markWord::lock_mask_in_place)
 125   //
 126   // assuming both the stack pointer and page_size have their least
 127   // significant 2 bits cleared and page_size is a power of 2
 128   z_sgr(hdr, Z_SP);
 129 
 130   load_const_optimized(Z_R0_scratch, (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
 131   z_ngr(hdr, Z_R0_scratch); // AND sets CC (result eq/ne 0).
 132   // For recursive locking, the result is zero. => Save it in the displaced header
 133   // location (NULL in the displaced hdr location indicates recursive locking).
 134   z_stg(hdr, Address(disp_hdr, (intptr_t)0));
 135   // Otherwise we don't care about the result and handle locking via runtime call.
 136   branch_optimized(Assembler::bcondNotZero, slow_case);
 137   // done
 138   bind(done);
 139 }
 140 
 141 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
 142   const int aligned_mask = BytesPerWord -1;
 143   const int hdr_offset = oopDesc::mark_offset_in_bytes();
 144   assert_different_registers(hdr, obj, disp_hdr);
 145   NearLabel done;
 146 
 147   if (UseBiasedLocking) {
 148     // Load object.
 149     z_lg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
 150     biased_locking_exit(obj, hdr, done);


 175   Register var_size_in_bytes,          // Object size in bytes if unknown at compile time; invalid otherwise.
 176   int      con_size_in_bytes,          // Object size in bytes if   known at compile time.
 177   Register t1,                         // Temp register: Must be global register for incr_allocated_bytes.
 178   Label&   slow_case                   // Continuation point if fast allocation fails.
 179 ) {
 180   if (UseTLAB) {
 181     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
 182   } else {
 183     // Allocation in shared Eden not implemented, because sapjvm allocation trace does not allow it.
 184     z_brul(slow_case);
 185   }
 186 }
 187 
 188 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register Rzero, Register t1) {
 189   assert_different_registers(obj, klass, len, t1, Rzero);
 190   if (UseBiasedLocking && !len->is_valid()) {
 191     assert_different_registers(obj, klass, len, t1);
 192     z_lg(t1, Address(klass, Klass::prototype_header_offset()));
 193   } else {
 194     // This assumes that all prototype bits fit in an int32_t.
 195     load_const_optimized(t1, (intx)markWord::prototype().value());
 196   }
 197   z_stg(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
 198 
 199   if (len->is_valid()) {
 200     // Length will be in the klass gap, if one exists.
 201     z_st(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
 202   } else if (UseCompressedClassPointers) {
 203     store_klass_gap(Rzero, obj);  // Zero klass gap for compressed oops.
 204   }
 205   store_klass(klass, obj, t1);
 206 }
 207 
 208 void C1_MacroAssembler::initialize_body(Register objectFields, Register len_in_bytes, Register Rzero) {
 209   Label done;
 210   assert_different_registers(objectFields, len_in_bytes, Rzero);
 211 
 212   // Initialize object fields.
 213   // See documentation for MVCLE instruction!!!
 214   assert(objectFields->encoding()%2==0, "objectFields must be an even register");
 215   assert(len_in_bytes->encoding() == (objectFields->encoding()+1), "objectFields and len_in_bytes must be a register pair");




  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "c1/c1_MacroAssembler.hpp"
  29 #include "c1/c1_Runtime1.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 #include "oops/arrayOop.hpp"
  34 #include "oops/markOop.hpp"
  35 #include "runtime/basicLock.hpp"
  36 #include "runtime/biasedLocking.hpp"
  37 #include "runtime/os.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/stubRoutines.hpp"
  40 
  41 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
  42   Label ic_miss, ic_hit;
  43   verify_oop(receiver);
  44   int klass_offset = oopDesc::klass_offset_in_bytes();
  45 
  46   if (!ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(klass_offset)) {
  47     if (VM_Version::has_CompareBranch()) {
  48       z_cgij(receiver, 0, Assembler::bcondEqual, ic_miss);
  49     } else {
  50       z_ltgr(receiver, receiver);
  51       z_bre(ic_miss);
  52     }
  53   }
  54 


  79 }
  80 
  81 void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
  82   const int hdr_offset = oopDesc::mark_offset_in_bytes();
  83   assert_different_registers(hdr, obj, disp_hdr);
  84   NearLabel done;
  85 
  86   verify_oop(obj);
  87 
  88   // Load object header.
  89   z_lg(hdr, Address(obj, hdr_offset));
  90 
  91   // Save object being locked into the BasicObjectLock...
  92   z_stg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
  93 
  94   if (UseBiasedLocking) {
  95     biased_locking_enter(obj, hdr, Z_R1_scratch, Z_R0_scratch, done, &slow_case);
  96   }
  97 
  98   // and mark it as unlocked.
  99   z_oill(hdr, markOopDesc::unlocked_value);
 100   // Save unlocked object header into the displaced header location on the stack.
 101   z_stg(hdr, Address(disp_hdr, (intptr_t)0));
 102   // Test if object header is still the same (i.e. unlocked), and if so, store the
 103   // displaced header address in the object header. If it is not the same, get the
 104   // object header instead.
 105   z_csg(hdr, disp_hdr, hdr_offset, obj);
 106   // If the object header was the same, we're done.
 107   if (PrintBiasedLockingStatistics) {
 108     Unimplemented();
 109 #if 0
 110     cond_inc32(Assembler::equal,
 111                ExternalAddress((address)BiasedLocking::fast_path_entry_count_addr()));
 112 #endif
 113   }
 114   branch_optimized(Assembler::bcondEqual, done);
 115   // If the object header was not the same, it is now in the hdr register.
 116   // => Test if it is a stack pointer into the same stack (recursive locking), i.e.:
 117   //
 118   // 1) (hdr & markOopDesc::lock_mask_in_place) == 0
 119   // 2) rsp <= hdr
 120   // 3) hdr <= rsp + page_size
 121   //
 122   // These 3 tests can be done by evaluating the following expression:
 123   //
 124   // (hdr - Z_SP) & (~(page_size-1) | markOopDesc::lock_mask_in_place)
 125   //
 126   // assuming both the stack pointer and page_size have their least
 127   // significant 2 bits cleared and page_size is a power of 2
 128   z_sgr(hdr, Z_SP);
 129 
 130   load_const_optimized(Z_R0_scratch, (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
 131   z_ngr(hdr, Z_R0_scratch); // AND sets CC (result eq/ne 0).
 132   // For recursive locking, the result is zero. => Save it in the displaced header
 133   // location (NULL in the displaced hdr location indicates recursive locking).
 134   z_stg(hdr, Address(disp_hdr, (intptr_t)0));
 135   // Otherwise we don't care about the result and handle locking via runtime call.
 136   branch_optimized(Assembler::bcondNotZero, slow_case);
 137   // done
 138   bind(done);
 139 }
 140 
 141 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
 142   const int aligned_mask = BytesPerWord -1;
 143   const int hdr_offset = oopDesc::mark_offset_in_bytes();
 144   assert_different_registers(hdr, obj, disp_hdr);
 145   NearLabel done;
 146 
 147   if (UseBiasedLocking) {
 148     // Load object.
 149     z_lg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
 150     biased_locking_exit(obj, hdr, done);


 175   Register var_size_in_bytes,          // Object size in bytes if unknown at compile time; invalid otherwise.
 176   int      con_size_in_bytes,          // Object size in bytes if   known at compile time.
 177   Register t1,                         // Temp register: Must be global register for incr_allocated_bytes.
 178   Label&   slow_case                   // Continuation point if fast allocation fails.
 179 ) {
 180   if (UseTLAB) {
 181     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
 182   } else {
 183     // Allocation in shared Eden not implemented, because sapjvm allocation trace does not allow it.
 184     z_brul(slow_case);
 185   }
 186 }
 187 
 188 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register Rzero, Register t1) {
 189   assert_different_registers(obj, klass, len, t1, Rzero);
 190   if (UseBiasedLocking && !len->is_valid()) {
 191     assert_different_registers(obj, klass, len, t1);
 192     z_lg(t1, Address(klass, Klass::prototype_header_offset()));
 193   } else {
 194     // This assumes that all prototype bits fit in an int32_t.
 195     load_const_optimized(t1, (intx)markOopDesc::prototype());
 196   }
 197   z_stg(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
 198 
 199   if (len->is_valid()) {
 200     // Length will be in the klass gap, if one exists.
 201     z_st(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
 202   } else if (UseCompressedClassPointers) {
 203     store_klass_gap(Rzero, obj);  // Zero klass gap for compressed oops.
 204   }
 205   store_klass(klass, obj, t1);
 206 }
 207 
 208 void C1_MacroAssembler::initialize_body(Register objectFields, Register len_in_bytes, Register Rzero) {
 209   Label done;
 210   assert_different_registers(objectFields, len_in_bytes, Rzero);
 211 
 212   // Initialize object fields.
 213   // See documentation for MVCLE instruction!!!
 214   assert(objectFields->encoding()%2==0, "objectFields must be an even register");
 215   assert(len_in_bytes->encoding() == (objectFields->encoding()+1), "objectFields and len_in_bytes must be a register pair");


< prev index next >