< prev index next >

hotspot/src/share/vm/opto/memnode.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>

*** 857,866 **** --- 857,870 ---- return NULL; // No progress } //============================================================================= + // Should LoadNode::Ideal() attempt to remove control edges? + bool LoadNode::can_remove_control() const { + return true; + } uint LoadNode::size_of() const { return sizeof(*this); } uint LoadNode::cmp( const Node &n ) const { return !Type::cmp( _type, ((LoadNode&)n)._type ); } const Type *LoadNode::bottom_type() const { return _type; } uint LoadNode::ideal_reg() const {
*** 1453,1463 **** igvn->register_new_node_with_optimizer(phi); return phi; } //------------------------------Ideal------------------------------------------ ! // If the load is from Field memory and the pointer is non-null, we can // zero out the control input. // If the offset is constant and the base is an object allocation, // try to hook me up to the exact initializing store. Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* p = MemNode::Ideal_common(phase, can_reshape); --- 1457,1467 ---- igvn->register_new_node_with_optimizer(phi); return phi; } //------------------------------Ideal------------------------------------------ ! // If the load is from Field memory and the pointer is non-null, it might be possible to // zero out the control input. // If the offset is constant and the base is an object allocation, // try to hook me up to the exact initializing store. Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* p = MemNode::Ideal_common(phase, can_reshape);
*** 1478,1487 **** --- 1482,1492 ---- Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); if (base != NULL && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) { // Check for useless control edge in some common special cases if (in(MemNode::Control) != NULL + && can_remove_control() && phase->type(base)->higher_equal(TypePtr::NOTNULL) && all_controls_dominate(base, phase->C->start())) { // A method-invariant, non-null address (constant or 'this' argument). set_req(MemNode::Control, NULL); }
*** 2005,2017 **** } //============================================================================= //----------------------------LoadKlassNode::make------------------------------ // Polymorphic factory method: ! Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) { Compile* C = gvn.C; - Node *ctl = NULL; // sanity check the alias category against the created node type const TypePtr *adr_type = adr->bottom_type()->isa_ptr(); assert(adr_type != NULL, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { --- 2010,2021 ---- } //============================================================================= //----------------------------LoadKlassNode::make------------------------------ // Polymorphic factory method: ! Node* LoadKlassNode::make(PhaseGVN& gvn, Node* ctl, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk) { Compile* C = gvn.C; // sanity check the alias category against the created node type const TypePtr *adr_type = adr->bottom_type()->isa_ptr(); assert(adr_type != NULL, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) {
*** 2027,2036 **** --- 2031,2046 ---- //------------------------------Value------------------------------------------ const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { return klass_value_common(phase); } + // In most cases, LoadKlassNode does not have the control input set. If the control + // input is set, it must not be removed (by LoadNode::Ideal()). + bool LoadKlassNode::can_remove_control() const { + return false; + } + const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP const Type *t1 = phase->type( in(MemNode::Memory) ); if (t1 == Type::TOP) return Type::TOP; Node *adr = in(MemNode::Address);
< prev index next >