Example #1
0
void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
  assert(x->number_of_arguments() == 3, "wrong type");
  LIRItem obj       (x->argument_at(0), this);  // AtomicLong object
  LIRItem cmp_value (x->argument_at(1), this);  // value to compare with field
  LIRItem new_value (x->argument_at(2), this);  // replace field with new_value if it matches cmp_value

  // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction
  cmp_value.load_item_force(FrameMap::long0_opr);

  // new value must be in rcx,ebx (hi,lo)
  new_value.load_item_force(FrameMap::long1_opr);

  // object pointer register is overwritten with field address
  obj.load_item();

  // generate compare-and-swap; produces zero condition if swap occurs
  int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
  LIR_Opr addr = new_pointer_register();
  __ leal(LIR_OprFact::address(new LIR_Address(obj.result(), value_offset, T_LONG)), addr);
  LIR_Opr t1 = LIR_OprFact::illegalOpr;  // no temp needed
  LIR_Opr t2 = LIR_OprFact::illegalOpr;  // no temp needed
  __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);

  // generate conditional move of boolean result
  LIR_Opr result = rlock_result(x);
  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
}
void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
  assert(x->number_of_arguments() == 4, "wrong type");
  LIRItem obj   (x->argument_at(0), this);  // object
  LIRItem offset(x->argument_at(1), this);  // offset of field
  LIRItem cmp   (x->argument_at(2), this);  // value to compare with field
  LIRItem val   (x->argument_at(3), this);  // replace field with val if matches cmp

  // Use temps to avoid kills
  LIR_Opr t1 = FrameMap::G1_opr;
  LIR_Opr t2 = FrameMap::G3_opr;
  LIR_Opr addr = new_pointer_register();

  // get address of field
  obj.load_item();
  offset.load_item();
  cmp.load_item();
  val.load_item();

  __ add(obj.result(), offset.result(), addr);

  if (type == objectType) {  // Write-barrier needed for Object fields.
    pre_barrier(obj.result(), false, NULL);
  }

  if (type == objectType)
    __ cas_obj(addr, cmp.result(), val.result(), t1, t2);
  else if (type == intType)
    __ cas_int(addr, cmp.result(), val.result(), t1, t2);
  else if (type == longType)
    __ cas_long(addr, cmp.result(), val.result(), t1, t2);
  else {
    ShouldNotReachHere();
  }

  // generate conditional move of boolean result
  LIR_Opr result = rlock_result(x);
  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
  if (type == objectType) {  // Write-barrier needed for Object fields.
#ifdef PRECISE_CARDMARK
    post_barrier(addr, val.result());
#else
    post_barrier(obj.result(), val.result());
#endif // PRECISE_CARDMARK
  }
}
void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
  assert(x->number_of_arguments() == 3, "wrong type");
  LIRItem obj       (x->argument_at(0), this);  // AtomicLong object
  LIRItem cmp_value (x->argument_at(1), this);  // value to compare with field
  LIRItem new_value (x->argument_at(2), this);  // replace field with new_value if it matches cmp_value

  obj.load_item();
  cmp_value.load_item();
  new_value.load_item();

  // generate compare-and-swap and produce zero condition if swap occurs
  int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
  LIR_Opr addr = FrameMap::O7_opr;
  __ add(obj.result(), LIR_OprFact::intConst(value_offset), addr);
  LIR_Opr t1 = FrameMap::G1_opr;  // temp for 64-bit value
  LIR_Opr t2 = FrameMap::G3_opr;  // temp for 64-bit value
  __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);

  // generate conditional move of boolean result
  LIR_Opr result = rlock_result(x);
  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
}
Example #4
0
void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
  assert(x->number_of_arguments() == 4, "wrong type");
  LIRItem obj   (x->argument_at(0), this);  // object
  LIRItem offset(x->argument_at(1), this);  // offset of field
  LIRItem cmp   (x->argument_at(2), this);  // value to compare with field
  LIRItem val   (x->argument_at(3), this);  // replace field with val if matches cmp

  assert(obj.type()->tag() == objectTag, "invalid type");

  // In 64bit the type can be long, sparc doesn't have this assert
  // assert(offset.type()->tag() == intTag, "invalid type");

  assert(cmp.type()->tag() == type->tag(), "invalid type");
  assert(val.type()->tag() == type->tag(), "invalid type");

  // get address of field
  obj.load_item();
  offset.load_nonconstant();

  if (type == objectType) {
    cmp.load_item_force(FrameMap::rax_oop_opr);
    val.load_item();
  } else if (type == intType) {
    cmp.load_item_force(FrameMap::rax_opr);
    val.load_item();
  } else if (type == longType) {
    cmp.load_item_force(FrameMap::long0_opr);
    val.load_item_force(FrameMap::long1_opr);
  } else {
    ShouldNotReachHere();
  }

  LIR_Opr addr = new_pointer_register();
  LIR_Address* a;
  if(offset.result()->is_constant()) {
    a = new LIR_Address(obj.result(),
                        NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()),
                        as_BasicType(type));
  } else {
    a = new LIR_Address(obj.result(),
                        offset.result(),
                        LIR_Address::times_1,
                        0,
                        as_BasicType(type));
  }
  __ leal(LIR_OprFact::address(a), addr);

  if (type == objectType) {  // Write-barrier needed for Object fields.
    // Do the pre-write barrier, if any.
    pre_barrier(addr, false, NULL);
  }

  LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
  if (type == objectType)
    __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
  else if (type == intType)
    __ cas_int(addr, cmp.result(), val.result(), ill, ill);
  else if (type == longType)
    __ cas_long(addr, cmp.result(), val.result(), ill, ill);
  else {
    ShouldNotReachHere();
  }

  // generate conditional move of boolean result
  LIR_Opr result = rlock_result(x);
  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
           result, as_BasicType(type));
  if (type == objectType) {   // Write-barrier needed for Object fields.
    // Seems to be precise
    post_barrier(addr, val.result());
  }
}