< prev index next >
hotspot/src/share/vm/opto/memnode.hpp
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>
*** 146,155 ****
--- 146,157 ----
const MemOrd _mo;
protected:
virtual uint cmp(const Node &n) const;
virtual uint size_of() const; // Size is bigger
+ // Should LoadNode::Ideal() attempt to remove control edges?
+ virtual bool can_remove_control() const;
const Type* const _type; // What kind of value is loaded?
public:
LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo)
: MemNode(c,mem,adr,at), _type(rt), _mo(mo) {
*** 169,180 ****
// Handle algebraic identities here. If we have an identity, return the Node
// we are equivalent to. We look for Load of a Store.
virtual Node *Identity( PhaseTransform *phase );
! // If the load is from Field memory and the pointer is non-null, we can
// zero out the control input.
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
// Split instance field load through Phi.
Node* split_through_phi(PhaseGVN *phase);
--- 171,184 ----
// Handle algebraic identities here. If we have an identity, return the Node
// we are equivalent to. We look for Load of a Store.
virtual Node *Identity( PhaseTransform *phase );
! // 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.
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
// Split instance field load through Phi.
Node* split_through_phi(PhaseGVN *phase);
*** 411,431 ****
};
//------------------------------LoadKlassNode----------------------------------
// Load a Klass from an object
class LoadKlassNode : public LoadPNode {
public:
LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
: LoadPNode(c, mem, adr, at, tk, mo) {}
virtual int Opcode() const;
virtual const Type *Value( PhaseTransform *phase ) const;
virtual Node *Identity( PhaseTransform *phase );
virtual bool depends_only_on_test() const { return true; }
// Polymorphic factory method:
! static Node* make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at,
! const TypeKlassPtr *tk = TypeKlassPtr::OBJECT );
};
//------------------------------LoadNKlassNode---------------------------------
// Load a narrow Klass from an object.
class LoadNKlassNode : public LoadNNode {
--- 415,439 ----
};
//------------------------------LoadKlassNode----------------------------------
// Load a Klass from an object
class LoadKlassNode : public LoadPNode {
+ protected:
+ // 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()).
+ virtual bool can_remove_control() const;
public:
LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
: LoadPNode(c, mem, adr, at, tk, mo) {}
virtual int Opcode() const;
virtual const Type *Value( PhaseTransform *phase ) const;
virtual Node *Identity( PhaseTransform *phase );
virtual bool depends_only_on_test() const { return true; }
// Polymorphic factory method:
! static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at,
! const TypeKlassPtr* tk = TypeKlassPtr::OBJECT);
};
//------------------------------LoadNKlassNode---------------------------------
// Load a narrow Klass from an object.
class LoadNKlassNode : public LoadNNode {
< prev index next >