< prev index next >

src/hotspot/cpu/aarch64/aarch64.ad

Print this page
*** 1765,10 ***
--- 1765,13 ---
    //   stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)))
    //   blr(rscratch1)
    CodeBlob *cb = CodeCache::find_blob(_entry_point);
    if (cb) {
      return 1 * NativeInstruction::instruction_size;
+   } else if (_entry_point == NULL) {
+     // See CallLeafNoFPIndirect
+     return 1 * NativeInstruction::instruction_size;
    } else {
      return 6 * NativeInstruction::instruction_size;
    }
  }
  

*** 1882,13 ***
  
  void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
    Compile* C = ra_->C;
    C2_MacroAssembler _masm(&cbuf);
  
-   // n.b. frame size includes space for return pc and rfp
-   const int framesize = C->output()->frame_size_in_bytes();
- 
    // insert a nop at the start of the prolog so we can patch in a
    // branch if we need to invalidate the method later
    __ nop();
  
    if (C->clinit_barrier_on_entry()) {
--- 1885,10 ---

*** 1904,15 ***
  
    if (C->max_vector_size() > 0) {
      __ reinitialize_ptrue();
    }
  
!   int bangsize = C->output()->bang_size_in_bytes();
!   if (C->output()->need_stack_bang(bangsize))
-     __ generate_stack_overflow_check(bangsize);
- 
-   __ build_frame(framesize);
  
    if (C->stub_function() == NULL) {
      BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
      bs->nmethod_entry_barrier(&_masm);
    }
--- 1904,12 ---
  
    if (C->max_vector_size() > 0) {
      __ reinitialize_ptrue();
    }
  
!   __ verified_entry(C, 0);
!   __ bind(*_verified_entry);
  
    if (C->stub_function() == NULL) {
      BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
      bs->nmethod_entry_barrier(&_masm);
    }

*** 1929,16 ***
      ConstantTable& constant_table = C->output()->constant_table();
      constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
    }
  }
  
- uint MachPrologNode::size(PhaseRegAlloc* ra_) const
- {
-   return MachNode::size(ra_); // too many variables; just compute it
-                               // the hard way
- }
- 
  int MachPrologNode::reloc() const
  {
    return 0;
  }
  
--- 1926,10 ---

*** 1974,11 ***
  void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
    Compile* C = ra_->C;
    C2_MacroAssembler _masm(&cbuf);
    int framesize = C->output()->frame_slots() << LogBytesPerInt;
  
!   __ remove_frame(framesize);
  
    if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
      __ reserved_stack_check();
    }
  
--- 1965,11 ---
  void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
    Compile* C = ra_->C;
    C2_MacroAssembler _masm(&cbuf);
    int framesize = C->output()->frame_slots() << LogBytesPerInt;
  
!   __ remove_frame(framesize, C->needs_stack_repair());
  
    if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
      __ reserved_stack_check();
    }
  

*** 1991,15 ***
      __ relocate(relocInfo::poll_return_type);
      __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */);
    }
  }
  
- uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
-   // Variable size. Determine dynamically.
-   return MachNode::size(ra_);
- }
- 
  int MachEpilogNode::reloc() const {
    // Return number of relocatable values contained in this instruction.
    return 1; // 1 for polling page.
  }
  
--- 1982,10 ---

*** 2278,12 ***
    } else {
      return 2 * NativeInstruction::instruction_size;
    }
  }
  
! //=============================================================================
  
  #ifndef PRODUCT
  void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
  {
    st->print_cr("# MachUEPNode");
    if (UseCompressedClassPointers) {
--- 2264,45 ---
    } else {
      return 2 * NativeInstruction::instruction_size;
    }
  }
  
! ///=============================================================================
+ #ifndef PRODUCT
+ void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
+ {
+   st->print_cr("# MachVEPNode");
+   if (!_verified) {
+     st->print_cr("\t load_class");
+   } else {
+     st->print_cr("\t unpack_inline_arg");
+   }
+ }
+ #endif
+ 
+ void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
+ {
+   MacroAssembler _masm(&cbuf);
+ 
+   if (!_verified) {
+     Label skip;
+     __ cmp_klass(j_rarg0, rscratch2, rscratch1);
+     __ br(Assembler::EQ, skip);
+       __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
+     __ bind(skip);
  
+   } else {
+     // Unpack inline type args passed as oop and then jump to
+     // the verified entry point (skipping the unverified entry).
+     int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only);
+     // Emit code for verified entry and save increment for stack repair on return
+     __ verified_entry(ra_->C, sp_inc);
+     __ b(*_verified_entry);
+   }
+ }
+ 
+ //=============================================================================
  #ifndef PRODUCT
  void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
  {
    st->print_cr("# MachUEPNode");
    if (UseCompressedClassPointers) {

*** 2301,25 ***
  
  void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
  {
    // This is the unverified entry point.
    C2_MacroAssembler _masm(&cbuf);
  
    __ cmp_klass(j_rarg0, rscratch2, rscratch1);
!   Label skip;
    // TODO
    // can we avoid this skip and still use a reloc?
    __ br(Assembler::EQ, skip);
    __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
    __ bind(skip);
  }
  
- uint MachUEPNode::size(PhaseRegAlloc* ra_) const
- {
-   return MachNode::size(ra_);
- }
- 
  // REQUIRED EMIT CODE
  
  //=============================================================================
  
  // Emit exception handler code.
--- 2320,22 ---
  
  void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
  {
    // This is the unverified entry point.
    C2_MacroAssembler _masm(&cbuf);
+   Label skip;
  
+   // UseCompressedClassPointers logic are inside cmp_klass
    __ cmp_klass(j_rarg0, rscratch2, rscratch1);
! 
    // TODO
    // can we avoid this skip and still use a reloc?
    __ br(Assembler::EQ, skip);
    __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
    __ bind(skip);
  }
  
  // REQUIRED EMIT CODE
  
  //=============================================================================
  
  // Emit exception handler code.

*** 3740,10 ***
--- 3756,21 ---
      C2_MacroAssembler _masm(&cbuf);
      if (VerifyStackAtCalls) {
        // Check that stack depth is unchanged: find majik cookie on stack
        __ call_Unimplemented();
      }
+     if (tf()->returns_inline_type_as_fields() && !_method->is_method_handle_intrinsic()) {
+       // An inline type is returned as fields in multiple registers.
+       // R0 either contains an oop if the inline type is buffered or a pointer
+       // to the corresponding InlineKlass with the lowest bit set to 1. Zero r0
+       // if the lowest bit is set to allow C2 to use the oop after null checking.
+       // r0 &= (r0 & 1) - 1
+       C2_MacroAssembler _masm(&cbuf);
+       __ andr(rscratch1, r0, 0x1);
+       __ sub(rscratch1, rscratch1, 0x1);
+       __ andr(r0, r0, rscratch1);
+     }
    %}
  
    enc_class aarch64_enc_java_to_runtime(method meth) %{
      C2_MacroAssembler _masm(&cbuf);
  

*** 3831,10 ***
--- 3858,15 ---
      __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
  
      // Set tmp to be (markWord of object | UNLOCK_VALUE).
      __ orr(tmp, disp_hdr, markWord::unlocked_value);
  
+     if (EnableValhalla) {
+       // Mask inline_type bit such that we go to the slow path if object is an inline type
+       __ andr(tmp, tmp, ~((int) markWord::inline_type_bit_in_place));
+     }
+ 
      // Initialize the box. (Must happen before we update the object mark!)
      __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
  
      // Compare object markWord with an unlocked value (tmp) and if
      // equal exchange the stack address of our box with object markWord.

*** 7503,11 ***
  %{
    match(Set dst con);
  
    ins_cost(INSN_COST * 4);
    format %{
!     "mov  $dst, $con\t# ptr\n\t"
    %}
  
    ins_encode(aarch64_enc_mov_p(dst, con));
  
    ins_pipe(ialu_imm);
--- 7535,11 ---
  %{
    match(Set dst con);
  
    ins_cost(INSN_COST * 4);
    format %{
!     "mov  $dst, $con\t# ptr"
    %}
  
    ins_encode(aarch64_enc_mov_p(dst, con));
  
    ins_pipe(ialu_imm);

*** 8635,10 ***
--- 8667,25 ---
    %}
  
    ins_pipe(ialu_reg);
  %}
  
+ instruct castN2X(iRegLNoSp dst, iRegN src) %{
+   match(Set dst (CastP2X src));
+ 
+   ins_cost(INSN_COST);
+   format %{ "mov $dst, $src\t# ptr -> long" %}
+ 
+   ins_encode %{
+     if ($dst$$reg != $src$$reg) {
+       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
+     }
+   %}
+ 
+   ins_pipe(ialu_reg);
+ %}
+ 
  instruct castP2X(iRegLNoSp dst, iRegP src) %{
    match(Set dst (CastP2X src));
  
    ins_cost(INSN_COST);
    format %{ "mov $dst, $src\t# ptr -> long" %}

*** 14978,13 ***
  %}
  
  // ============================================================================
  // clearing of an array
  
! instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
  %{
!   match(Set dummy (ClearArray cnt base));
    effect(USE_KILL cnt, USE_KILL base, KILL cr);
  
    ins_cost(4 * INSN_COST);
    format %{ "ClearArray $cnt, $base" %}
  
--- 15025,13 ---
  %}
  
  // ============================================================================
  // clearing of an array
  
! instruct clearArray_reg_reg_immL0(iRegL_R11 cnt, iRegP_R10 base, immL0 zero, Universe dummy, rFlagsReg cr)
  %{
!   match(Set dummy (ClearArray (Binary cnt base) zero));
    effect(USE_KILL cnt, USE_KILL base, KILL cr);
  
    ins_cost(4 * INSN_COST);
    format %{ "ClearArray $cnt, $base" %}
  

*** 14997,14 ***
    %}
  
    ins_pipe(pipe_class_memory);
  %}
  
  instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr)
  %{
    predicate((uint64_t)n->in(2)->get_long()
!             < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
    match(Set dummy (ClearArray cnt base));
    effect(TEMP temp, USE_KILL base, KILL cr);
  
    ins_cost(4 * INSN_COST);
    format %{ "ClearArray $cnt, $base" %}
--- 15044,31 ---
    %}
  
    ins_pipe(pipe_class_memory);
  %}
  
+ instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, iRegL val, Universe dummy, rFlagsReg cr)
+ %{
+   predicate(((ClearArrayNode*)n)->word_copy_only());
+   match(Set dummy (ClearArray (Binary cnt base) val));
+   effect(USE_KILL cnt, USE_KILL base, KILL cr);
+ 
+   ins_cost(4 * INSN_COST);
+   format %{ "ClearArray $cnt, $base, $val" %}
+ 
+   ins_encode %{
+     __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
+   %}
+ 
+   ins_pipe(pipe_class_memory);
+ %}
+ 
  instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr)
  %{
    predicate((uint64_t)n->in(2)->get_long()
!             < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
+             && !((ClearArrayNode*)n)->word_copy_only());
    match(Set dummy (ClearArray cnt base));
    effect(TEMP temp, USE_KILL base, KILL cr);
  
    ins_cost(4 * INSN_COST);
    format %{ "ClearArray $cnt, $base" %}

*** 16330,12 ***
--- 16394,32 ---
    ins_pipe(pipe_class_call);
  %}
  
  // Call Runtime Instruction
  
+ // entry point is null, target holds the address to call
+ instruct CallLeafNoFPIndirect(iRegP target)
+ %{
+   predicate(n->as_Call()->entry_point() == NULL);
+ 
+   match(CallLeafNoFP target);
+ 
+   ins_cost(CALL_COST);
+ 
+   format %{ "CALL, runtime leaf nofp indirect $target" %}
+ 
+   ins_encode %{
+     __ blr($target$$Register);
+   %}
+ 
+   ins_pipe(pipe_class_call);
+ %}
+ 
  instruct CallLeafNoFPDirect(method meth)
  %{
+   predicate(n->as_Call()->entry_point() != NULL);
+ 
    match(CallLeafNoFP);
  
    effect(USE meth);
  
    ins_cost(CALL_COST);
< prev index next >