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
--- a/hotspot/src/share/vm/opto/addnode.cpp Wed Aug 27 09:15:46 2008 -0700
+++ b/hotspot/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/hotspot/src/share/vm/opto/escape.cpp Wed Aug 27 09:15:46 2008 -0700
+++ b/hotspot/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/hotspot/src/share/vm/opto/macro.cpp Wed Aug 27 09:15:46 2008 -0700
+++ b/hotspot/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/hotspot/src/share/vm/opto/type.cpp Wed Aug 27 09:15:46 2008 -0700
+++ b/hotspot/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/hotspot/src/share/vm/opto/type.hpp Wed Aug 27 09:15:46 2008 -0700
+++ b/hotspot/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/hotspot/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();
+ }
+}