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.cpp
          +++ new/hotspot/src/share/vm/opto/memnode.cpp
↓ open down ↓ 851 lines elided ↑ open up ↑
 852  852        }
 853  853        break;
 854  854      }
 855  855    }
 856  856  
 857  857    return  NULL;               // No progress
 858  858  }
 859  859  
 860  860  
 861  861  //=============================================================================
      862 +// Should LoadNode::Ideal() attempt to remove control edges?
      863 +bool LoadNode::can_remove_control() const {
      864 +  return true;
      865 +}
 862  866  uint LoadNode::size_of() const { return sizeof(*this); }
 863  867  uint LoadNode::cmp( const Node &n ) const
 864  868  { return !Type::cmp( _type, ((LoadNode&)n)._type ); }
 865  869  const Type *LoadNode::bottom_type() const { return _type; }
 866  870  uint LoadNode::ideal_reg() const {
 867  871    return _type->ideal_reg();
 868  872  }
 869  873  
 870  874  #ifndef PRODUCT
 871  875  void LoadNode::dump_spec(outputStream *st) const {
↓ open down ↓ 576 lines elided ↑ open up ↑
1448 1452        igvn->remove_dead_node(the_clone);
1449 1453      }
1450 1454      phi->set_req(i, x);
1451 1455    }
1452 1456    // Record Phi
1453 1457    igvn->register_new_node_with_optimizer(phi);
1454 1458    return phi;
1455 1459  }
1456 1460  
1457 1461  //------------------------------Ideal------------------------------------------
1458      -// If the load is from Field memory and the pointer is non-null, we can
     1462 +// If the load is from Field memory and the pointer is non-null, it might be possible to
1459 1463  // zero out the control input.
1460 1464  // If the offset is constant and the base is an object allocation,
1461 1465  // try to hook me up to the exact initializing store.
1462 1466  Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1463 1467    Node* p = MemNode::Ideal_common(phase, can_reshape);
1464 1468    if (p)  return (p == NodeSentinel) ? NULL : p;
1465 1469  
1466 1470    Node* ctrl    = in(MemNode::Control);
1467 1471    Node* address = in(MemNode::Address);
1468 1472  
↓ open down ↓ 4 lines elided ↑ open up ↑
1473 1477      ctrl = ctrl->in(0);
1474 1478      set_req(MemNode::Control,ctrl);
1475 1479    }
1476 1480  
1477 1481    intptr_t ignore = 0;
1478 1482    Node*    base   = AddPNode::Ideal_base_and_offset(address, phase, ignore);
1479 1483    if (base != NULL
1480 1484        && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) {
1481 1485      // Check for useless control edge in some common special cases
1482 1486      if (in(MemNode::Control) != NULL
     1487 +        && can_remove_control()
1483 1488          && phase->type(base)->higher_equal(TypePtr::NOTNULL)
1484 1489          && all_controls_dominate(base, phase->C->start())) {
1485 1490        // A method-invariant, non-null address (constant or 'this' argument).
1486 1491        set_req(MemNode::Control, NULL);
1487 1492      }
1488 1493    }
1489 1494  
1490 1495    Node* mem = in(MemNode::Memory);
1491 1496    const TypePtr *addr_t = phase->type(address)->isa_ptr();
1492 1497  
↓ open down ↓ 507 lines elided ↑ open up ↑
2000 2005      // a singleton Value is needed for split_thru_phi optimization.
2001 2006      int con = value->get_int();
2002 2007      return TypeInt::make((con << 16) >> 16);
2003 2008    }
2004 2009    return LoadNode::Value(phase);
2005 2010  }
2006 2011  
2007 2012  //=============================================================================
2008 2013  //----------------------------LoadKlassNode::make------------------------------
2009 2014  // Polymorphic factory method:
2010      -Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) {
     2015 +Node* LoadKlassNode::make(PhaseGVN& gvn, Node* ctl, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk) {
2011 2016    Compile* C = gvn.C;
2012      -  Node *ctl = NULL;
2013 2017    // sanity check the alias category against the created node type
2014 2018    const TypePtr *adr_type = adr->bottom_type()->isa_ptr();
2015 2019    assert(adr_type != NULL, "expecting TypeKlassPtr");
2016 2020  #ifdef _LP64
2017 2021    if (adr_type->is_ptr_to_narrowklass()) {
2018 2022      assert(UseCompressedClassPointers, "no compressed klasses");
2019 2023      Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered));
2020 2024      return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr());
2021 2025    }
2022 2026  #endif
2023 2027    assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
2024 2028    return new (C) LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered);
2025 2029  }
2026 2030  
2027 2031  //------------------------------Value------------------------------------------
2028 2032  const Type *LoadKlassNode::Value( PhaseTransform *phase ) const {
2029 2033    return klass_value_common(phase);
2030 2034  }
2031 2035  
     2036 +// In most cases, LoadKlassNode does not have the control input set. If the control
     2037 +// input is set, it must not be removed (by LoadNode::Ideal()).
     2038 +bool LoadKlassNode::can_remove_control() const {
     2039 +  return false;
     2040 +}
     2041 +
2032 2042  const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const {
2033 2043    // Either input is TOP ==> the result is TOP
2034 2044    const Type *t1 = phase->type( in(MemNode::Memory) );
2035 2045    if (t1 == Type::TOP)  return Type::TOP;
2036 2046    Node *adr = in(MemNode::Address);
2037 2047    const Type *t2 = phase->type( adr );
2038 2048    if (t2 == Type::TOP)  return Type::TOP;
2039 2049    const TypePtr *tp = t2->is_ptr();
2040 2050    if (TypePtr::above_centerline(tp->ptr()) ||
2041 2051        tp->ptr() == TypePtr::Null)  return Type::TOP;
↓ open down ↓ 2535 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX