< prev index next >

hotspot/src/share/vm/opto/parseHelper.cpp

Print this page
rev 6883 : 8057622: java/util/stream/test/org/openjdk/tests/java/util/stream/InfiniteStreamWithLimitOpTest: SEGV inside compiled code (sparc)
Summary: In Parse::array_store_check(), add control edge FROM IfTrue branch of runtime type check of the destination array TO loading _element_klass from destination array.
Reviewed-by: kvn, roland, anoll
Contributed-by: Zoltan Majo <zoltan.majo@oracle.com>


 139 // pull array from stack and check that the store is valid
 140 void Parse::array_store_check() {
 141 
 142   // Shorthand access to array store elements without popping them.
 143   Node *obj = peek(0);
 144   Node *idx = peek(1);
 145   Node *ary = peek(2);
 146 
 147   if (_gvn.type(obj) == TypePtr::NULL_PTR) {
 148     // There's never a type check on null values.
 149     // This cutout lets us avoid the uncommon_trap(Reason_array_check)
 150     // below, which turns into a performance liability if the
 151     // gen_checkcast folds up completely.
 152     return;
 153   }
 154 
 155   // Extract the array klass type
 156   int klass_offset = oopDesc::klass_offset_in_bytes();
 157   Node* p = basic_plus_adr( ary, ary, klass_offset );
 158   // p's type is array-of-OOPS plus klass_offset
 159   Node* array_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS) );
 160   // Get the array klass
 161   const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();
 162 
 163   // array_klass's type is generally INexact array-of-oop.  Heroically
 164   // cast the array klass to EXACT array and uncommon-trap if the cast
 165   // fails.

 166   bool always_see_exact_class = false;
 167   if (MonomorphicArrayCheck
 168       && !too_many_traps(Deoptimization::Reason_array_check)) {























 169     always_see_exact_class = true;
 170     // (If no MDO at all, hope for the best, until a trap actually occurs.)
 171   }
 172 
 173   // Is the array klass is exactly its defined type?
 174   if (always_see_exact_class && !tak->klass_is_exact()) {
 175     // Make a constant out of the inexact array klass
 176     const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr();
 177     Node* con = makecon(extak);
 178     Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con ));
 179     Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq ));
 180     Node* ctrl= control();
 181     { BuildCutout unless(this, bol, PROB_MAX);
 182       uncommon_trap(Deoptimization::Reason_array_check,
 183                     Deoptimization::Action_maybe_recompile,
 184                     tak->klass());
 185     }
 186     if (stopped()) {          // MUST uncommon-trap?
 187       set_control(ctrl);      // Then Don't Do It, just fall into the normal checking
 188     } else {                  // Cast array klass to exactness:
 189       // Use the exact constant value we know it is.
 190       replace_in_map(array_klass,con);
 191       CompileLog* log = C->log();
 192       if (log != NULL) {
 193         log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'",
 194                   log->identify(tak->klass()));
 195       }
 196       array_klass = con;      // Use cast value moving forward
 197     }
 198   }
 199 
 200   // Come here for polymorphic array klasses
 201 
 202   // Extract the array element class
 203   int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset());
 204   Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
 205   Node *a_e_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p2, tak) );




 206 
 207   // Check (the hard way) and throw if not a subklass.
 208   // Result is ignored, we just need the CFG effects.
 209   gen_checkcast( obj, a_e_klass );
 210 }
 211 
 212 
 213 void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
 214   // Emit guarded new
 215   //   if (klass->_init_thread != current_thread ||
 216   //       klass->_init_state != being_initialized)
 217   //      uncommon_trap
 218   Node* cur_thread = _gvn.transform( new (C) ThreadLocalNode() );
 219   Node* merge = new (C) RegionNode(3);
 220   _gvn.set_type(merge, Type::CONTROL);
 221   Node* kls = makecon(TypeKlassPtr::make(klass));
 222 
 223   Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
 224   Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
 225   Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
 226   Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
 227   IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
 228   set_control(IfTrue(iff));
 229   merge->set_req(1, IfFalse(iff));




 139 // pull array from stack and check that the store is valid
 140 void Parse::array_store_check() {
 141 
 142   // Shorthand access to array store elements without popping them.
 143   Node *obj = peek(0);
 144   Node *idx = peek(1);
 145   Node *ary = peek(2);
 146 
 147   if (_gvn.type(obj) == TypePtr::NULL_PTR) {
 148     // There's never a type check on null values.
 149     // This cutout lets us avoid the uncommon_trap(Reason_array_check)
 150     // below, which turns into a performance liability if the
 151     // gen_checkcast folds up completely.
 152     return;
 153   }
 154 
 155   // Extract the array klass type
 156   int klass_offset = oopDesc::klass_offset_in_bytes();
 157   Node* p = basic_plus_adr( ary, ary, klass_offset );
 158   // p's type is array-of-OOPS plus klass_offset
 159   Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS));
 160   // Get the array klass
 161   const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();
 162 
 163   // The type of array_klass is usually INexact array-of-oop.  Heroically
 164   // cast array_klass to EXACT array and uncommon-trap if the cast fails.
 165   // Make constant out of the inexact array klass, but use it only if the cast
 166   // succeeds.
 167   bool always_see_exact_class = false;
 168   if (MonomorphicArrayCheck
 169       && !too_many_traps(Deoptimization::Reason_array_check)
 170       && !tak->klass_is_exact()
 171       && tak != TypeKlassPtr::OBJECT) {
 172       // Regarding the fourth condition in the if-statement from above:
 173       //
 174       // If the compiler has determined that the type of array 'ary' (represented
 175       // by 'array_klass') is java/lang/Object, the compiler must not assume that
 176       // the array 'ary' is monomorphic.
 177       //
 178       // If 'ary' were of type java/lang/Object, this arraystore would have to fail,
 179       // because it is not possible to perform a arraystore into an object that is not
 180       // a "proper" array.
 181       //
 182       // Therefore, let's obtain at runtime the type of 'ary' and check if we can still
 183       // successfully perform the store.
 184       //
 185       // The implementation reasons for the condition are the following:
 186       //
 187       // java/lang/Object is the superclass of all arrays, but it is represented by the VM
 188       // as an InstanceKlass. The checks generated by gen_checkcast() (see below) expect
 189       // 'array_klass' to be ObjArrayKlass, which can result in invalid memory accesses.
 190       //
 191       // See issue JDK-8057622 for details.
 192 
 193     always_see_exact_class = true;
 194     // (If no MDO at all, hope for the best, until a trap actually occurs.)

 195 


 196     // Make a constant out of the inexact array klass
 197     const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr();
 198     Node* con = makecon(extak);
 199     Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con ));
 200     Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq ));
 201     Node* ctrl= control();
 202     { BuildCutout unless(this, bol, PROB_MAX);
 203       uncommon_trap(Deoptimization::Reason_array_check,
 204                     Deoptimization::Action_maybe_recompile,
 205                     tak->klass());
 206     }
 207     if (stopped()) {          // MUST uncommon-trap?
 208       set_control(ctrl);      // Then Don't Do It, just fall into the normal checking
 209     } else {                  // Cast array klass to exactness:
 210       // Use the exact constant value we know it is.
 211       replace_in_map(array_klass,con);
 212       CompileLog* log = C->log();
 213       if (log != NULL) {
 214         log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'",
 215                   log->identify(tak->klass()));
 216       }
 217       array_klass = con;      // Use cast value moving forward
 218     }
 219   }
 220 
 221   // Come here for polymorphic array klasses
 222 
 223   // Extract the array element class
 224   int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset());
 225   Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
 226   // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true,
 227   // we must set a control edge from the IfTrue node created by the uncommon_trap above to the
 228   // LoadKlassNode.
 229   Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL,
 230                                                        immutable_memory(), p2, tak));
 231 
 232   // Check (the hard way) and throw if not a subklass.
 233   // Result is ignored, we just need the CFG effects.
 234   gen_checkcast(obj, a_e_klass);
 235 }
 236 
 237 
 238 void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
 239   // Emit guarded new
 240   //   if (klass->_init_thread != current_thread ||
 241   //       klass->_init_state != being_initialized)
 242   //      uncommon_trap
 243   Node* cur_thread = _gvn.transform( new (C) ThreadLocalNode() );
 244   Node* merge = new (C) RegionNode(3);
 245   _gvn.set_type(merge, Type::CONTROL);
 246   Node* kls = makecon(TypeKlassPtr::make(klass));
 247 
 248   Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
 249   Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
 250   Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
 251   Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
 252   IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
 253   set_control(IfTrue(iff));
 254   merge->set_req(1, IfFalse(iff));


< prev index next >