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 7063 : 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


  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 Node *CastIINode::Identity(PhaseTransform *phase) {
  87   if (_inexact) {
  88     return this;
  89   }
  90   return ConstraintCastNode::Identity(phase);
  91 }
  92 
  93 Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) {
  94   Node* res = ConstraintCastNode::Ideal(phase, can_reshape);
  95   // Try to improve the type of the CastII if we recognize a CmpI/If
  96   // pattern.
  97   if (res == NULL && _inexact) {
  98     if (in(0) != NULL && (in(0)->is_IfFalse() || in(0)->is_IfTrue())) {
  99       Node* proj = in(0);
 100       if (proj->in(0)->in(1)->is_Bool()) {
 101         Node* b = proj->in(0)->in(1);
 102         if (b->in(1)->Opcode() == Op_CmpI) {
 103           Node* cmp = b->in(1);
 104           if (cmp->in(1) == in(1)) {
 105             const TypeInt* in2_t = phase->type(cmp->in(2))->is_int();
 106             const Type* t = TypeInt::INT;
 107             BoolTest test = b->as_Bool()->_test;
 108             if (proj->is_IfFalse()) {
 109               test = test.negate();
 110             }
 111             BoolTest::mask m = test._test;
 112             jlong lo_long = min_jint;
 113             jlong hi_long = max_jint;
 114             if (m == BoolTest::le || m == BoolTest::lt) {
 115               hi_long = in2_t->_hi;
 116               if (m == BoolTest::lt) {
 117                 hi_long -= 1;
 118               }
 119             } else if (m == BoolTest::ge || m == BoolTest::gt) {
 120               lo_long = in2_t->_lo;
 121               if (m == BoolTest::gt) {
 122                 lo_long += 1;
 123               }
 124             } else if (m == BoolTest::eq) {
 125               lo_long = in2_t->_lo;
 126               hi_long = in2_t->_hi;
 127             } else if (m == BoolTest::ne) {
 128               // can't do any better
 129             } else {
 130               ShouldNotReachHere();
 131             }
 132             int lo_int = (int)lo_long;
 133             int hi_int = (int)hi_long;
 134             
 135             if (lo_long != (jlong)lo_int) {
 136               lo_int = min_jint;
 137             }
 138             if (hi_long != (jlong)hi_int) {
 139               hi_int = max_jint;
 140             }
 141 
 142             t = TypeInt::make(lo_int, hi_int, Type::WidenMax);
 143             t = t->filter_speculative(_type);
 144             if (_type != t || in2_t->is_con()) {
 145               CastIINode* castii = new CastIINode(in(1), t, _required, !in2_t->is_con());
 146               castii->set_req(0, in(0));
 147               res = castii;
 148             }
 149           }
 150         }
 151       }
 152     }
 153   }
 154   return res;
 155 }
 156 
 157 Node *CastIINode::Ideal_DU_postCCP(PhaseCCP *ccp) {
 158   if (_required) {
 159     return NULL;
 160   }
 161   return ConstraintCastNode::Ideal_DU_postCCP(ccp);
 162 }
 163 
 164 #ifndef PRODUCT
 165 void CastIINode::dump_spec(outputStream *st) const {
 166   TypeNode::dump_spec(st);
 167   if (_inexact) {
 168     st->print(" inexact");
 169   }
 170   if (_required) {
 171     st->print(" required");
 172   }
 173 }
 174 #endif
 175 
 176 //=============================================================================
 177 
 178 //------------------------------Ideal_DU_postCCP-------------------------------
 179 // If not converting int->oop, throw away cast after constant propagation
 180 Node *CastPPNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
 181   const Type *t = ccp->type(in(1));
 182   if (!t->isa_oop_ptr() || ((in(1)->is_DecodeN()) && Matcher::gen_narrow_oop_implicit_null_checks())) {
 183     return NULL; // do not transform raw pointers or narrow oops
 184   }
 185   return ConstraintCastNode::Ideal_DU_postCCP(ccp);
 186 }
 187 
 188 
 189 
 190 //=============================================================================
 191 //------------------------------Identity---------------------------------------
 192 // If input is already higher or equal to cast type, then this is an identity.
 193 Node *CheckCastPPNode::Identity( PhaseTransform *phase ) {
 194   // 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