src/share/vm/opto/opaquenode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/opaquenode.cpp

Print this page
rev 7345 : 8054478: C2: Incorrectly compiled char[] array access crashes JVM
Summary: propagate node replacements along control flow edges to callers
Reviewed-by: dead backbranch in main loop results in erroneous array access
rev 7347 : more reviews


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"

  26 #include "opto/opaquenode.hpp"
  27 #include "opto/phaseX.hpp"
  28 
  29 //=============================================================================
  30 // Do not allow value-numbering
  31 uint Opaque1Node::hash() const { return NO_HASH; }
  32 uint Opaque1Node::cmp( const Node &n ) const {
  33   return (&n == this);          // Always fail except on self
  34 }
  35 
  36 //------------------------------Identity---------------------------------------
  37 // If _major_progress, then more loop optimizations follow.  Do NOT remove
  38 // the opaque Node until no more loop ops can happen.  Note the timing of
  39 // _major_progress; it's set in the major loop optimizations THEN comes the
  40 // call to IterGVN and any chance of hitting this code.  Hence there's no
  41 // phase-ordering problem with stripping Opaque1 in IGVN followed by some
  42 // more loop optimizations that require it.
  43 Node *Opaque1Node::Identity( PhaseTransform *phase ) {
  44   return phase->C->major_progress() ? this : in(1);






































  45 }
  46 
  47 //=============================================================================
  48 // A node to prevent unwanted optimizations.  Allows constant folding.  Stops
  49 // value-numbering, most Ideal calls or Identity functions.  This Node is
  50 // specifically designed to prevent the pre-increment value of a loop trip
  51 // counter from being live out of the bottom of the loop (hence causing the
  52 // pre- and post-increment values both being live and thus requiring an extra
  53 // temp register and an extra move).  If we "accidentally" optimize through
  54 // this kind of a Node, we'll get slightly pessimal, but correct, code.  Thus
  55 // it's OK to be slightly sloppy on optimizations here.
  56 
  57 // Do not allow value-numbering
  58 uint Opaque2Node::hash() const { return NO_HASH; }
  59 uint Opaque2Node::cmp( const Node &n ) const {
  60   return (&n == this);          // Always fail except on self
  61 }
  62 
  63 


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "opto/loopnode.hpp"
  27 #include "opto/opaquenode.hpp"
  28 #include "opto/phaseX.hpp"
  29 
  30 //=============================================================================
  31 // Do not allow value-numbering
  32 uint Opaque1Node::hash() const { return NO_HASH; }
  33 uint Opaque1Node::cmp(const Node &n) const {
  34   return (&n == this);          // Always fail except on self
  35 }
  36 
  37 //------------------------------Identity---------------------------------------
  38 // If _major_progress, then more loop optimizations follow.  Do NOT remove
  39 // the opaque Node until no more loop ops can happen.  Note the timing of
  40 // _major_progress; it's set in the major loop optimizations THEN comes the
  41 // call to IterGVN and any chance of hitting this code.  Hence there's no
  42 // phase-ordering problem with stripping Opaque1 in IGVN followed by some
  43 // more loop optimizations that require it.
  44 Node *Opaque1Node::Identity(PhaseTransform *phase) {
  45   return phase->C->major_progress() ? this : in(1);
  46 }
  47 
  48 Node *Opaque1Node::Ideal(PhaseGVN *phase, bool can_reshape) {
  49   if (!phase->C->major_progress() && outcnt() > 0) {
  50     assert(can_reshape, "loop opts over but not IGVN?");
  51     if (raw_out(0)->Opcode() == Op_CmpI) {
  52       Node* cmp = raw_out(0);
  53       // If this opaque node feeds into the limit condition of a
  54       // CountedLoop, we need to process the Phi node for the
  55       // induction variable: the range of values taken by the Phi is
  56       // known now and so its type is also known.
  57       if (cmp->raw_out(0)->is_Bool()) {
  58         Node* b = cmp->raw_out(0);
  59         if (b->raw_out(0)->is_CountedLoopEnd()) {
  60           CountedLoopEndNode* cle = b->raw_out(0)->as_CountedLoopEnd();
  61           if (cle->limit() == this) {
  62             phase->is_IterGVN()->_worklist.push(cle->phi());
  63           }
  64         }
  65       }
  66       Node* in1 = cmp->in(1);
  67       for (uint i = 0; i < in1->outcnt(); i++) {
  68         if (in1->raw_out(i)->Opcode() == Op_CastII) {
  69           Node* castii = in1->raw_out(i);
  70           if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) {
  71             Node* ifnode = castii->in(0)->in(0);
  72             if (ifnode->in(1) != NULL && ifnode->in(1)->in(1) == cmp) {
  73               // Reprocess a CastII node that may depend on this
  74               // opaque node value in case it's inexact and we can do
  75               // a better job of setting its type.
  76               phase->is_IterGVN()->_worklist.push(castii);
  77             }
  78           }
  79         }
  80       }
  81     }
  82   }
  83   return NULL;
  84 }
  85 
  86 //=============================================================================
  87 // A node to prevent unwanted optimizations.  Allows constant folding.  Stops
  88 // value-numbering, most Ideal calls or Identity functions.  This Node is
  89 // specifically designed to prevent the pre-increment value of a loop trip
  90 // counter from being live out of the bottom of the loop (hence causing the
  91 // pre- and post-increment values both being live and thus requiring an extra
  92 // temp register and an extra move).  If we "accidentally" optimize through
  93 // this kind of a Node, we'll get slightly pessimal, but correct, code.  Thus
  94 // it's OK to be slightly sloppy on optimizations here.
  95 
  96 // Do not allow value-numbering
  97 uint Opaque2Node::hash() const { return NO_HASH; }
  98 uint Opaque2Node::cmp( const Node &n ) const {
  99   return (&n == this);          // Always fail except on self
 100 }
 101 
 102 
src/share/vm/opto/opaquenode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File