JDK-6579652 : repair to split_through_phi breaks AddPNode::Base invariant
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-07-12
  • Updated: 2010-04-02
  • Resolved: 2009-01-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u10Fixed 7Fixed hs11Fixed
Related Reports
Relates :  
Description
The fix to 6552204 can sometimes cause a tree of AddPNodes to lose their common base.  The variable PhiNode 'base' can have a type which differs slightly from a pre-existing Phi which already serves as the base elsewhere in the tree.

Comments
EVALUATION the report is correct.
12-07-2007

SUGGESTED FIX #! /bin/sh # This is a shell script generated by sccs-diff-tree. # It will apply diffs to the following files: # src/share/vm/opto/cfgnode.cpp # src/share/vm/opto/type.cpp IFS="${IFS}" # Include ^L (page separator) as whitespace. : ${PATCH=patch} # Where is the patch program? : ${PATCHFLAGS="-g1"} # What are the default options for patch? # sccs diffs -u src/share/vm/opto/type.cpp $PATCH $PATCHFLAGS -p0 src/share/vm/opto/type.cpp <<'@@end@@' ------- src/share/vm/opto/type.cpp ------- --- /tmp/sccs.zhaaSt 2007-07-11 18:45:30.857321832 -0700 +++ src/share/vm/opto/type.cpp 2007-07-11 18:19:40.124330000 -0700 @@ -1708,8 +1708,20 @@ //============================================================================= // Convenience common pre-built types. +inline const TypeInt* normalize_array_size(const TypeInt* size) { + // Certain normalizations keep us sane when comparing types. + // We do not want arrayOop variables to differ only by the wideness + // of their index types. Pick minimum wideness, since that is the + // forced wideness of small ranges anyway. + if (size->_widen != Type::WidenMin) + return TypeInt::make(size->_lo, size->_hi, Type::WidenMin); + else + return size; +} + //------------------------------make------------------------------------------- const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { + size = normalize_array_size(size); return (TypeAry*)(new TypeAry(elem,size))->hashcons(); } @@ -1742,7 +1754,9 @@ //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual const Type *TypeAry::xdual() const { - return new TypeAry( _elem->dual(), _size->dual()->is_int() ); + const TypeInt* size_dual = _size->dual()->is_int(); + size_dual = normalize_array_size(size_dual); + return new TypeAry( _elem->dual(), size_dual); } //------------------------------eq--------------------------------------------- @@end@@ # sccs diffs -u src/share/vm/opto/cfgnode.cpp $PATCH $PATCHFLAGS -p0 src/share/vm/opto/cfgnode.cpp <<'@@end@@' ------- src/share/vm/opto/cfgnode.cpp ------- --- /tmp/sccs.iiaaTt 2007-07-11 18:45:30.900685490 -0700 +++ src/share/vm/opto/cfgnode.cpp 2007-07-11 18:42:37.343214000 -0700 @@ -1579,12 +1579,31 @@ // Accumulate type for resulting Phi type = type->meet(in(i)->in(AddPNode::Base)->bottom_type()); } + Node* base = NULL; if (doit) { - Node* base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL); - for (uint i = 1; i < req(); i++) { - base->init_req(i, in(i)->in(AddPNode::Base)); + // Check for neighboring AddP nodes in a tree. + // If they have a base, use that it. + for (DUIterator_Fast kmax, k = this->fast_outs(kmax); k < kmax; k++) { + Node* u = this->fast_out(k); + if (u->is_AddP()) { + Node* base2 = u->in(AddPNode::Base); + if (base2 != NULL && !base2->is_top()) { + if (base == NULL) + base = base2; + else if (base != base2) + { doit = false; break; } + } + } + } + } + if (doit) { + if (base == NULL) { + base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL); + for (uint i = 1; i < req(); i++) { + base->init_req(i, in(i)->in(AddPNode::Base)); + } + phase->is_IterGVN()->register_new_node_with_optimizer(base); } - phase->is_IterGVN()->register_new_node_with_optimizer(base); return new (phase->C, 4) AddPNode(base, base, y); } } @@end@@
12-07-2007