8058744: Crash in C1 OSRed method w/ Unsafe usage

Tue, 23 Sep 2014 15:09:07 -0700

author
iveresov
date
Tue, 23 Sep 2014 15:09:07 -0700
changeset 7205
a60a1309a03a
parent 7204
97ad90b2712c
child 7206
50d3433155d9

8058744: Crash in C1 OSRed method w/ Unsafe usage
Summary: Fix UnsafeRawOp optimizations
Reviewed-by: kvn, drchase, vlivanov

src/share/vm/c1/c1_Canonicalizer.cpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_LIRGenerator.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/c1/c1_Canonicalizer.cpp	Wed Sep 24 09:49:47 2014 +0200
     1.2 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp	Tue Sep 23 15:09:07 2014 -0700
     1.3 @@ -327,7 +327,7 @@
     1.4    if (t2->is_constant()) {
     1.5      switch (t2->tag()) {
     1.6        case intTag   : if (t2->as_IntConstant()->value() == 0)  set_canonical(x->x()); return;
     1.7 -      case longTag  : if (t2->as_IntConstant()->value() == 0)  set_canonical(x->x()); return;
     1.8 +      case longTag  : if (t2->as_LongConstant()->value() == (jlong)0)  set_canonical(x->x()); return;
     1.9        default       : ShouldNotReachHere();
    1.10      }
    1.11    }
    1.12 @@ -808,28 +808,41 @@
    1.13  
    1.14  static bool match_index_and_scale(Instruction*  instr,
    1.15                                    Instruction** index,
    1.16 -                                  int*          log2_scale,
    1.17 -                                  Instruction** instr_to_unpin) {
    1.18 -  *instr_to_unpin = NULL;
    1.19 -
    1.20 -  // Skip conversion ops
    1.21 +                                  int*          log2_scale) {
    1.22 +  // Skip conversion ops. This works only on 32bit because of the implicit l2i that the
    1.23 +  // unsafe performs.
    1.24 +#ifndef _LP64
    1.25    Convert* convert = instr->as_Convert();
    1.26 -  if (convert != NULL) {
    1.27 +  if (convert != NULL && convert->op() == Bytecodes::_i2l) {
    1.28 +    assert(convert->value()->type() == intType, "invalid input type");
    1.29      instr = convert->value();
    1.30    }
    1.31 +#endif
    1.32  
    1.33    ShiftOp* shift = instr->as_ShiftOp();
    1.34    if (shift != NULL) {
    1.35 -    if (shift->is_pinned()) {
    1.36 -      *instr_to_unpin = shift;
    1.37 +    if (shift->op() == Bytecodes::_lshl) {
    1.38 +      assert(shift->x()->type() == longType, "invalid input type");
    1.39 +    } else {
    1.40 +#ifndef _LP64
    1.41 +      if (shift->op() == Bytecodes::_ishl) {
    1.42 +        assert(shift->x()->type() == intType, "invalid input type");
    1.43 +      } else {
    1.44 +        return false;
    1.45 +      }
    1.46 +#else
    1.47 +      return false;
    1.48 +#endif
    1.49      }
    1.50 +
    1.51 +
    1.52      // Constant shift value?
    1.53      Constant* con = shift->y()->as_Constant();
    1.54      if (con == NULL) return false;
    1.55      // Well-known type and value?
    1.56      IntConstant* val = con->type()->as_IntConstant();
    1.57 -    if (val == NULL) return false;
    1.58 -    if (shift->x()->type() != intType) return false;
    1.59 +    assert(val != NULL, "Should be an int constant");
    1.60 +
    1.61      *index = shift->x();
    1.62      int tmp_scale = val->value();
    1.63      if (tmp_scale >= 0 && tmp_scale < 4) {
    1.64 @@ -842,31 +855,42 @@
    1.65  
    1.66    ArithmeticOp* arith = instr->as_ArithmeticOp();
    1.67    if (arith != NULL) {
    1.68 -    if (arith->is_pinned()) {
    1.69 -      *instr_to_unpin = arith;
    1.70 +    // See if either arg is a known constant
    1.71 +    Constant* con = arith->x()->as_Constant();
    1.72 +    if (con != NULL) {
    1.73 +      *index = arith->y();
    1.74 +    } else {
    1.75 +      con = arith->y()->as_Constant();
    1.76 +      if (con == NULL) return false;
    1.77 +      *index = arith->x();
    1.78      }
    1.79 +    long const_value;
    1.80      // Check for integer multiply
    1.81 -    if (arith->op() == Bytecodes::_imul) {
    1.82 -      // See if either arg is a known constant
    1.83 -      Constant* con = arith->x()->as_Constant();
    1.84 -      if (con != NULL) {
    1.85 -        *index = arith->y();
    1.86 +    if (arith->op() == Bytecodes::_lmul) {
    1.87 +      assert((*index)->type() == longType, "invalid input type");
    1.88 +      LongConstant* val = con->type()->as_LongConstant();
    1.89 +      assert(val != NULL, "expecting a long constant");
    1.90 +      const_value = val->value();
    1.91 +    } else {
    1.92 +#ifndef _LP64
    1.93 +      if (arith->op() == Bytecodes::_imul) {
    1.94 +        assert((*index)->type() == intType, "invalid input type");
    1.95 +        IntConstant* val = con->type()->as_IntConstant();
    1.96 +        assert(val != NULL, "expecting an int constant");
    1.97 +        const_value = val->value();
    1.98        } else {
    1.99 -        con = arith->y()->as_Constant();
   1.100 -        if (con == NULL) return false;
   1.101 -        *index = arith->x();
   1.102 +        return false;
   1.103        }
   1.104 -      if ((*index)->type() != intType) return false;
   1.105 -      // Well-known type and value?
   1.106 -      IntConstant* val = con->type()->as_IntConstant();
   1.107 -      if (val == NULL) return false;
   1.108 -      switch (val->value()) {
   1.109 -      case 1: *log2_scale = 0; return true;
   1.110 -      case 2: *log2_scale = 1; return true;
   1.111 -      case 4: *log2_scale = 2; return true;
   1.112 -      case 8: *log2_scale = 3; return true;
   1.113 -      default:            return false;
   1.114 -      }
   1.115 +#else
   1.116 +      return false;
   1.117 +#endif
   1.118 +    }
   1.119 +    switch (const_value) {
   1.120 +    case 1: *log2_scale = 0; return true;
   1.121 +    case 2: *log2_scale = 1; return true;
   1.122 +    case 4: *log2_scale = 2; return true;
   1.123 +    case 8: *log2_scale = 3; return true;
   1.124 +    default:            return false;
   1.125      }
   1.126    }
   1.127  
   1.128 @@ -879,29 +903,37 @@
   1.129                    Instruction** base,
   1.130                    Instruction** index,
   1.131                    int*          log2_scale) {
   1.132 -  Instruction* instr_to_unpin = NULL;
   1.133    ArithmeticOp* root = x->base()->as_ArithmeticOp();
   1.134    if (root == NULL) return false;
   1.135    // Limit ourselves to addition for now
   1.136    if (root->op() != Bytecodes::_ladd) return false;
   1.137 +
   1.138 +  bool match_found = false;
   1.139    // Try to find shift or scale op
   1.140 -  if (match_index_and_scale(root->y(), index, log2_scale, &instr_to_unpin)) {
   1.141 +  if (match_index_and_scale(root->y(), index, log2_scale)) {
   1.142      *base = root->x();
   1.143 -  } else if (match_index_and_scale(root->x(), index, log2_scale, &instr_to_unpin)) {
   1.144 +    match_found = true;
   1.145 +  } else if (match_index_and_scale(root->x(), index, log2_scale)) {
   1.146      *base = root->y();
   1.147 -  } else if (root->y()->as_Convert() != NULL) {
   1.148 +    match_found = true;
   1.149 +  } else if (NOT_LP64(root->y()->as_Convert() != NULL) LP64_ONLY(false)) {
   1.150 +    // Skipping i2l works only on 32bit because of the implicit l2i that the unsafe performs.
   1.151 +    // 64bit needs a real sign-extending conversion.
   1.152      Convert* convert = root->y()->as_Convert();
   1.153 -    if (convert->op() == Bytecodes::_i2l && convert->value()->type() == intType) {
   1.154 +    if (convert->op() == Bytecodes::_i2l) {
   1.155 +      assert(convert->value()->type() == intType, "should be an int");
   1.156        // pick base and index, setting scale at 1
   1.157        *base  = root->x();
   1.158        *index = convert->value();
   1.159        *log2_scale = 0;
   1.160 -    } else {
   1.161 -      return false;
   1.162 +      match_found = true;
   1.163      }
   1.164 -  } else {
   1.165 -    // doesn't match any expected sequences
   1.166 -    return false;
   1.167 +  }
   1.168 +  // The default solution
   1.169 +  if (!match_found) {
   1.170 +    *base = root->x();
   1.171 +    *index = root->y();
   1.172 +    *log2_scale = 0;
   1.173    }
   1.174  
   1.175    // If the value is pinned then it will be always be computed so
     2.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Sep 24 09:49:47 2014 +0200
     2.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Sep 23 15:09:07 2014 -0700
     2.3 @@ -2042,6 +2042,8 @@
     2.4    }
     2.5  }
     2.6  
     2.7 +// Here UnsafeGetRaw may have x->base() and x->index() be int or long
     2.8 +// on both 64 and 32 bits. Expecting x->base() to be always long on 64bit.
     2.9  void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
    2.10    LIRItem base(x->base(), this);
    2.11    LIRItem idx(this);
    2.12 @@ -2056,50 +2058,73 @@
    2.13  
    2.14    int   log2_scale = 0;
    2.15    if (x->has_index()) {
    2.16 -    assert(x->index()->type()->tag() == intTag, "should not find non-int index");
    2.17      log2_scale = x->log2_scale();
    2.18    }
    2.19  
    2.20    assert(!x->has_index() || idx.value() == x->index(), "should match");
    2.21  
    2.22    LIR_Opr base_op = base.result();
    2.23 +  LIR_Opr index_op = idx.result();
    2.24  #ifndef _LP64
    2.25    if (x->base()->type()->tag() == longTag) {
    2.26      base_op = new_register(T_INT);
    2.27      __ convert(Bytecodes::_l2i, base.result(), base_op);
    2.28 -  } else {
    2.29 -    assert(x->base()->type()->tag() == intTag, "must be");
    2.30    }
    2.31 +  if (x->has_index()) {
    2.32 +    if (x->index()->type()->tag() == longTag) {
    2.33 +      LIR_Opr long_index_op = index_op;
    2.34 +      if (x->index()->type()->is_constant()) {
    2.35 +        long_index_op = new_register(T_LONG);
    2.36 +        __ move(index_op, long_index_op);
    2.37 +      }
    2.38 +      index_op = new_register(T_INT);
    2.39 +      __ convert(Bytecodes::_l2i, long_index_op, index_op);
    2.40 +    } else {
    2.41 +      assert(x->index()->type()->tag() == intTag, "must be");
    2.42 +    }
    2.43 +  }
    2.44 +  // At this point base and index should be all ints.
    2.45 +  assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
    2.46 +  assert(!x->has_index() || index_op->type() == T_INT, "index should be an int");
    2.47 +#else
    2.48 +  if (x->has_index()) {
    2.49 +    if (x->index()->type()->tag() == intTag) {
    2.50 +      if (!x->index()->type()->is_constant()) {
    2.51 +        index_op = new_register(T_LONG);
    2.52 +        __ convert(Bytecodes::_i2l, idx.result(), index_op);
    2.53 +      }
    2.54 +    } else {
    2.55 +      assert(x->index()->type()->tag() == longTag, "must be");
    2.56 +      if (x->index()->type()->is_constant()) {
    2.57 +        index_op = new_register(T_LONG);
    2.58 +        __ move(idx.result(), index_op);
    2.59 +      }
    2.60 +    }
    2.61 +  }
    2.62 +  // At this point base is a long non-constant
    2.63 +  // Index is a long register or a int constant.
    2.64 +  // We allow the constant to stay an int because that would allow us a more compact encoding by
    2.65 +  // embedding an immediate offset in the address expression. If we have a long constant, we have to
    2.66 +  // move it into a register first.
    2.67 +  assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a long non-constant");
    2.68 +  assert(!x->has_index() || (index_op->type() == T_INT && index_op->is_constant()) ||
    2.69 +                            (index_op->type() == T_LONG && !index_op->is_constant()), "unexpected index type");
    2.70  #endif
    2.71  
    2.72    BasicType dst_type = x->basic_type();
    2.73 -  LIR_Opr index_op = idx.result();
    2.74  
    2.75    LIR_Address* addr;
    2.76    if (index_op->is_constant()) {
    2.77      assert(log2_scale == 0, "must not have a scale");
    2.78 +    assert(index_op->type() == T_INT, "only int constants supported");
    2.79      addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
    2.80    } else {
    2.81  #ifdef X86
    2.82 -#ifdef _LP64
    2.83 -    if (!index_op->is_illegal() && index_op->type() == T_INT) {
    2.84 -      LIR_Opr tmp = new_pointer_register();
    2.85 -      __ convert(Bytecodes::_i2l, index_op, tmp);
    2.86 -      index_op = tmp;
    2.87 -    }
    2.88 -#endif
    2.89      addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
    2.90  #elif defined(ARM)
    2.91      addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
    2.92  #else
    2.93      if (index_op->is_illegal() || log2_scale == 0) {
    2.94 -#ifdef _LP64
    2.95 -      if (!index_op->is_illegal() && index_op->type() == T_INT) {
    2.96 -        LIR_Opr tmp = new_pointer_register();
    2.97 -        __ convert(Bytecodes::_i2l, index_op, tmp);
    2.98 -        index_op = tmp;
    2.99 -      }
   2.100 -#endif
   2.101        addr = new LIR_Address(base_op, index_op, dst_type);
   2.102      } else {
   2.103        LIR_Opr tmp = new_pointer_register();
   2.104 @@ -2126,7 +2151,6 @@
   2.105    BasicType type = x->basic_type();
   2.106  
   2.107    if (x->has_index()) {
   2.108 -    assert(x->index()->type()->tag() == intTag, "should not find non-int index");
   2.109      log2_scale = x->log2_scale();
   2.110    }
   2.111  
   2.112 @@ -2149,38 +2173,39 @@
   2.113    set_no_result(x);
   2.114  
   2.115    LIR_Opr base_op = base.result();
   2.116 +  LIR_Opr index_op = idx.result();
   2.117 +
   2.118  #ifndef _LP64
   2.119    if (x->base()->type()->tag() == longTag) {
   2.120      base_op = new_register(T_INT);
   2.121      __ convert(Bytecodes::_l2i, base.result(), base_op);
   2.122 -  } else {
   2.123 -    assert(x->base()->type()->tag() == intTag, "must be");
   2.124    }
   2.125 +  if (x->has_index()) {
   2.126 +    if (x->index()->type()->tag() == longTag) {
   2.127 +      index_op = new_register(T_INT);
   2.128 +      __ convert(Bytecodes::_l2i, idx.result(), index_op);
   2.129 +    }
   2.130 +  }
   2.131 +  // At this point base and index should be all ints and not constants
   2.132 +  assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
   2.133 +  assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int");
   2.134 +#else
   2.135 +  if (x->has_index()) {
   2.136 +    if (x->index()->type()->tag() == intTag) {
   2.137 +      index_op = new_register(T_LONG);
   2.138 +      __ convert(Bytecodes::_i2l, idx.result(), index_op);
   2.139 +    }
   2.140 +  }
   2.141 +  // At this point base and index are long and non-constant
   2.142 +  assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a non-constant long");
   2.143 +  assert(!x->has_index() || (index_op->type() == T_LONG && !index_op->is_constant()), "index must be a non-constant long");
   2.144  #endif
   2.145  
   2.146 -  LIR_Opr index_op = idx.result();
   2.147    if (log2_scale != 0) {
   2.148      // temporary fix (platform dependent code without shift on Intel would be better)
   2.149 -    index_op = new_pointer_register();
   2.150 -#ifdef _LP64
   2.151 -    if(idx.result()->type() == T_INT) {
   2.152 -      __ convert(Bytecodes::_i2l, idx.result(), index_op);
   2.153 -    } else {
   2.154 -#endif
   2.155 -      // TODO: ARM also allows embedded shift in the address
   2.156 -      __ move(idx.result(), index_op);
   2.157 -#ifdef _LP64
   2.158 -    }
   2.159 -#endif
   2.160 +    // TODO: ARM also allows embedded shift in the address
   2.161      __ shift_left(index_op, log2_scale, index_op);
   2.162    }
   2.163 -#ifdef _LP64
   2.164 -  else if(!index_op->is_illegal() && index_op->type() == T_INT) {
   2.165 -    LIR_Opr tmp = new_pointer_register();
   2.166 -    __ convert(Bytecodes::_i2l, index_op, tmp);
   2.167 -    index_op = tmp;
   2.168 -  }
   2.169 -#endif
   2.170  
   2.171    LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
   2.172    __ move(value.result(), addr);

mercurial