changeset 306:af945ba2e739

6741738: TypePtr::add_offset() set incorrect offset when the add overflows Summary: Set offset to OffsetBot when the add overflows in TypePtr::add_offset() Reviewed-by: jrose, never
author kvn
date Wed, 27 Aug 2008 14:47:32 -0700
parents ab075d07f1ba
children 892493c3d862
files src/share/vm/opto/addnode.cpp src/share/vm/opto/escape.cpp src/share/vm/opto/macro.cpp src/share/vm/opto/type.cpp src/share/vm/opto/type.hpp test/compiler/6741738/Tester.java
diffstat 6 files changed, 84 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/addnode.cpp	Wed Aug 27 09:15:46 2008 -0700
+++ b/src/share/vm/opto/addnode.cpp	Wed Aug 27 14:47:32 2008 -0700
@@ -573,8 +573,6 @@
   intptr_t txoffset = Type::OffsetBot;
   if (tx->is_con()) {   // Left input is an add of a constant?
     txoffset = tx->get_con();
-    if (txoffset != (int)txoffset)
-      txoffset = Type::OffsetBot;   // oops:  add_offset will choke on it
   }
   return tp->add_offset(txoffset);
 }
@@ -595,8 +593,6 @@
   intptr_t p2offset = Type::OffsetBot;
   if (p2->is_con()) {   // Left input is an add of a constant?
     p2offset = p2->get_con();
-    if (p2offset != (int)p2offset)
-      p2offset = Type::OffsetBot;   // oops:  add_offset will choke on it
   }
   return p1->add_offset(p2offset);
 }
@@ -675,7 +671,7 @@
     // Check for any interesting operand info.
     // In particular, check for both memory and non-memory operands.
     // %%%%% Clean this up: use xadd_offset
-    int con = opnd->constant();
+    intptr_t con = opnd->constant();
     if ( con == TypePtr::OffsetBot )  goto bottom_out;
     offset += con;
     con = opnd->constant_disp();
--- a/src/share/vm/opto/escape.cpp	Wed Aug 27 09:15:46 2008 -0700
+++ b/src/share/vm/opto/escape.cpp	Wed Aug 27 14:47:32 2008 -0700
@@ -501,7 +501,7 @@
     // compute an appropriate address type (cases #3 and #5).
     assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer");
     assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation");
-    int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot);
+    intptr_t offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot);
     assert(offs != Type::OffsetBot, "offset must be a constant");
     t = base_t->add_offset(offs)->is_oopptr();
   }
--- a/src/share/vm/opto/macro.cpp	Wed Aug 27 09:15:46 2008 -0700
+++ b/src/share/vm/opto/macro.cpp	Wed Aug 27 14:47:32 2008 -0700
@@ -594,7 +594,7 @@
 
     // Scan object's fields adding an input to the safepoint for each field.
     for (int j = 0; j < nfields; j++) {
-      int offset;
+      intptr_t offset;
       ciField* field = NULL;
       if (iklass != NULL) {
         field = iklass->nonstatic_field_at(j);
@@ -602,7 +602,7 @@
         elem_type = field->type();
         basic_elem_type = field->layout_type();
       } else {
-        offset = array_base + j * element_size;
+        offset = array_base + j * (intptr_t)element_size;
       }
 
       const Type *field_type;
--- a/src/share/vm/opto/type.cpp	Wed Aug 27 09:15:46 2008 -0700
+++ b/src/share/vm/opto/type.cpp	Wed Aug 27 14:47:32 2008 -0700
@@ -1956,14 +1956,25 @@
   return new TypePtr( AnyPtr, dual_ptr(), dual_offset() );
 }
 
+//------------------------------xadd_offset------------------------------------
+int TypePtr::xadd_offset( intptr_t offset ) const {
+  // Adding to 'TOP' offset?  Return 'TOP'!
+  if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop;
+  // Adding to 'BOTTOM' offset?  Return 'BOTTOM'!
+  if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot;
+  // Addition overflows or "accidentally" equals to OffsetTop? Return 'BOTTOM'!
+  offset += (intptr_t)_offset;
+  if (offset != (int)offset || offset == OffsetTop) return OffsetBot;
+
+  // assert( _offset >= 0 && _offset+offset >= 0, "" );
+  // It is possible to construct a negative offset during PhaseCCP
+
+  return (int)offset;        // Sum valid offsets
+}
+
 //------------------------------add_offset-------------------------------------
-const TypePtr *TypePtr::add_offset( int offset ) const {
-  if( offset == 0 ) return this; // No change
-  if( _offset == OffsetBot ) return this;
-  if(  offset == OffsetBot ) offset = OffsetBot;
-  else if( _offset == OffsetTop || offset == OffsetTop ) offset = OffsetTop;
-  else offset += _offset;
-  return make( AnyPtr, _ptr, offset );
+const TypePtr *TypePtr::add_offset( intptr_t offset ) const {
+  return make( AnyPtr, _ptr, xadd_offset(offset) );
 }
 
 //------------------------------eq---------------------------------------------
@@ -2096,7 +2107,7 @@
 }
 
 //------------------------------add_offset-------------------------------------
-const TypePtr *TypeRawPtr::add_offset( int offset ) const {
+const TypePtr *TypeRawPtr::add_offset( intptr_t offset ) const {
   if( offset == OffsetTop ) return BOTTOM; // Undefined offset-> undefined pointer
   if( offset == OffsetBot ) return BOTTOM; // Unknown offset-> unknown pointer
   if( offset == 0 ) return this; // No change
@@ -2545,21 +2556,8 @@
   return (_offset == 0) && !below_centerline(_ptr);
 }
 
-//------------------------------xadd_offset------------------------------------
-int TypeOopPtr::xadd_offset( int offset ) const {
-  // Adding to 'TOP' offset?  Return 'TOP'!
-  if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop;
-  // Adding to 'BOTTOM' offset?  Return 'BOTTOM'!
-  if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot;
-
-  // assert( _offset >= 0 && _offset+offset >= 0, "" );
-  // It is possible to construct a negative offset during PhaseCCP
-
-  return _offset+offset;        // Sum valid offsets
-}
-
 //------------------------------add_offset-------------------------------------
-const TypePtr *TypeOopPtr::add_offset( int offset ) const {
+const TypePtr *TypeOopPtr::add_offset( intptr_t offset ) const {
   return make( _ptr, xadd_offset(offset) );
 }
 
@@ -3076,7 +3074,7 @@
 #endif
 
 //------------------------------add_offset-------------------------------------
-const TypePtr *TypeInstPtr::add_offset( int offset ) const {
+const TypePtr *TypeInstPtr::add_offset( intptr_t offset ) const {
   return make( _ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id );
 }
 
@@ -3427,7 +3425,7 @@
 }
 
 //------------------------------add_offset-------------------------------------
-const TypePtr *TypeAryPtr::add_offset( int offset ) const {
+const TypePtr *TypeAryPtr::add_offset( intptr_t offset ) const {
   return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id );
 }
 
@@ -3654,7 +3652,7 @@
 
 //------------------------------add_offset-------------------------------------
 // Access internals of klass object
-const TypePtr *TypeKlassPtr::add_offset( int offset ) const {
+const TypePtr *TypeKlassPtr::add_offset( intptr_t offset ) const {
   return make( _ptr, klass(), xadd_offset(offset) );
 }
 
--- a/src/share/vm/opto/type.hpp	Wed Aug 27 09:15:46 2008 -0700
+++ b/src/share/vm/opto/type.hpp	Wed Aug 27 14:47:32 2008 -0700
@@ -581,7 +581,8 @@
 
   virtual intptr_t get_con() const;
 
-  virtual const TypePtr *add_offset( int offset ) const;
+  int xadd_offset( intptr_t offset ) const;
+  virtual const TypePtr *add_offset( intptr_t offset ) const;
 
   virtual bool singleton(void) const;    // TRUE if type is a singleton
   virtual bool empty(void) const;        // TRUE if type is vacuous
@@ -632,7 +633,7 @@
 
   virtual intptr_t get_con() const;
 
-  virtual const TypePtr *add_offset( int offset ) const;
+  virtual const TypePtr *add_offset( intptr_t offset ) const;
 
   virtual const Type *xmeet( const Type *t ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
@@ -659,7 +660,6 @@
   };
 protected:
 
-  int xadd_offset( int offset ) const;
   // Oop is NULL, unless this is a constant oop.
   ciObject*     _const_oop;   // Constant oop
   // If _klass is NULL, then so is _sig.  This is an unloaded klass.
@@ -724,7 +724,7 @@
   // corresponding pointer to klass, for a given instance
   const TypeKlassPtr* as_klass_type() const;
 
-  virtual const TypePtr *add_offset( int offset ) const;
+  virtual const TypePtr *add_offset( intptr_t offset ) const;
 
   virtual const Type *xmeet( const Type *t ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
@@ -793,7 +793,7 @@
 
   virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
 
-  virtual const TypePtr *add_offset( int offset ) const;
+  virtual const TypePtr *add_offset( intptr_t offset ) const;
 
   virtual const Type *xmeet( const Type *t ) const;
   virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
@@ -842,7 +842,7 @@
   virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
 
   virtual bool empty(void) const;        // TRUE if type is vacuous
-  virtual const TypePtr *add_offset( int offset ) const;
+  virtual const TypePtr *add_offset( intptr_t offset ) const;
 
   virtual const Type *xmeet( const Type *t ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
@@ -896,7 +896,7 @@
   // corresponding pointer to instance, for a given class
   const TypeOopPtr* as_instance_type() const;
 
-  virtual const TypePtr *add_offset( int offset ) const;
+  virtual const TypePtr *add_offset( intptr_t offset ) const;
   virtual const Type    *xmeet( const Type *t ) const;
   virtual const Type    *xdual() const;      // Compute dual right now.
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6741738/Tester.java	Wed Aug 27 14:47:32 2008 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6741738
+ * @summary TypePtr::add_offset() set incorrect offset when the add overflows
+ * @run main/othervm -Xcomp -XX:CompileOnly=Tester.foo Tester
+ */
+
+public class Tester {
+        private String[] values;
+        private int count;
+
+        String foo() {
+                int i = Integer.MAX_VALUE-1;
+                String s;
+                try {
+                    s = values[i];
+                } catch (Throwable e) {
+                    s = "";
+                }
+                return s;
+        }
+
+        public static void main(String[] args) {
+                Tester t = new Tester();
+                String s = t.foo();
+        }
+}