< prev index next >

src/hotspot/cpu/sparc/interp_masm_sparc.cpp

Print this page




  12  * version 2 for more details (a copy is included in the LICENSE file that
  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 "interp_masm_sparc.hpp"
  28 #include "interpreter/interpreter.hpp"
  29 #include "interpreter/interpreterRuntime.hpp"
  30 #include "logging/log.hpp"
  31 #include "oops/arrayOop.hpp"
  32 #include "oops/markWord.hpp"
  33 #include "oops/methodData.hpp"
  34 #include "oops/method.hpp"
  35 #include "oops/methodCounters.hpp"
  36 #include "prims/jvmtiExport.hpp"
  37 #include "prims/jvmtiThreadState.hpp"
  38 #include "runtime/basicLock.hpp"
  39 #include "runtime/biasedLocking.hpp"
  40 #include "runtime/frame.inline.hpp"
  41 #include "runtime/safepointMechanism.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #include "runtime/thread.inline.hpp"
  44 #include "utilities/align.hpp"
  45 
  46 // Implementation of InterpreterMacroAssembler
  47 
  48 // This file specializes the assember with interpreter-specific macros
  49 
  50 const Address InterpreterMacroAssembler::l_tmp(FP, (frame::interpreter_frame_l_scratch_fp_offset * wordSize) + STACK_BIAS);
  51 const Address InterpreterMacroAssembler::d_tmp(FP, (frame::interpreter_frame_d_scratch_fp_offset * wordSize) + STACK_BIAS);
  52 


1183 // Lock object
1184 //
1185 // Argument - lock_reg points to the BasicObjectLock to be used for locking,
1186 //            it must be initialized with the object to lock
1187 void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object) {
1188   if (UseHeavyMonitors) {
1189     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg);
1190   }
1191   else {
1192     Register obj_reg = Object;
1193     Register mark_reg = G4_scratch;
1194     Register temp_reg = G1_scratch;
1195     Address  lock_addr(lock_reg, BasicObjectLock::lock_offset_in_bytes());
1196     Address  mark_addr(obj_reg, oopDesc::mark_offset_in_bytes());
1197     Label    done;
1198 
1199     Label slow_case;
1200 
1201     assert_different_registers(lock_reg, obj_reg, mark_reg, temp_reg);
1202 
1203     // load markWord from object into mark_reg
1204     ld_ptr(mark_addr, mark_reg);
1205 
1206     if (UseBiasedLocking) {
1207       biased_locking_enter(obj_reg, mark_reg, temp_reg, done, &slow_case);
1208     }
1209 
1210     // get the address of basicLock on stack that will be stored in the object
1211     // we need a temporary register here as we do not want to clobber lock_reg
1212     // (cas clobbers the destination register)
1213     mov(lock_reg, temp_reg);
1214     // set mark reg to be (markWord of object | UNLOCK_VALUE)
1215     or3(mark_reg, markWord::unlocked_value, mark_reg);
1216     // initialize the box  (Must happen before we update the object mark!)
1217     st_ptr(mark_reg, lock_addr, BasicLock::displaced_header_offset_in_bytes());
1218     // compare and exchange object_addr, markWord | 1, stack address of basicLock
1219     assert(mark_addr.disp() == 0, "cas must take a zero displacement");
1220     cas_ptr(mark_addr.base(), mark_reg, temp_reg);
1221 
1222     // if the compare and exchange succeeded we are done (we saw an unlocked object)
1223     cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
1224 
1225     // We did not see an unlocked object so try the fast recursive case
1226 
1227     // Check if owner is self by comparing the value in the markWord of object
1228     // with the stack pointer
1229     sub(temp_reg, SP, temp_reg);
1230     sub(temp_reg, STACK_BIAS, temp_reg);
1231     assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
1232 
1233     // Composite "andcc" test:
1234     // (a) %sp -vs- markword proximity check, and,
1235     // (b) verify mark word LSBs == 0 (Stack-locked).
1236     //
1237     // FFFFF003/FFFFFFFFFFFF003 is (markWord::lock_mask_in_place | -os::vm_page_size())
1238     // Note that the page size used for %sp proximity testing is arbitrary and is
1239     // unrelated to the actual MMU page size.  We use a 'logical' page size of
1240     // 4096 bytes.   F..FFF003 is designed to fit conveniently in the SIMM13 immediate
1241     // field of the andcc instruction.
1242     andcc (temp_reg, 0xFFFFF003, G0) ;
1243 
1244     // if condition is true we are done and hence we can store 0 in the displaced
1245     // header indicating it is a recursive lock and be done
1246     brx(Assembler::zero, true, Assembler::pt, done);
1247     delayed()->st_ptr(G0, lock_addr, BasicLock::displaced_header_offset_in_bytes());
1248 
1249     // none of the above fast optimizations worked so we have to get into the
1250     // slow case of monitor enter
1251     bind(slow_case);
1252     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg);
1253 
1254     bind(done);
1255   }
1256 }
1257 




  12  * version 2 for more details (a copy is included in the LICENSE file that
  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 "interp_masm_sparc.hpp"
  28 #include "interpreter/interpreter.hpp"
  29 #include "interpreter/interpreterRuntime.hpp"
  30 #include "logging/log.hpp"
  31 #include "oops/arrayOop.hpp"
  32 #include "oops/markOop.hpp"
  33 #include "oops/methodData.hpp"
  34 #include "oops/method.hpp"
  35 #include "oops/methodCounters.hpp"
  36 #include "prims/jvmtiExport.hpp"
  37 #include "prims/jvmtiThreadState.hpp"
  38 #include "runtime/basicLock.hpp"
  39 #include "runtime/biasedLocking.hpp"
  40 #include "runtime/frame.inline.hpp"
  41 #include "runtime/safepointMechanism.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #include "runtime/thread.inline.hpp"
  44 #include "utilities/align.hpp"
  45 
  46 // Implementation of InterpreterMacroAssembler
  47 
  48 // This file specializes the assember with interpreter-specific macros
  49 
  50 const Address InterpreterMacroAssembler::l_tmp(FP, (frame::interpreter_frame_l_scratch_fp_offset * wordSize) + STACK_BIAS);
  51 const Address InterpreterMacroAssembler::d_tmp(FP, (frame::interpreter_frame_d_scratch_fp_offset * wordSize) + STACK_BIAS);
  52 


1183 // Lock object
1184 //
1185 // Argument - lock_reg points to the BasicObjectLock to be used for locking,
1186 //            it must be initialized with the object to lock
1187 void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object) {
1188   if (UseHeavyMonitors) {
1189     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg);
1190   }
1191   else {
1192     Register obj_reg = Object;
1193     Register mark_reg = G4_scratch;
1194     Register temp_reg = G1_scratch;
1195     Address  lock_addr(lock_reg, BasicObjectLock::lock_offset_in_bytes());
1196     Address  mark_addr(obj_reg, oopDesc::mark_offset_in_bytes());
1197     Label    done;
1198 
1199     Label slow_case;
1200 
1201     assert_different_registers(lock_reg, obj_reg, mark_reg, temp_reg);
1202 
1203     // load markOop from object into mark_reg
1204     ld_ptr(mark_addr, mark_reg);
1205 
1206     if (UseBiasedLocking) {
1207       biased_locking_enter(obj_reg, mark_reg, temp_reg, done, &slow_case);
1208     }
1209 
1210     // get the address of basicLock on stack that will be stored in the object
1211     // we need a temporary register here as we do not want to clobber lock_reg
1212     // (cas clobbers the destination register)
1213     mov(lock_reg, temp_reg);
1214     // set mark reg to be (markOop of object | UNLOCK_VALUE)
1215     or3(mark_reg, markOopDesc::unlocked_value, mark_reg);
1216     // initialize the box  (Must happen before we update the object mark!)
1217     st_ptr(mark_reg, lock_addr, BasicLock::displaced_header_offset_in_bytes());
1218     // compare and exchange object_addr, markOop | 1, stack address of basicLock
1219     assert(mark_addr.disp() == 0, "cas must take a zero displacement");
1220     cas_ptr(mark_addr.base(), mark_reg, temp_reg);
1221 
1222     // if the compare and exchange succeeded we are done (we saw an unlocked object)
1223     cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
1224 
1225     // We did not see an unlocked object so try the fast recursive case
1226 
1227     // Check if owner is self by comparing the value in the markOop of object
1228     // with the stack pointer
1229     sub(temp_reg, SP, temp_reg);
1230     sub(temp_reg, STACK_BIAS, temp_reg);
1231     assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
1232 
1233     // Composite "andcc" test:
1234     // (a) %sp -vs- markword proximity check, and,
1235     // (b) verify mark word LSBs == 0 (Stack-locked).
1236     //
1237     // FFFFF003/FFFFFFFFFFFF003 is (markOopDesc::lock_mask_in_place | -os::vm_page_size())
1238     // Note that the page size used for %sp proximity testing is arbitrary and is
1239     // unrelated to the actual MMU page size.  We use a 'logical' page size of
1240     // 4096 bytes.   F..FFF003 is designed to fit conveniently in the SIMM13 immediate
1241     // field of the andcc instruction.
1242     andcc (temp_reg, 0xFFFFF003, G0) ;
1243 
1244     // if condition is true we are done and hence we can store 0 in the displaced
1245     // header indicating it is a recursive lock and be done
1246     brx(Assembler::zero, true, Assembler::pt, done);
1247     delayed()->st_ptr(G0, lock_addr, BasicLock::displaced_header_offset_in_bytes());
1248 
1249     // none of the above fast optimizations worked so we have to get into the
1250     // slow case of monitor enter
1251     bind(slow_case);
1252     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), lock_reg);
1253 
1254     bind(done);
1255   }
1256 }
1257 


< prev index next >