< prev index next >

src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp

Print this page

  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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 "c1/c1_MacroAssembler.hpp"
 27 #include "c1/c1_Runtime1.hpp"
 28 #include "gc/shared/barrierSet.hpp"
 29 #include "gc/shared/barrierSetAssembler.hpp"
 30 #include "gc/shared/collectedHeap.hpp"
 31 #include "gc/shared/tlab_globals.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "oops/arrayOop.hpp"
 34 #include "oops/markWord.hpp"
 35 #include "runtime/basicLock.hpp"
 36 #include "runtime/os.hpp"
 37 #include "runtime/sharedRuntime.hpp"
 38 #include "runtime/stubRoutines.hpp"
 39 
 40 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
 41   const Register rklass_decode_tmp = LP64_ONLY(rscratch1) NOT_LP64(noreg);
 42   const int aligned_mask = BytesPerWord -1;
 43   const int hdr_offset = oopDesc::mark_offset_in_bytes();
 44   assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
 45   assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");

 78   //
 79   // 1) (hdr & aligned_mask) == 0
 80   // 2) rsp <= hdr
 81   // 3) hdr <= rsp + page_size
 82   //
 83   // these 3 tests can be done by evaluating the following expression:
 84   //
 85   // (hdr - rsp) & (aligned_mask - page_size)
 86   //
 87   // assuming both the stack pointer and page_size have their least
 88   // significant 2 bits cleared and page_size is a power of 2
 89   subptr(hdr, rsp);
 90   andptr(hdr, aligned_mask - os::vm_page_size());
 91   // for recursive locking, the result is zero => save it in the displaced header
 92   // location (NULL in the displaced hdr location indicates recursive locking)
 93   movptr(Address(disp_hdr, 0), hdr);
 94   // otherwise we don't care about the result and handle locking via runtime call
 95   jcc(Assembler::notZero, slow_case);
 96   // done
 97   bind(done);

 98   return null_check_offset;
 99 }
100 
101 
102 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
103   const int aligned_mask = BytesPerWord -1;
104   const int hdr_offset = oopDesc::mark_offset_in_bytes();
105   assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction");
106   assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
107   Label done;
108 
109   // load displaced header
110   movptr(hdr, Address(disp_hdr, 0));
111   // if the loaded hdr is NULL we had recursive locking
112   testptr(hdr, hdr);
113   // if we had recursive locking, we are done
114   jcc(Assembler::zero, done);
115   // load object
116   movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
117 

340     // Also first instruction will be one byte "push(rbp)" if stack banging
341     // code is not generated (see build_frame() above).
342     // For all these cases generate long instruction first.
343     fat_nop();
344   }
345   if (C1Breakpoint)int3();
346   // build frame
347   IA32_ONLY( verify_FPU(0, "method_entry"); )
348 }
349 
350 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
351   // rbp, + 0: link
352   //     + 1: return address
353   //     + 2: argument with offset 0
354   //     + 3: argument with offset 1
355   //     + 4: ...
356 
357   movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
358 }
359 




360 #ifndef PRODUCT
361 
362 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
363   if (!VerifyOops) return;
364   verify_oop_addr(Address(rsp, stack_offset));
365 }
366 
367 void C1_MacroAssembler::verify_not_null_oop(Register r) {
368   if (!VerifyOops) return;
369   Label not_null;
370   testptr(r, r);
371   jcc(Assembler::notZero, not_null);
372   stop("non-null oop required");
373   bind(not_null);
374   verify_oop(r);
375 }
376 
377 void C1_MacroAssembler::invalidate_registers(bool inv_rax, bool inv_rbx, bool inv_rcx, bool inv_rdx, bool inv_rsi, bool inv_rdi) {
378 #ifdef ASSERT
379   if (inv_rax) movptr(rax, 0xDEAD);

  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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 "c1/c1_IR.hpp"
 27 #include "c1/c1_MacroAssembler.hpp"
 28 #include "c1/c1_Runtime1.hpp"
 29 #include "gc/shared/barrierSet.hpp"
 30 #include "gc/shared/barrierSetAssembler.hpp"
 31 #include "gc/shared/collectedHeap.hpp"
 32 #include "gc/shared/tlab_globals.hpp"
 33 #include "interpreter/interpreter.hpp"
 34 #include "oops/arrayOop.hpp"
 35 #include "oops/markWord.hpp"
 36 #include "runtime/basicLock.hpp"
 37 #include "runtime/os.hpp"
 38 #include "runtime/sharedRuntime.hpp"
 39 #include "runtime/stubRoutines.hpp"
 40 
 41 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
 42   const Register rklass_decode_tmp = LP64_ONLY(rscratch1) NOT_LP64(noreg);
 43   const int aligned_mask = BytesPerWord -1;
 44   const int hdr_offset = oopDesc::mark_offset_in_bytes();
 45   assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
 46   assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");

 79   //
 80   // 1) (hdr & aligned_mask) == 0
 81   // 2) rsp <= hdr
 82   // 3) hdr <= rsp + page_size
 83   //
 84   // these 3 tests can be done by evaluating the following expression:
 85   //
 86   // (hdr - rsp) & (aligned_mask - page_size)
 87   //
 88   // assuming both the stack pointer and page_size have their least
 89   // significant 2 bits cleared and page_size is a power of 2
 90   subptr(hdr, rsp);
 91   andptr(hdr, aligned_mask - os::vm_page_size());
 92   // for recursive locking, the result is zero => save it in the displaced header
 93   // location (NULL in the displaced hdr location indicates recursive locking)
 94   movptr(Address(disp_hdr, 0), hdr);
 95   // otherwise we don't care about the result and handle locking via runtime call
 96   jcc(Assembler::notZero, slow_case);
 97   // done
 98   bind(done);
 99   
100   return null_check_offset;
101 }
102 
103 
104 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
105   const int aligned_mask = BytesPerWord -1;
106   const int hdr_offset = oopDesc::mark_offset_in_bytes();
107   assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction");
108   assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
109   Label done;
110 
111   // load displaced header
112   movptr(hdr, Address(disp_hdr, 0));
113   // if the loaded hdr is NULL we had recursive locking
114   testptr(hdr, hdr);
115   // if we had recursive locking, we are done
116   jcc(Assembler::zero, done);
117   // load object
118   movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
119 

342     // Also first instruction will be one byte "push(rbp)" if stack banging
343     // code is not generated (see build_frame() above).
344     // For all these cases generate long instruction first.
345     fat_nop();
346   }
347   if (C1Breakpoint)int3();
348   // build frame
349   IA32_ONLY( verify_FPU(0, "method_entry"); )
350 }
351 
352 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
353   // rbp, + 0: link
354   //     + 1: return address
355   //     + 2: argument with offset 0
356   //     + 3: argument with offset 1
357   //     + 4: ...
358 
359   movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
360 }
361 
362 void C1_MacroAssembler::oopmap_metadata(CodeEmitInfo* info) {
363   MacroAssembler::oopmap_metadata(info != NULL ? info->oop_map()->index() : -1);
364 }
365 
366 #ifndef PRODUCT
367 
368 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
369   if (!VerifyOops) return;
370   verify_oop_addr(Address(rsp, stack_offset));
371 }
372 
373 void C1_MacroAssembler::verify_not_null_oop(Register r) {
374   if (!VerifyOops) return;
375   Label not_null;
376   testptr(r, r);
377   jcc(Assembler::notZero, not_null);
378   stop("non-null oop required");
379   bind(not_null);
380   verify_oop(r);
381 }
382 
383 void C1_MacroAssembler::invalidate_registers(bool inv_rax, bool inv_rbx, bool inv_rcx, bool inv_rdx, bool inv_rsi, bool inv_rdi) {
384 #ifdef ASSERT
385   if (inv_rax) movptr(rax, 0xDEAD);
< prev index next >