src/share/vm/opto/castnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/castnode.cpp

Print this page
rev 7345 : 8054478: C2: Incorrectly compiled char[] array access crashes JVM
Summary: propagate node replacements along control flow edges to callers
Reviewed-by: dead backbranch in main loop results in erroneous array access
rev 7346 : reviews
rev 7347 : more reviews


  66   return ft;
  67 }
  68 
  69 //------------------------------Ideal------------------------------------------
  70 // Return a node which is more "ideal" than the current node.  Strip out
  71 // control copies
  72 Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape){
  73   return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL;
  74 }
  75 
  76 //------------------------------Ideal_DU_postCCP-------------------------------
  77 // Throw away cast after constant propagation
  78 Node *ConstraintCastNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
  79   const Type *t = ccp->type(in(1));
  80   ccp->hash_delete(this);
  81   set_type(t);                   // Turn into ID function
  82   ccp->hash_insert(this);
  83   return this;
  84 }
  85 































































































  86 
  87 //=============================================================================
  88 
  89 //------------------------------Ideal_DU_postCCP-------------------------------
  90 // If not converting int->oop, throw away cast after constant propagation
  91 Node *CastPPNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
  92   const Type *t = ccp->type(in(1));
  93   if (!t->isa_oop_ptr() || ((in(1)->is_DecodeN()) && Matcher::gen_narrow_oop_implicit_null_checks())) {
  94     return NULL; // do not transform raw pointers or narrow oops
  95   }
  96   return ConstraintCastNode::Ideal_DU_postCCP(ccp);
  97 }
  98 
  99 
 100 
 101 //=============================================================================
 102 //------------------------------Identity---------------------------------------
 103 // If input is already higher or equal to cast type, then this is an identity.
 104 Node *CheckCastPPNode::Identity( PhaseTransform *phase ) {
 105   // Toned down to rescue meeting at a Phi 3 different oops all implementing




  66   return ft;
  67 }
  68 
  69 //------------------------------Ideal------------------------------------------
  70 // Return a node which is more "ideal" than the current node.  Strip out
  71 // control copies
  72 Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape){
  73   return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL;
  74 }
  75 
  76 //------------------------------Ideal_DU_postCCP-------------------------------
  77 // Throw away cast after constant propagation
  78 Node *ConstraintCastNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
  79   const Type *t = ccp->type(in(1));
  80   ccp->hash_delete(this);
  81   set_type(t);                   // Turn into ID function
  82   ccp->hash_insert(this);
  83   return this;
  84 }
  85 
  86 uint CastIINode::size_of() const {
  87   return sizeof(*this);
  88 }
  89 
  90 uint CastIINode::cmp(const Node &n) const {
  91   return TypeNode::cmp(n) && ((CastIINode&)n)._carry_dependency == _carry_dependency;
  92 }
  93 
  94 Node *CastIINode::Identity(PhaseTransform *phase) {
  95   if (_carry_dependency) {
  96     return this;
  97   }
  98   return ConstraintCastNode::Identity(phase);
  99 }
 100 
 101 const Type *CastIINode::Value(PhaseTransform *phase) const {
 102   const Type *res = ConstraintCastNode::Value(phase);
 103 
 104   // Try to improve the type of the CastII if we recognize a CmpI/If
 105   // pattern.
 106   if (_carry_dependency) {
 107     if (in(0) != NULL && (in(0)->is_IfFalse() || in(0)->is_IfTrue())) {
 108       Node* proj = in(0);
 109       if (proj->in(0)->in(1)->is_Bool()) {
 110         Node* b = proj->in(0)->in(1);
 111         if (b->in(1)->Opcode() == Op_CmpI) {
 112           Node* cmp = b->in(1);
 113           if (cmp->in(1) == in(1) && phase->type(cmp->in(2))->isa_int()) {
 114             const TypeInt* in2_t = phase->type(cmp->in(2))->is_int();
 115             const Type* t = TypeInt::INT;
 116             BoolTest test = b->as_Bool()->_test;
 117             if (proj->is_IfFalse()) {
 118               test = test.negate();
 119             }
 120             BoolTest::mask m = test._test;
 121             jlong lo_long = min_jint;
 122             jlong hi_long = max_jint;
 123             if (m == BoolTest::le || m == BoolTest::lt) {
 124               hi_long = in2_t->_hi;
 125               if (m == BoolTest::lt) {
 126                 hi_long -= 1;
 127               }
 128             } else if (m == BoolTest::ge || m == BoolTest::gt) {
 129               lo_long = in2_t->_lo;
 130               if (m == BoolTest::gt) {
 131                 lo_long += 1;
 132               }
 133             } else if (m == BoolTest::eq) {
 134               lo_long = in2_t->_lo;
 135               hi_long = in2_t->_hi;
 136             } else if (m == BoolTest::ne) {
 137               // can't do any better
 138             } else {
 139               stringStream ss;
 140               test.dump_on(&ss);
 141               fatal(err_msg_res("unexpected comparison %s", ss.as_string()));
 142             }
 143             int lo_int = (int)lo_long;
 144             int hi_int = (int)hi_long;
 145             
 146             if (lo_long != (jlong)lo_int) {
 147               lo_int = min_jint;
 148             }
 149             if (hi_long != (jlong)hi_int) {
 150               hi_int = max_jint;
 151             }
 152 
 153             t = TypeInt::make(lo_int, hi_int, Type::WidenMax);
 154 
 155             res = res->filter_speculative(t);
 156 
 157             return res;
 158           }
 159         }
 160       }
 161     }
 162   }
 163   return res;
 164 }
 165 
 166 Node *CastIINode::Ideal_DU_postCCP(PhaseCCP *ccp) {
 167   if (_carry_dependency) {
 168     return NULL;
 169   }
 170   return ConstraintCastNode::Ideal_DU_postCCP(ccp);
 171 }
 172 
 173 #ifndef PRODUCT
 174 void CastIINode::dump_spec(outputStream *st) const {
 175   TypeNode::dump_spec(st);
 176   if (_carry_dependency) {
 177     st->print(" carry dependency");
 178   }
 179 }
 180 #endif
 181 
 182 //=============================================================================
 183 
 184 //------------------------------Ideal_DU_postCCP-------------------------------
 185 // If not converting int->oop, throw away cast after constant propagation
 186 Node *CastPPNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
 187   const Type *t = ccp->type(in(1));
 188   if (!t->isa_oop_ptr() || ((in(1)->is_DecodeN()) && Matcher::gen_narrow_oop_implicit_null_checks())) {
 189     return NULL; // do not transform raw pointers or narrow oops
 190   }
 191   return ConstraintCastNode::Ideal_DU_postCCP(ccp);
 192 }
 193 
 194 
 195 
 196 //=============================================================================
 197 //------------------------------Identity---------------------------------------
 198 // If input is already higher or equal to cast type, then this is an identity.
 199 Node *CheckCastPPNode::Identity( PhaseTransform *phase ) {
 200   // Toned down to rescue meeting at a Phi 3 different oops all implementing


src/share/vm/opto/castnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File