< prev index next >

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

Print this page
*** 264,29 ***
    // copied into place by code emitted in the IR.
  
    Register OSR_buf = osrBufferPointer()->as_pointer_register();
    { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
      int monitor_offset = BytesPerWord * method()->max_locals() +
!       (2 * BytesPerWord) * (number_of_locks - 1);
-     // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
-     // the OSR buffer using 2 word entries: first the lock and then
-     // the oop.
      for (int i = 0; i < number_of_locks; i++) {
!       int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
  #ifdef ASSERT
        // verify the interpreter's monitor has a non-null object
        {
          Label L;
!         __ ldr(rscratch1, Address(OSR_buf, slot_offset + 1*BytesPerWord));
          __ cbnz(rscratch1, L);
          __ stop("locked object is NULL");
          __ bind(L);
        }
  #endif
!       __ ldp(r19, r20, Address(OSR_buf, slot_offset));
!       __ str(r19, frame_map()->address_for_monitor_lock(i));
-       __ str(r20, frame_map()->address_for_monitor_object(i));
      }
    }
  }
  
  
--- 264,25 ---
    // copied into place by code emitted in the IR.
  
    Register OSR_buf = osrBufferPointer()->as_pointer_register();
    { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
      int monitor_offset = BytesPerWord * method()->max_locals() +
!       BytesPerWord * (number_of_locks - 1);
      for (int i = 0; i < number_of_locks; i++) {
!       int slot_offset = monitor_offset - (i * BytesPerWord);
  #ifdef ASSERT
        // verify the interpreter's monitor has a non-null object
        {
          Label L;
!         __ ldr(rscratch1, Address(OSR_buf, slot_offset));
          __ cbnz(rscratch1, L);
          __ stop("locked object is NULL");
          __ bind(L);
        }
  #endif
!       __ ldr(r19, Address(OSR_buf, slot_offset));
!       __ str(r19, frame_map()->address_for_monitor_object(i));
      }
    }
  }
  
  

*** 428,11 ***
  
    // Perform needed unlocking
    MonitorExitStub* stub = NULL;
    if (method()->is_synchronized()) {
      monitor_address(0, FrameMap::r0_opr);
!     stub = new MonitorExitStub(FrameMap::r0_opr, true, 0);
      if (UseHeavyMonitors) {
        __ b(*stub->entry());
      } else {
        __ unlock_object(r5, r4, r0, *stub->entry());
      }
--- 424,12 ---
  
    // Perform needed unlocking
    MonitorExitStub* stub = NULL;
    if (method()->is_synchronized()) {
      monitor_address(0, FrameMap::r0_opr);
!     __ ldr(r4, Address(r0, BasicObjectLock::obj_offset_in_bytes()));
+     stub = new MonitorExitStub(FrameMap::r4_opr);
      if (UseHeavyMonitors) {
        __ b(*stub->entry());
      } else {
        __ unlock_object(r5, r4, r0, *stub->entry());
      }

*** 1227,11 ***
      }
      __ allocate_array(op->obj()->as_register(),
                        len,
                        tmp1,
                        tmp2,
!                       arrayOopDesc::header_size(op->type()),
                        array_element_size(op->type()),
                        op->klass()->as_register(),
                        *op->stub()->entry());
    }
    __ bind(*op->stub()->continuation());
--- 1224,11 ---
      }
      __ allocate_array(op->obj()->as_register(),
                        len,
                        tmp1,
                        tmp2,
!                       arrayOopDesc::base_offset_in_bytes(op->type()),
                        array_element_size(op->type()),
                        op->klass()->as_register(),
                        *op->stub()->entry());
    }
    __ bind(*op->stub()->continuation());

*** 2285,12 ***
    int elem_size = type2aelembytes(basic_type);
    int scale = exact_log2(elem_size);
  
    Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
    Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
-   Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
-   Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
  
    // test for NULL
    if (flags & LIR_OpArrayCopy::src_null_check) {
      __ cbz(src, *stub->entry());
    }
--- 2282,10 ---

*** 2347,19 ***
  
    if (flags & LIR_OpArrayCopy::type_check) {
      // We don't know the array types are compatible
      if (basic_type != T_OBJECT) {
        // Simple test for basic type arrays
!       if (UseCompressedClassPointers) {
!         __ ldrw(tmp, src_klass_addr);
!         __ ldrw(rscratch1, dst_klass_addr);
!         __ cmpw(tmp, rscratch1);
-       } else {
-         __ ldr(tmp, src_klass_addr);
-         __ ldr(rscratch1, dst_klass_addr);
-         __ cmp(tmp, rscratch1);
-       }
        __ br(Assembler::NE, *stub->entry());
      } else {
        // For object arrays, if src is a sub class of dst then we can
        // safely do the copy.
        Label cont, slow;
--- 2342,14 ---
  
    if (flags & LIR_OpArrayCopy::type_check) {
      // We don't know the array types are compatible
      if (basic_type != T_OBJECT) {
        // Simple test for basic type arrays
!       assert(UseCompressedClassPointers, "Lilliput");
!       __ load_nklass(tmp, src);
!       __ load_nklass(rscratch1, dst);
!       __ cmpw(tmp, rscratch1);
        __ br(Assembler::NE, *stub->entry());
      } else {
        // For object arrays, if src is a sub class of dst then we can
        // safely do the copy.
        Label cont, slow;

*** 2370,12 ***
  #define POP(r1, r2)                                     \
        ldp(r1, r2, __ post(sp, 2 * wordSize));
  
        __ PUSH(src, dst);
  
!       __ load_klass(src, src);
!       __ load_klass(dst, dst);
  
        __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL);
  
        __ PUSH(src, dst);
        __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
--- 2360,14 ---
  #define POP(r1, r2)                                     \
        ldp(r1, r2, __ post(sp, 2 * wordSize));
  
        __ PUSH(src, dst);
  
!       __ load_klass(tmp, src);
!       __ mov(src, tmp);
+       __ load_klass(tmp, dst);
+       __ mov(dst, tmp);
  
        __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL);
  
        __ PUSH(src, dst);
        __ far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));

*** 2481,36 ***
      __ mov_metadata(tmp, default_type->constant_encoding());
      if (UseCompressedClassPointers) {
        __ encode_klass_not_null(tmp);
      }
  
      if (basic_type != T_OBJECT) {
! 
!       if (UseCompressedClassPointers) {
-         __ ldrw(rscratch1, dst_klass_addr);
-         __ cmpw(tmp, rscratch1);
-       } else {
-         __ ldr(rscratch1, dst_klass_addr);
-         __ cmp(tmp, rscratch1);
-       }
        __ br(Assembler::NE, halt);
!       if (UseCompressedClassPointers) {
!         __ ldrw(rscratch1, src_klass_addr);
-         __ cmpw(tmp, rscratch1);
-       } else {
-         __ ldr(rscratch1, src_klass_addr);
-         __ cmp(tmp, rscratch1);
-       }
        __ br(Assembler::EQ, known_ok);
      } else {
!       if (UseCompressedClassPointers) {
!         __ ldrw(rscratch1, dst_klass_addr);
-         __ cmpw(tmp, rscratch1);
-       } else {
-         __ ldr(rscratch1, dst_klass_addr);
-         __ cmp(tmp, rscratch1);
-       }
        __ br(Assembler::EQ, known_ok);
        __ cmp(src, dst);
        __ br(Assembler::EQ, known_ok);
      }
      __ bind(halt);
--- 2473,21 ---
      __ mov_metadata(tmp, default_type->constant_encoding());
      if (UseCompressedClassPointers) {
        __ encode_klass_not_null(tmp);
      }
  
+     assert(UseCompressedClassPointers, "Lilliput");
      if (basic_type != T_OBJECT) {
!       __ load_nklass(rscratch1, dst);
!       __ cmpw(tmp, rscratch1);
        __ br(Assembler::NE, halt);
!       __ load_nklass(rscratch1, src);
!       __ cmpw(tmp, rscratch1);
        __ br(Assembler::EQ, known_ok);
      } else {
!       __ load_nklass(rscratch1, dst);
!       __ cmpw(tmp, rscratch1);
        __ br(Assembler::EQ, known_ok);
        __ cmp(src, dst);
        __ br(Assembler::EQ, known_ok);
      }
      __ bind(halt);

*** 2561,41 ***
        add_debug_info_for_null_check_here(op->info());
        __ null_check(obj, -1);
      }
      __ b(*op->stub()->entry());
    } else if (op->code() == lir_lock) {
-     assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
      // add debug info for NullPointerException only if one is possible
      int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry());
      if (op->info() != NULL) {
        add_debug_info_for_null_check(null_check_offset, op->info());
      }
      // done
    } else if (op->code() == lir_unlock) {
-     assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
      __ unlock_object(hdr, obj, lock, *op->stub()->entry());
    } else {
      Unimplemented();
    }
    __ bind(*op->stub()->continuation());
  }
  
  void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
    Register obj = op->obj()->as_pointer_register();
    Register result = op->result_opr()->as_pointer_register();
  
    CodeEmitInfo* info = op->info();
    if (info != NULL) {
      add_debug_info_for_null_check_here(info);
    }
  
!   if (UseCompressedClassPointers) {
!     __ ldrw(result, Address (obj, oopDesc::klass_offset_in_bytes()));
!     __ decode_klass_not_null(result);
!   } else {
!     __ ldr(result, Address (obj, oopDesc::klass_offset_in_bytes()));
!   }
  }
  
  void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
    ciMethod* method = op->profiled_method();
    int bci          = op->profiled_bci();
--- 2538,48 ---
        add_debug_info_for_null_check_here(op->info());
        __ null_check(obj, -1);
      }
      __ b(*op->stub()->entry());
    } else if (op->code() == lir_lock) {
      // add debug info for NullPointerException only if one is possible
      int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry());
      if (op->info() != NULL) {
        add_debug_info_for_null_check(null_check_offset, op->info());
      }
      // done
    } else if (op->code() == lir_unlock) {
      __ unlock_object(hdr, obj, lock, *op->stub()->entry());
    } else {
      Unimplemented();
    }
    __ bind(*op->stub()->continuation());
  }
  
  void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
    Register obj = op->obj()->as_pointer_register();
    Register result = op->result_opr()->as_pointer_register();
+   Register tmp = rscratch1;
  
    CodeEmitInfo* info = op->info();
    if (info != NULL) {
      add_debug_info_for_null_check_here(info);
    }
  
!   assert(UseCompressedClassPointers, "expects UseCompressedClassPointers");
! 
!   // Check if we can take the (common) fast path, if obj is unlocked.
!   __ ldr(tmp, Address(obj, oopDesc::mark_offset_in_bytes()));
!   __ eor(tmp, tmp, markWord::unlocked_value);
!   __ tst(tmp, markWord::lock_mask_in_place);
+   __ br(Assembler::NE, *op->stub()->entry());
+ 
+   // Fast-path: shift and decode Klass*.
+   __ mov(result, tmp);
+   __ lsr(result, result, markWord::klass_shift);
+ 
+   __ bind(*op->stub()->continuation());
+   __ decode_klass_not_null(result);
  }
  
  void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
    ciMethod* method = op->profiled_method();
    int bci          = op->profiled_bci();

*** 2652,11 ***
            __ addptr(data_addr, DataLayout::counter_increment);
            return;
          }
        }
      } else {
!       __ load_klass(recv, recv);
        Label update_done;
        type_profile_helper(mdo, md, data, recv, &update_done);
        // Receiver did not match any saved receiver and there is no empty row for it.
        // Increment total counter to indicate polymorphic case.
        __ addptr(counter_addr, DataLayout::counter_increment);
--- 2636,12 ---
            __ addptr(data_addr, DataLayout::counter_increment);
            return;
          }
        }
      } else {
!       __ load_klass(rscratch1, recv);
+       __ mov(recv, rscratch1);
        Label update_done;
        type_profile_helper(mdo, md, data, recv, &update_done);
        // Receiver did not match any saved receiver and there is no empty row for it.
        // Increment total counter to indicate polymorphic case.
        __ addptr(counter_addr, DataLayout::counter_increment);

*** 2674,11 ***
    Unimplemented();
  }
  
  
  void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) {
!   __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no));
  }
  
  void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {
    assert(op->crc()->is_single_cpu(),  "crc must be register");
    assert(op->val()->is_single_cpu(),  "byte value must be register");
--- 2659,11 ---
    Unimplemented();
  }
  
  
  void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) {
!   __ lea(dst->as_register(), frame_map()->address_for_monitor_object(monitor_no));
  }
  
  void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {
    assert(op->crc()->is_single_cpu(),  "crc must be register");
    assert(op->val()->is_single_cpu(),  "byte value must be register");

*** 2746,11 ***
  
    if (do_update) {
  #ifdef ASSERT
      if (exact_klass != NULL) {
        Label ok;
!       __ load_klass(tmp, tmp);
        __ mov_metadata(rscratch1, exact_klass->constant_encoding());
        __ eor(rscratch1, tmp, rscratch1);
        __ cbz(rscratch1, ok);
        __ stop("exact klass and actual klass differ");
        __ bind(ok);
--- 2731,12 ---
  
    if (do_update) {
  #ifdef ASSERT
      if (exact_klass != NULL) {
        Label ok;
!       __ load_klass(rscratch1, tmp);
+       __ mov(tmp, rscratch1);
        __ mov_metadata(rscratch1, exact_klass->constant_encoding());
        __ eor(rscratch1, tmp, rscratch1);
        __ cbz(rscratch1, ok);
        __ stop("exact klass and actual klass differ");
        __ bind(ok);

*** 2759,11 ***
      if (!no_conflict) {
        if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
          if (exact_klass != NULL) {
            __ mov_metadata(tmp, exact_klass->constant_encoding());
          } else {
!           __ load_klass(tmp, tmp);
          }
  
          __ ldr(rscratch2, mdo_addr);
          __ eor(tmp, tmp, rscratch2);
          __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
--- 2745,12 ---
      if (!no_conflict) {
        if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
          if (exact_klass != NULL) {
            __ mov_metadata(tmp, exact_klass->constant_encoding());
          } else {
!           __ load_klass(rscratch1, tmp);
+           __ mov(tmp, rscratch1);
          }
  
          __ ldr(rscratch2, mdo_addr);
          __ eor(tmp, tmp, rscratch2);
          __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
< prev index next >