< prev index next >

src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp

Print this page




  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  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 "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::float_cmp(bool is_float, int unordered_result,
  41                                   FloatRegister f0, FloatRegister f1,
  42                                   Register result)
  43 {
  44   Label done;
  45   if (is_float) {
  46     fcmps(f0, f1);
  47   } else {
  48     fcmpd(f0, f1);
  49   }
  50   if (unordered_result < 0) {


  66   assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
  67   Label done;
  68   int null_check_offset = -1;
  69 
  70   verify_oop(obj);
  71 
  72   // save object being locked into the BasicObjectLock
  73   str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
  74 
  75   if (UseBiasedLocking) {
  76     assert(scratch != noreg, "should have scratch register at this point");
  77     null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
  78   } else {
  79     null_check_offset = offset();
  80   }
  81 
  82   // Load object header
  83   ldr(hdr, Address(obj, hdr_offset));
  84   // and mark it as unlocked
  85   orr(hdr, hdr, markOopDesc::unlocked_value);






  86   // save unlocked object header into the displaced header location on the stack
  87   str(hdr, Address(disp_hdr, 0));
  88   // test if object header is still the same (i.e. unlocked), and if so, store the
  89   // displaced header address in the object header - if it is not the same, get the
  90   // object header instead
  91   lea(rscratch2, Address(obj, hdr_offset));
  92   cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
  93   // if the object header was the same, we're done
  94   // if the object header was not the same, it is now in the hdr register
  95   // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
  96   //
  97   // 1) (hdr & aligned_mask) == 0
  98   // 2) sp <= hdr
  99   // 3) hdr <= sp + page_size
 100   //
 101   // these 3 tests can be done by evaluating the following expression:
 102   //
 103   // (hdr - sp) & (aligned_mask - page_size)
 104   //
 105   // assuming both the stack pointer and page_size have their least


 313 
 314   if (CURRENT_ENV->dtrace_alloc_probes()) {
 315     assert(obj == r0, "must be");
 316     far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
 317   }
 318 
 319   verify_oop(obj);
 320 }
 321 
 322 
 323 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
 324   verify_oop(receiver);
 325   // explicit NULL check not needed since load from [klass_offset] causes a trap
 326   // check against inline cache
 327   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
 328 
 329   cmp_klass(receiver, iCache, rscratch1);
 330 }
 331 
 332 
 333 void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) {


 334   // If we have to make this method not-entrant we'll overwrite its
 335   // first instruction with a jump.  For this action to be legal we
 336   // must ensure that this first instruction is a B, BL, NOP, BKPT,
 337   // SVC, HVC, or SMC.  Make it a NOP.
 338   nop();
 339   assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
 340   // Make sure there is enough stack space for this method's activation.
 341   // Note that we do this before doing an enter().
 342   generate_stack_overflow_check(bang_size_in_bytes);






 343   MacroAssembler::build_frame(framesize + 2 * wordSize);
 344   if (NotifySimulator) {
 345     notify(Assembler::method_entry);
 346   }
 347 }
 348 
 349 void C1_MacroAssembler::remove_frame(int framesize) {



 350   MacroAssembler::remove_frame(framesize + 2 * wordSize);
 351   if (NotifySimulator) {
 352     notify(Assembler::method_reentry);
 353   }
 354 }
 355 

















 356 
 357 void C1_MacroAssembler::verified_entry() {


 358 }

 359 
 360 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
 361   // rbp, + 0: link
 362   //     + 1: return address
 363   //     + 2: argument with offset 0
 364   //     + 3: argument with offset 1
 365   //     + 4: ...
 366 
 367   ldr(reg, Address(rfp, (offset_in_words + 2) * BytesPerWord));
 368 }
 369 
 370 #ifndef PRODUCT
 371 
 372 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
 373   if (!VerifyOops) return;
 374   verify_oop_addr(Address(sp, stack_offset), "oop");
 375 }
 376 
 377 void C1_MacroAssembler::verify_not_null_oop(Register r) {
 378   if (!VerifyOops) return;


  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  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 "c1/c1_MacroAssembler.hpp"
  28 #include "c1/c1_Runtime1.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "gc/shared/barrierSet.hpp"
  32 #include "gc/shared/barrierSetAssembler.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "oops/arrayOop.hpp"
  35 #include "oops/markOop.hpp"
  36 #include "runtime/basicLock.hpp"
  37 #include "runtime/biasedLocking.hpp"
  38 #include "runtime/os.hpp"
  39 #include "runtime/sharedRuntime.hpp"
  40 #include "runtime/stubRoutines.hpp"
  41 
  42 void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
  43                                   FloatRegister f0, FloatRegister f1,
  44                                   Register result)
  45 {
  46   Label done;
  47   if (is_float) {
  48     fcmps(f0, f1);
  49   } else {
  50     fcmpd(f0, f1);
  51   }
  52   if (unordered_result < 0) {


  68   assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
  69   Label done;
  70   int null_check_offset = -1;
  71 
  72   verify_oop(obj);
  73 
  74   // save object being locked into the BasicObjectLock
  75   str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
  76 
  77   if (UseBiasedLocking) {
  78     assert(scratch != noreg, "should have scratch register at this point");
  79     null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
  80   } else {
  81     null_check_offset = offset();
  82   }
  83 
  84   // Load object header
  85   ldr(hdr, Address(obj, hdr_offset));
  86   // and mark it as unlocked
  87   orr(hdr, hdr, markOopDesc::unlocked_value);
  88 
  89   if (EnableValhalla && !UseBiasedLocking) {
  90     // Mask always_locked bit such that we go to the slow path if object is a value type
  91     andr(hdr, hdr, ~markOopDesc::biased_lock_bit_in_place);
  92   }
  93 
  94   // save unlocked object header into the displaced header location on the stack
  95   str(hdr, Address(disp_hdr, 0));
  96   // test if object header is still the same (i.e. unlocked), and if so, store the
  97   // displaced header address in the object header - if it is not the same, get the
  98   // object header instead
  99   lea(rscratch2, Address(obj, hdr_offset));
 100   cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
 101   // if the object header was the same, we're done
 102   // if the object header was not the same, it is now in the hdr register
 103   // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
 104   //
 105   // 1) (hdr & aligned_mask) == 0
 106   // 2) sp <= hdr
 107   // 3) hdr <= sp + page_size
 108   //
 109   // these 3 tests can be done by evaluating the following expression:
 110   //
 111   // (hdr - sp) & (aligned_mask - page_size)
 112   //
 113   // assuming both the stack pointer and page_size have their least


 321 
 322   if (CURRENT_ENV->dtrace_alloc_probes()) {
 323     assert(obj == r0, "must be");
 324     far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
 325   }
 326 
 327   verify_oop(obj);
 328 }
 329 
 330 
 331 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
 332   verify_oop(receiver);
 333   // explicit NULL check not needed since load from [klass_offset] causes a trap
 334   // check against inline cache
 335   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
 336 
 337   cmp_klass(receiver, iCache, rscratch1);
 338 }
 339 
 340 
 341 void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes,  bool needs_stack_repair, Label* verified_value_entry_label) {
 342    
 343 
 344   // If we have to make this method not-entrant we'll overwrite its
 345   // first instruction with a jump.  For this action to be legal we
 346   // must ensure that this first instruction is a B, BL, NOP, BKPT,
 347   // SVC, HVC, or SMC.  Make it a NOP.
 348   nop();
 349   assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
 350   // Make sure there is enough stack space for this method's activation.
 351   // Note that we do this before doing an enter().
 352   generate_stack_overflow_check(bang_size_in_bytes);
 353 
 354   guarantee(needs_stack_repair == false, "Stack repair should not be true");
 355   if (verified_value_entry_label != NULL) {
 356     bind(*verified_value_entry_label);
 357   }
 358 
 359   MacroAssembler::build_frame(framesize + 2 * wordSize);
 360   if (NotifySimulator) {
 361     notify(Assembler::method_entry);
 362   }
 363 }
 364 
 365 void C1_MacroAssembler::remove_frame(int framesize, bool needs_stack_repair) {
 366 
 367   guarantee(needs_stack_repair == false, "Stack repair should not be true");
 368 
 369   MacroAssembler::remove_frame(framesize + 2 * wordSize);
 370   if (NotifySimulator) {
 371     notify(Assembler::method_reentry);
 372   }
 373 }
 374 
 375 void C1_MacroAssembler::verified_value_entry() {
 376   if (C1Breakpoint || VerifyFPU || !UseStackBanging) {
 377     // Verified Entry first instruction should be 5 bytes long for correct
 378     // patching by patch_verified_entry().
 379     //
 380     // C1Breakpoint and VerifyFPU have one byte first instruction.
 381     // Also first instruction will be one byte "push(rbp)" if stack banging
 382     // code is not generated (see build_frame() above).
 383     // For all these cases generate long instruction first.
 384     nop();
 385   }
 386   
 387   // build frame
 388   // DMS CHECK: is it nop?
 389   // verify_FPU(0, "method_entry");
 390  
 391 }
 392 
 393 int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature *ces, int frame_size_in_bytes, int bang_size_in_bytes, Label& verified_value_entry_label, bool is_value_ro_entry) {
 394   guarantee(false, "Support for ValueTypePassFieldsAsArgs and ValueTypeReturnedAsFields is not implemented");
 395   return 0;
 396 }
 397 
 398 
 399 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
 400   // rbp, + 0: link
 401   //     + 1: return address
 402   //     + 2: argument with offset 0
 403   //     + 3: argument with offset 1
 404   //     + 4: ...
 405 
 406   ldr(reg, Address(rfp, (offset_in_words + 2) * BytesPerWord));
 407 }
 408 
 409 #ifndef PRODUCT
 410 
 411 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
 412   if (!VerifyOops) return;
 413   verify_oop_addr(Address(sp, stack_offset), "oop");
 414 }
 415 
 416 void C1_MacroAssembler::verify_not_null_oop(Register r) {
 417   if (!VerifyOops) return;
< prev index next >