< prev index next >

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

Print this page
@@ -264,29 +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() +
-       (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.
+       BytesPerWord * (number_of_locks - 1);
      for (int i = 0; i < number_of_locks; i++) {
-       int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
+       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 + 1*BytesPerWord));
+         __ ldr(rscratch1, Address(OSR_buf, slot_offset));
          __ 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));
+       __ ldr(r19, Address(OSR_buf, slot_offset));
+       __ str(r19, frame_map()->address_for_monitor_object(i));
      }
    }
  }
  
  

@@ -428,11 +424,12 @@
  
    // Perform needed unlocking
    MonitorExitStub* stub = NULL;
    if (method()->is_synchronized()) {
      monitor_address(0, FrameMap::r0_opr);
-     stub = new MonitorExitStub(FrameMap::r0_opr, true, 0);
+     __ 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 +1224,11 @@
      }
      __ allocate_array(op->obj()->as_register(),
                        len,
                        tmp1,
                        tmp2,
-                       arrayOopDesc::header_size(op->type()),
+                       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 +2282,10 @@
    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());
    }

@@ -2347,19 +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
-       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);
-       }
+       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 +2360,14 @@
  #define POP(r1, r2)                                     \
        ldp(r1, r2, __ post(sp, 2 * wordSize));
  
        __ PUSH(src, dst);
  
-       __ load_klass(src, src);
-       __ load_klass(dst, 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 +2473,21 @@
      __ mov_metadata(tmp, default_type->constant_encoding());
      if (UseCompressedClassPointers) {
        __ encode_klass_not_null(tmp);
      }
  
+     assert(UseCompressedClassPointers, "Lilliput");
      if (basic_type != T_OBJECT) {
- 
-       if (UseCompressedClassPointers) {
-         __ ldrw(rscratch1, dst_klass_addr);
-         __ cmpw(tmp, rscratch1);
-       } else {
-         __ ldr(rscratch1, dst_klass_addr);
-         __ cmp(tmp, rscratch1);
-       }
+       __ load_nklass(rscratch1, dst);
+       __ cmpw(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);
-       }
+       __ load_nklass(rscratch1, src);
+       __ cmpw(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);
-       }
+       __ load_nklass(rscratch1, dst);
+       __ cmpw(tmp, rscratch1);
        __ br(Assembler::EQ, known_ok);
        __ cmp(src, dst);
        __ br(Assembler::EQ, known_ok);
      }
      __ bind(halt);

@@ -2561,41 +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) {
-     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();
+   Register tmp = rscratch1;
  
    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()));
-   }
+   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 +2636,12 @@
            __ addptr(data_addr, DataLayout::counter_increment);
            return;
          }
        }
      } else {
-       __ load_klass(recv, recv);
+       __ 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 +2659,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));
+   __ 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 +2731,12 @@
  
    if (do_update) {
  #ifdef ASSERT
      if (exact_klass != NULL) {
        Label ok;
-       __ load_klass(tmp, tmp);
+       __ 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 +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(tmp, tmp);
+           __ 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 >