comparison src/share/vm/opto/parseHelper.cpp @ 20627:e7b3d177adda

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>
author zmajo
date Mon, 10 Nov 2014 17:14:59 +0100
parents 2113136690bc
children 7848fc12602b
comparison
equal deleted inserted replaced
20626:1a2069ede139 20627:e7b3d177adda
154 154
155 // Extract the array klass type 155 // Extract the array klass type
156 int klass_offset = oopDesc::klass_offset_in_bytes(); 156 int klass_offset = oopDesc::klass_offset_in_bytes();
157 Node* p = basic_plus_adr( ary, ary, klass_offset ); 157 Node* p = basic_plus_adr( ary, ary, klass_offset );
158 // p's type is array-of-OOPS plus 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) ); 159 Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS));
160 // Get the array klass 160 // Get the array klass
161 const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr(); 161 const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();
162 162
163 // array_klass's type is generally INexact array-of-oop. Heroically 163 // The type of array_klass is usually INexact array-of-oop. Heroically
164 // cast the array klass to EXACT array and uncommon-trap if the cast 164 // cast array_klass to EXACT array and uncommon-trap if the cast fails.
165 // fails. 165 // Make constant out of the inexact array klass, but use it only if the cast
166 // succeeds.
166 bool always_see_exact_class = false; 167 bool always_see_exact_class = false;
167 if (MonomorphicArrayCheck 168 if (MonomorphicArrayCheck
168 && !too_many_traps(Deoptimization::Reason_array_check)) { 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
169 always_see_exact_class = true; 193 always_see_exact_class = true;
170 // (If no MDO at all, hope for the best, until a trap actually occurs.) 194 // (If no MDO at all, hope for the best, until a trap actually occurs.)
171 } 195
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 196 // Make a constant out of the inexact array klass
176 const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr(); 197 const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr();
177 Node* con = makecon(extak); 198 Node* con = makecon(extak);
178 Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con )); 199 Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con ));
179 Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq )); 200 Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq ));
200 // Come here for polymorphic array klasses 221 // Come here for polymorphic array klasses
201 222
202 // Extract the array element class 223 // Extract the array element class
203 int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset()); 224 int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset());
204 Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); 225 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) ); 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));
206 231
207 // Check (the hard way) and throw if not a subklass. 232 // Check (the hard way) and throw if not a subklass.
208 // Result is ignored, we just need the CFG effects. 233 // Result is ignored, we just need the CFG effects.
209 gen_checkcast( obj, a_e_klass ); 234 gen_checkcast(obj, a_e_klass);
210 } 235 }
211 236
212 237
213 void Parse::emit_guard_for_new(ciInstanceKlass* klass) { 238 void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
214 // Emit guarded new 239 // Emit guarded new