< prev index next >

src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp

Print this page
*** 29,10 ***
--- 29,11 ---
  #include "c1/c1_LIRAssembler.hpp"
  #include "c1/c1_LIRGenerator.hpp"
  #include "c1/c1_Runtime1.hpp"
  #include "c1/c1_ValueStack.hpp"
  #include "ci/ciArray.hpp"
+ #include "ci/ciInlineKlass.hpp"
  #include "ci/ciObjArrayKlass.hpp"
  #include "ci/ciTypeArrayKlass.hpp"
  #include "gc/shared/c1/barrierSetC1.hpp"
  #include "runtime/sharedRuntime.hpp"
  #include "runtime/stubRoutines.hpp"

*** 114,10 ***
--- 115,23 ---
    set_vreg_flag(reg, LIRGenerator::byte_reg);
    return reg;
  }
  
  
+ void LIRGenerator::init_temps_for_substitutability_check(LIR_Opr& tmp1, LIR_Opr& tmp2) {
+   // We just need one 32-bit temp register for x86/x64, to check whether both
+   // oops have markWord::always_locked_pattern. See LIR_Assembler::emit_opSubstitutabilityCheck().
+   // @temp = %r10d
+   // mov $0x405, %r10d
+   // and (%left), %r10d   /* if need to check left */
+   // and (%right), %r10d  /* if need to check right */
+   // cmp $0x405, $r10d
+   // jne L_oops_not_equal
+   tmp1 = new_register(T_INT);
+   tmp2 = LIR_OprFact::illegalOpr;
+ }
+ 
  //--------- loading items into registers --------------------------------
  
  
  // i486 instructions can inline constants
  bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {

*** 309,21 ***
  
    set_no_result(x);
  
    // "lock" stores the address of the monitor stack slot, so this is not an oop
    LIR_Opr lock = new_register(T_INT);
  
    CodeEmitInfo* info_for_exception = nullptr;
    if (x->needs_null_check()) {
      info_for_exception = state_for(x);
    }
    // this CodeEmitInfo must not have the xhandlers because here the
    // object is already locked (xhandlers expect object to be unlocked)
    CodeEmitInfo* info = state_for(x, x->state(), true);
!   LIR_Opr tmp = LockingMode == LM_LIGHTWEIGHT ? new_register(T_ADDRESS) : LIR_OprFact::illegalOpr;
!   monitor_enter(obj.result(), lock, syncTempOpr(), tmp,
-                         x->monitor_no(), info_for_exception, info);
  }
  
  
  void LIRGenerator::do_MonitorExit(MonitorExit* x) {
    assert(x->is_pinned(),"");
--- 323,32 ---
  
    set_no_result(x);
  
    // "lock" stores the address of the monitor stack slot, so this is not an oop
    LIR_Opr lock = new_register(T_INT);
+   // Need a scratch register for inline types on x86
+   LIR_Opr scratch = LIR_OprFact::illegalOpr;
+   if ((LockingMode == LM_LIGHTWEIGHT) ||
+       (EnableValhalla && x->maybe_inlinetype())) {
+     scratch = new_register(T_ADDRESS);
+   }
  
    CodeEmitInfo* info_for_exception = nullptr;
    if (x->needs_null_check()) {
      info_for_exception = state_for(x);
    }
+ 
+   CodeStub* throw_imse_stub = x->maybe_inlinetype() ?
+       new SimpleExceptionStub(Runtime1::throw_illegal_monitor_state_exception_id,
+                               LIR_OprFact::illegalOpr, state_for(x))
+     : nullptr;
+ 
    // this CodeEmitInfo must not have the xhandlers because here the
    // object is already locked (xhandlers expect object to be unlocked)
    CodeEmitInfo* info = state_for(x, x->state(), true);
!   monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
!                 x->monitor_no(), info_for_exception, info, throw_imse_stub);
  }
  
  
  void LIRGenerator::do_MonitorExit(MonitorExit* x) {
    assert(x->is_pinned(),"");

*** 1292,23 ***
  
  
  void LIRGenerator::do_NewInstance(NewInstance* x) {
    print_if_not_loaded(x);
  
!   CodeEmitInfo* info = state_for(x, x->state());
    LIR_Opr reg = result_register_for(x->type());
    new_instance(reg, x->klass(), x->is_unresolved(),
!                        FrameMap::rcx_oop_opr,
!                        FrameMap::rdi_oop_opr,
!                        FrameMap::rsi_oop_opr,
!                        LIR_OprFact::illegalOpr,
!                        FrameMap::rdx_metadata_opr, info);
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  }
  
- 
  void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
    CodeEmitInfo* info = state_for(x, x->state());
  
    LIRItem length(x->length(), this);
    length.load_item_force(FrameMap::rbx_opr);
--- 1317,23 ---
  
  
  void LIRGenerator::do_NewInstance(NewInstance* x) {
    print_if_not_loaded(x);
  
!   CodeEmitInfo* info = state_for(x, x->needs_state_before() ? x->state_before() : x->state());
    LIR_Opr reg = result_register_for(x->type());
    new_instance(reg, x->klass(), x->is_unresolved(),
!                !x->is_unresolved() && x->klass()->is_inlinetype(),
!                FrameMap::rcx_oop_opr,
!                FrameMap::rdi_oop_opr,
!                FrameMap::rsi_oop_opr,
!                LIR_OprFact::illegalOpr,
+                FrameMap::rdx_metadata_opr, info);
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  }
  
  void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
    CodeEmitInfo* info = state_for(x, x->state());
  
    LIRItem length(x->length(), this);
    length.load_item_force(FrameMap::rbx_opr);

*** 1323,11 ***
    BasicType elem_type = x->elt_type();
  
    __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
  
    CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
!   __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
  
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  }
  
--- 1348,11 ---
    BasicType elem_type = x->elt_type();
  
    __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
  
    CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
!   __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path, false);
  
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  }
  

*** 1351,17 ***
    LIR_Opr klass_reg = FrameMap::rdx_metadata_opr;
  
    length.load_item_force(FrameMap::rbx_opr);
    LIR_Opr len = length.result();
  
!   CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
!   ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass());
    if (obj == ciEnv::unloaded_ciobjarrayklass()) {
      BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
    }
    klass2reg_with_patching(klass_reg, obj, patching_info);
!   __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);
  
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  }
  
--- 1376,17 ---
    LIR_Opr klass_reg = FrameMap::rdx_metadata_opr;
  
    length.load_item_force(FrameMap::rbx_opr);
    LIR_Opr len = length.result();
  
!   ciKlass* obj = (ciKlass*) x->exact_type();
!   CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info, x->is_null_free());
    if (obj == ciEnv::unloaded_ciobjarrayklass()) {
      BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
    }
    klass2reg_with_patching(klass_reg, obj, patching_info);
!   __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path, x->is_null_free());
  
    LIR_Opr result = rlock_result(x);
    __ move(reg, result);
  }
  

*** 1436,10 ***
--- 1461,14 ---
    // info for exceptions
    CodeEmitInfo* info_for_exception =
        (x->needs_exception_state() ? state_for(x) :
                                      state_for(x, x->state_before(), true /*ignore_xhandler*/));
  
+   if (x->is_null_free()) {
+     __ null_check(obj.result(), new CodeEmitInfo(info_for_exception));
+   }
+ 
    CodeStub* stub;
    if (x->is_incompatible_class_change_check()) {
      assert(patching_info == nullptr, "can't patch this");
      stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception);
    } else if (x->is_invokespecial_receiver_check()) {

*** 1454,11 ***
      tmp3 = new_register(objectType);
    }
    __ checkcast(reg, obj.result(), x->klass(),
                 new_register(objectType), new_register(objectType), tmp3,
                 x->direct_compare(), info_for_exception, patching_info, stub,
!                x->profiled_method(), x->profiled_bci());
  }
  
  
  void LIRGenerator::do_InstanceOf(InstanceOf* x) {
    LIRItem obj(x->obj(), this);
--- 1483,11 ---
      tmp3 = new_register(objectType);
    }
    __ checkcast(reg, obj.result(), x->klass(),
                 new_register(objectType), new_register(objectType), tmp3,
                 x->direct_compare(), info_for_exception, patching_info, stub,
!                x->profiled_method(), x->profiled_bci(), x->is_null_free());
  }
  
  
  void LIRGenerator::do_InstanceOf(InstanceOf* x) {
    LIRItem obj(x->obj(), this);

*** 1505,11 ***
    }
    xin->load_item();
    if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) {
      // inline long zero
      yin->dont_load_item();
!   } else if (tag == longTag || tag == floatTag || tag == doubleTag) {
      // longs cannot handle constants at right side
      yin->load_item();
    } else {
      yin->dont_load_item();
    }
--- 1534,11 ---
    }
    xin->load_item();
    if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) {
      // inline long zero
      yin->dont_load_item();
!   } else if (tag == longTag || tag == floatTag || tag == doubleTag || x->substitutability_check()) {
      // longs cannot handle constants at right side
      yin->load_item();
    } else {
      yin->dont_load_item();
    }

*** 1525,11 ***
      increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()),
          x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci());
      __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
    }
  
!   __ cmp(lir_cond(cond), left, right);
    // Generate branch profiling. Profiling code doesn't kill flags.
    profile_branch(x, cond);
    move_to_phi(x->state());
    if (x->x()->type()->is_float_kind()) {
      __ branch(lir_cond(cond), x->tsux(), x->usux());
--- 1554,15 ---
      increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()),
          x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci());
      __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
    }
  
!   if (x->substitutability_check()) {
+     substitutability_check(x, *xin, *yin);
+   } else {
+     __ cmp(lir_cond(cond), left, right);
+   }
    // Generate branch profiling. Profiling code doesn't kill flags.
    profile_branch(x, cond);
    move_to_phi(x->state());
    if (x->x()->type()->is_float_kind()) {
      __ branch(lir_cond(cond), x->tsux(), x->usux());
< prev index next >