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>

Split Split Close
Expand all
Collapse all
          --- old/hotspot/src/share/vm/opto/memnode.hpp
          +++ new/hotspot/src/share/vm/opto/memnode.hpp
↓ open down ↓ 140 lines elided ↑ open up ↑
 141  141  private:
 142  142    // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
 143  143    // loads that can be reordered, and such requiring acquire semantics to
 144  144    // adhere to the Java specification.  The required behaviour is stored in
 145  145    // this field.
 146  146    const MemOrd _mo;
 147  147  
 148  148  protected:
 149  149    virtual uint cmp(const Node &n) const;
 150  150    virtual uint size_of() const; // Size is bigger
      151 +  // Should LoadNode::Ideal() attempt to remove control edges?
      152 +  virtual bool can_remove_control() const;
 151  153    const Type* const _type;      // What kind of value is loaded?
 152  154  public:
 153  155  
 154  156    LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo)
 155  157      : MemNode(c,mem,adr,at), _type(rt), _mo(mo) {
 156  158      init_class_id(Class_Load);
 157  159    }
 158  160    inline bool is_unordered() const { return !is_acquire(); }
 159  161    inline bool is_acquire() const {
 160  162      assert(_mo == unordered || _mo == acquire, "unexpected");
↓ open down ↓ 3 lines elided ↑ open up ↑
 164  166    // Polymorphic factory method:
 165  167     static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
 166  168                       const TypePtr* at, const Type *rt, BasicType bt, MemOrd mo);
 167  169  
 168  170    virtual uint hash()   const;  // Check the type
 169  171  
 170  172    // Handle algebraic identities here.  If we have an identity, return the Node
 171  173    // we are equivalent to.  We look for Load of a Store.
 172  174    virtual Node *Identity( PhaseTransform *phase );
 173  175  
 174      -  // If the load is from Field memory and the pointer is non-null, we can
      176 +  // If the load is from Field memory and the pointer is non-null, it might be possible to
 175  177    // zero out the control input.
      178 +  // If the offset is constant and the base is an object allocation,
      179 +  // try to hook me up to the exact initializing store.
 176  180    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 177  181  
 178  182    // Split instance field load through Phi.
 179  183    Node* split_through_phi(PhaseGVN *phase);
 180  184  
 181  185    // Recover original value from boxed values
 182  186    Node *eliminate_autobox(PhaseGVN *phase);
 183  187  
 184  188    // Compute a new Type for this node.  Basically we just do the pre-check,
 185  189    // then call the virtual add() to set the type.
↓ open down ↓ 220 lines elided ↑ open up ↑
 406  410      : LoadNode(c, mem, adr, at, t, mo) {}
 407  411    virtual int Opcode() const;
 408  412    virtual uint ideal_reg() const { return Op_RegN; }
 409  413    virtual int store_Opcode() const { return Op_StoreN; }
 410  414    virtual BasicType memory_type() const { return T_NARROWOOP; }
 411  415  };
 412  416  
 413  417  //------------------------------LoadKlassNode----------------------------------
 414  418  // Load a Klass from an object
 415  419  class LoadKlassNode : public LoadPNode {
      420 +protected:
      421 +  // In most cases, LoadKlassNode does not have the control input set. If the control
      422 +  // input is set, it must not be removed (by LoadNode::Ideal()).
      423 +  virtual bool can_remove_control() const;
 416  424  public:
 417  425    LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
 418  426      : LoadPNode(c, mem, adr, at, tk, mo) {}
 419  427    virtual int Opcode() const;
 420  428    virtual const Type *Value( PhaseTransform *phase ) const;
 421  429    virtual Node *Identity( PhaseTransform *phase );
 422  430    virtual bool depends_only_on_test() const { return true; }
 423  431  
 424  432    // Polymorphic factory method:
 425      -  static Node* make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at,
 426      -                     const TypeKlassPtr *tk = TypeKlassPtr::OBJECT );
      433 +  static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at,
      434 +                    const TypeKlassPtr* tk = TypeKlassPtr::OBJECT);
 427  435  };
 428  436  
 429  437  //------------------------------LoadNKlassNode---------------------------------
 430  438  // Load a narrow Klass from an object.
 431  439  class LoadNKlassNode : public LoadNNode {
 432  440  public:
 433  441    LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo)
 434  442      : LoadNNode(c, mem, adr, at, tk, mo) {}
 435  443    virtual int Opcode() const;
 436  444    virtual uint ideal_reg() const { return Op_RegN; }
↓ open down ↓ 1008 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX