< prev index next >

src/hotspot/cpu/sparc/c1_MacroAssembler_sparc.cpp

Print this page




  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.inline.hpp"
  27 #include "c1/c1_MacroAssembler.hpp"
  28 #include "c1/c1_Runtime1.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "oops/arrayOop.hpp"
  33 #include "oops/markWord.hpp"
  34 #include "runtime/basicLock.hpp"
  35 #include "runtime/biasedLocking.hpp"
  36 #include "runtime/os.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 #include "runtime/stubRoutines.hpp"
  39 
  40 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
  41   Label L;
  42   const Register temp_reg = G3_scratch;
  43   // Note: needs more testing of out-of-line vs. inline slow case
  44   verify_oop(receiver);
  45   load_klass(receiver, temp_reg);
  46   cmp_and_brx_short(temp_reg, iCache, Assembler::equal, Assembler::pt, L);
  47   AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
  48   jump_to(ic_miss, temp_reg);
  49   delayed()->nop();
  50   align(CodeEntryAlignment);
  51   bind(L);
  52 }
  53 


  80   Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
  81 
  82   // The following move must be the first instruction of emitted since debug
  83   // information may be generated for it.
  84   // Load object header
  85   ld_ptr(mark_addr, Rmark);
  86 
  87   verify_oop(Roop);
  88 
  89   // save object being locked into the BasicObjectLock
  90   st_ptr(Roop, Rbox, BasicObjectLock::obj_offset_in_bytes());
  91 
  92   if (UseBiasedLocking) {
  93     biased_locking_enter(Roop, Rmark, Rscratch, done, &slow_case);
  94   }
  95 
  96   // Save Rbox in Rscratch to be used for the cas operation
  97   mov(Rbox, Rscratch);
  98 
  99   // and mark it unlocked
 100   or3(Rmark, markWord::unlocked_value, Rmark);
 101 
 102   // save unlocked object header into the displaced header location on the stack
 103   st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());
 104 
 105   // compare object markWord with Rmark and if equal exchange Rscratch with object markWord
 106   assert(mark_addr.disp() == 0, "cas must take a zero displacement");
 107   cas_ptr(mark_addr.base(), Rmark, Rscratch);
 108   // if compare/exchange succeeded we found an unlocked object and we now have locked it
 109   // hence we are done
 110   cmp(Rmark, Rscratch);
 111   brx(Assembler::equal, false, Assembler::pt, done);
 112   delayed()->sub(Rscratch, SP, Rscratch);  //pull next instruction into delay slot
 113   // we did not find an unlocked object so see if this is a recursive case
 114   // sub(Rscratch, SP, Rscratch);
 115   assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
 116   andcc(Rscratch, 0xfffff003, Rscratch);
 117   brx(Assembler::notZero, false, Assembler::pn, slow_case);
 118   delayed()->st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
 119   bind(done);
 120 }
 121 
 122 
 123 void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
 124   assert_different_registers(Rmark, Roop, Rbox);
 125 


 127 
 128   Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
 129   assert(mark_addr.disp() == 0, "cas must take a zero displacement");
 130 
 131   if (UseBiasedLocking) {
 132     // load the object out of the BasicObjectLock
 133     ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
 134     verify_oop(Roop);
 135     biased_locking_exit(mark_addr, Rmark, done);
 136   }
 137   // Test first it it is a fast recursive unlock
 138   ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
 139   br_null_short(Rmark, Assembler::pt, done);
 140   if (!UseBiasedLocking) {
 141     // load object
 142     ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
 143     verify_oop(Roop);
 144   }
 145 
 146   // Check if it is still a light weight lock, this is is true if we see
 147   // the stack address of the basicLock in the markWord of the object
 148   cas_ptr(mark_addr.base(), Rbox, Rmark);
 149   cmp(Rbox, Rmark);
 150 
 151   brx(Assembler::notEqual, false, Assembler::pn, slow_case);
 152   delayed()->nop();
 153   // Done
 154   bind(done);
 155 }
 156 
 157 
 158 void C1_MacroAssembler::try_allocate(
 159   Register obj,                        // result: pointer to object after successful allocation
 160   Register var_size_in_bytes,          // object size in bytes if unknown at compile time; invalid otherwise
 161   int      con_size_in_bytes,          // object size in bytes if   known at compile time
 162   Register t1,                         // temp register, must be global register for incr_allocated_bytes
 163   Register t2,                         // temp register
 164   Label&   slow_case                   // continuation point if fast allocation fails
 165 ) {
 166   RegisterOrConstant size_in_bytes = var_size_in_bytes->is_valid()
 167     ? RegisterOrConstant(var_size_in_bytes) : RegisterOrConstant(con_size_in_bytes);
 168   if (UseTLAB) {
 169     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
 170   } else {
 171     eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
 172     incr_allocated_bytes(size_in_bytes, t1, t2);
 173   }
 174 }
 175 
 176 
 177 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
 178   assert_different_registers(obj, klass, len, t1, t2);
 179   if (UseBiasedLocking && !len->is_valid()) {
 180     ld_ptr(klass, in_bytes(Klass::prototype_header_offset()), t1);
 181   } else {
 182     set((intx)markWord::prototype().value(), t1);
 183   }
 184   st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
 185   if (UseCompressedClassPointers) {
 186     // Save klass
 187     mov(klass, t1);
 188     encode_klass_not_null(t1);
 189     stw(t1, obj, oopDesc::klass_offset_in_bytes());
 190   } else {
 191     st_ptr(klass, obj, oopDesc::klass_offset_in_bytes());
 192   }
 193   if (len->is_valid()) {
 194     st(len, obj, arrayOopDesc::length_offset_in_bytes());
 195   } else if (UseCompressedClassPointers) {
 196     // otherwise length is in the class gap
 197     store_klass_gap(G0, obj);
 198   }
 199 }
 200 
 201 
 202 void C1_MacroAssembler::initialize_body(Register base, Register index) {




  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.inline.hpp"
  27 #include "c1/c1_MacroAssembler.hpp"
  28 #include "c1/c1_Runtime1.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "oops/arrayOop.hpp"
  33 #include "oops/markOop.hpp"
  34 #include "runtime/basicLock.hpp"
  35 #include "runtime/biasedLocking.hpp"
  36 #include "runtime/os.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 #include "runtime/stubRoutines.hpp"
  39 
  40 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
  41   Label L;
  42   const Register temp_reg = G3_scratch;
  43   // Note: needs more testing of out-of-line vs. inline slow case
  44   verify_oop(receiver);
  45   load_klass(receiver, temp_reg);
  46   cmp_and_brx_short(temp_reg, iCache, Assembler::equal, Assembler::pt, L);
  47   AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
  48   jump_to(ic_miss, temp_reg);
  49   delayed()->nop();
  50   align(CodeEntryAlignment);
  51   bind(L);
  52 }
  53 


  80   Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
  81 
  82   // The following move must be the first instruction of emitted since debug
  83   // information may be generated for it.
  84   // Load object header
  85   ld_ptr(mark_addr, Rmark);
  86 
  87   verify_oop(Roop);
  88 
  89   // save object being locked into the BasicObjectLock
  90   st_ptr(Roop, Rbox, BasicObjectLock::obj_offset_in_bytes());
  91 
  92   if (UseBiasedLocking) {
  93     biased_locking_enter(Roop, Rmark, Rscratch, done, &slow_case);
  94   }
  95 
  96   // Save Rbox in Rscratch to be used for the cas operation
  97   mov(Rbox, Rscratch);
  98 
  99   // and mark it unlocked
 100   or3(Rmark, markOopDesc::unlocked_value, Rmark);
 101 
 102   // save unlocked object header into the displaced header location on the stack
 103   st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());
 104 
 105   // compare object markOop with Rmark and if equal exchange Rscratch with object markOop
 106   assert(mark_addr.disp() == 0, "cas must take a zero displacement");
 107   cas_ptr(mark_addr.base(), Rmark, Rscratch);
 108   // if compare/exchange succeeded we found an unlocked object and we now have locked it
 109   // hence we are done
 110   cmp(Rmark, Rscratch);
 111   brx(Assembler::equal, false, Assembler::pt, done);
 112   delayed()->sub(Rscratch, SP, Rscratch);  //pull next instruction into delay slot
 113   // we did not find an unlocked object so see if this is a recursive case
 114   // sub(Rscratch, SP, Rscratch);
 115   assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
 116   andcc(Rscratch, 0xfffff003, Rscratch);
 117   brx(Assembler::notZero, false, Assembler::pn, slow_case);
 118   delayed()->st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
 119   bind(done);
 120 }
 121 
 122 
 123 void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
 124   assert_different_registers(Rmark, Roop, Rbox);
 125 


 127 
 128   Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
 129   assert(mark_addr.disp() == 0, "cas must take a zero displacement");
 130 
 131   if (UseBiasedLocking) {
 132     // load the object out of the BasicObjectLock
 133     ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
 134     verify_oop(Roop);
 135     biased_locking_exit(mark_addr, Rmark, done);
 136   }
 137   // Test first it it is a fast recursive unlock
 138   ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
 139   br_null_short(Rmark, Assembler::pt, done);
 140   if (!UseBiasedLocking) {
 141     // load object
 142     ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
 143     verify_oop(Roop);
 144   }
 145 
 146   // Check if it is still a light weight lock, this is is true if we see
 147   // the stack address of the basicLock in the markOop of the object
 148   cas_ptr(mark_addr.base(), Rbox, Rmark);
 149   cmp(Rbox, Rmark);
 150 
 151   brx(Assembler::notEqual, false, Assembler::pn, slow_case);
 152   delayed()->nop();
 153   // Done
 154   bind(done);
 155 }
 156 
 157 
 158 void C1_MacroAssembler::try_allocate(
 159   Register obj,                        // result: pointer to object after successful allocation
 160   Register var_size_in_bytes,          // object size in bytes if unknown at compile time; invalid otherwise
 161   int      con_size_in_bytes,          // object size in bytes if   known at compile time
 162   Register t1,                         // temp register, must be global register for incr_allocated_bytes
 163   Register t2,                         // temp register
 164   Label&   slow_case                   // continuation point if fast allocation fails
 165 ) {
 166   RegisterOrConstant size_in_bytes = var_size_in_bytes->is_valid()
 167     ? RegisterOrConstant(var_size_in_bytes) : RegisterOrConstant(con_size_in_bytes);
 168   if (UseTLAB) {
 169     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
 170   } else {
 171     eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
 172     incr_allocated_bytes(size_in_bytes, t1, t2);
 173   }
 174 }
 175 
 176 
 177 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
 178   assert_different_registers(obj, klass, len, t1, t2);
 179   if (UseBiasedLocking && !len->is_valid()) {
 180     ld_ptr(klass, in_bytes(Klass::prototype_header_offset()), t1);
 181   } else {
 182     set((intx)markOopDesc::prototype(), t1);
 183   }
 184   st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
 185   if (UseCompressedClassPointers) {
 186     // Save klass
 187     mov(klass, t1);
 188     encode_klass_not_null(t1);
 189     stw(t1, obj, oopDesc::klass_offset_in_bytes());
 190   } else {
 191     st_ptr(klass, obj, oopDesc::klass_offset_in_bytes());
 192   }
 193   if (len->is_valid()) {
 194     st(len, obj, arrayOopDesc::length_offset_in_bytes());
 195   } else if (UseCompressedClassPointers) {
 196     // otherwise length is in the class gap
 197     store_klass_gap(G0, obj);
 198   }
 199 }
 200 
 201 
 202 void C1_MacroAssembler::initialize_body(Register base, Register index) {


< prev index next >