提交 93403ca7 编写于 作者: K kvn

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
上级 322625dd
...@@ -573,8 +573,6 @@ const Type *AddPNode::bottom_type() const { ...@@ -573,8 +573,6 @@ const Type *AddPNode::bottom_type() const {
intptr_t txoffset = Type::OffsetBot; intptr_t txoffset = Type::OffsetBot;
if (tx->is_con()) { // Left input is an add of a constant? if (tx->is_con()) { // Left input is an add of a constant?
txoffset = tx->get_con(); txoffset = tx->get_con();
if (txoffset != (int)txoffset)
txoffset = Type::OffsetBot; // oops: add_offset will choke on it
} }
return tp->add_offset(txoffset); return tp->add_offset(txoffset);
} }
...@@ -595,8 +593,6 @@ const Type *AddPNode::Value( PhaseTransform *phase ) const { ...@@ -595,8 +593,6 @@ const Type *AddPNode::Value( PhaseTransform *phase ) const {
intptr_t p2offset = Type::OffsetBot; intptr_t p2offset = Type::OffsetBot;
if (p2->is_con()) { // Left input is an add of a constant? if (p2->is_con()) { // Left input is an add of a constant?
p2offset = p2->get_con(); p2offset = p2->get_con();
if (p2offset != (int)p2offset)
p2offset = Type::OffsetBot; // oops: add_offset will choke on it
} }
return p1->add_offset(p2offset); return p1->add_offset(p2offset);
} }
...@@ -675,7 +671,7 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) { ...@@ -675,7 +671,7 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) {
// Check for any interesting operand info. // Check for any interesting operand info.
// In particular, check for both memory and non-memory operands. // In particular, check for both memory and non-memory operands.
// %%%%% Clean this up: use xadd_offset // %%%%% Clean this up: use xadd_offset
int con = opnd->constant(); intptr_t con = opnd->constant();
if ( con == TypePtr::OffsetBot ) goto bottom_out; if ( con == TypePtr::OffsetBot ) goto bottom_out;
offset += con; offset += con;
con = opnd->constant_disp(); con = opnd->constant_disp();
......
...@@ -501,7 +501,7 @@ bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { ...@@ -501,7 +501,7 @@ bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
// compute an appropriate address type (cases #3 and #5). // compute an appropriate address type (cases #3 and #5).
assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer"); 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"); 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"); assert(offs != Type::OffsetBot, "offset must be a constant");
t = base_t->add_offset(offs)->is_oopptr(); t = base_t->add_offset(offs)->is_oopptr();
} }
......
...@@ -594,7 +594,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa ...@@ -594,7 +594,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
// Scan object's fields adding an input to the safepoint for each field. // Scan object's fields adding an input to the safepoint for each field.
for (int j = 0; j < nfields; j++) { for (int j = 0; j < nfields; j++) {
int offset; intptr_t offset;
ciField* field = NULL; ciField* field = NULL;
if (iklass != NULL) { if (iklass != NULL) {
field = iklass->nonstatic_field_at(j); field = iklass->nonstatic_field_at(j);
...@@ -602,7 +602,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa ...@@ -602,7 +602,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
elem_type = field->type(); elem_type = field->type();
basic_elem_type = field->layout_type(); basic_elem_type = field->layout_type();
} else { } else {
offset = array_base + j * element_size; offset = array_base + j * (intptr_t)element_size;
} }
const Type *field_type; const Type *field_type;
......
...@@ -1956,14 +1956,25 @@ const Type *TypePtr::xdual() const { ...@@ -1956,14 +1956,25 @@ const Type *TypePtr::xdual() const {
return new TypePtr( AnyPtr, dual_ptr(), dual_offset() ); 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------------------------------------- //------------------------------add_offset-------------------------------------
const TypePtr *TypePtr::add_offset( int offset ) const { const TypePtr *TypePtr::add_offset( intptr_t offset ) const {
if( offset == 0 ) return this; // No change return make( AnyPtr, _ptr, xadd_offset(offset) );
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 );
} }
//------------------------------eq--------------------------------------------- //------------------------------eq---------------------------------------------
...@@ -2096,7 +2107,7 @@ const Type *TypeRawPtr::xdual() const { ...@@ -2096,7 +2107,7 @@ const Type *TypeRawPtr::xdual() const {
} }
//------------------------------add_offset------------------------------------- //------------------------------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 == OffsetTop ) return BOTTOM; // Undefined offset-> undefined pointer
if( offset == OffsetBot ) return BOTTOM; // Unknown offset-> unknown pointer if( offset == OffsetBot ) return BOTTOM; // Unknown offset-> unknown pointer
if( offset == 0 ) return this; // No change if( offset == 0 ) return this; // No change
...@@ -2545,21 +2556,8 @@ bool TypeOopPtr::singleton(void) const { ...@@ -2545,21 +2556,8 @@ bool TypeOopPtr::singleton(void) const {
return (_offset == 0) && !below_centerline(_ptr); 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------------------------------------- //------------------------------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) ); return make( _ptr, xadd_offset(offset) );
} }
...@@ -3076,7 +3074,7 @@ void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const { ...@@ -3076,7 +3074,7 @@ void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
#endif #endif
//------------------------------add_offset------------------------------------- //------------------------------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 ); return make( _ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id );
} }
...@@ -3427,7 +3425,7 @@ bool TypeAryPtr::empty(void) const { ...@@ -3427,7 +3425,7 @@ bool TypeAryPtr::empty(void) const {
} }
//------------------------------add_offset------------------------------------- //------------------------------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 ); return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id );
} }
...@@ -3654,7 +3652,7 @@ ciKlass* TypeAryPtr::klass() const { ...@@ -3654,7 +3652,7 @@ ciKlass* TypeAryPtr::klass() const {
//------------------------------add_offset------------------------------------- //------------------------------add_offset-------------------------------------
// Access internals of klass object // 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) ); return make( _ptr, klass(), xadd_offset(offset) );
} }
......
...@@ -581,7 +581,8 @@ public: ...@@ -581,7 +581,8 @@ public:
virtual intptr_t get_con() const; 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 singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous virtual bool empty(void) const; // TRUE if type is vacuous
...@@ -632,7 +633,7 @@ public: ...@@ -632,7 +633,7 @@ public:
virtual intptr_t get_con() const; 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 *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now. virtual const Type *xdual() const; // Compute dual right now.
...@@ -659,7 +660,6 @@ public: ...@@ -659,7 +660,6 @@ public:
}; };
protected: protected:
int xadd_offset( int offset ) const;
// Oop is NULL, unless this is a constant oop. // Oop is NULL, unless this is a constant oop.
ciObject* _const_oop; // Constant oop ciObject* _const_oop; // Constant oop
// If _klass is NULL, then so is _sig. This is an unloaded klass. // If _klass is NULL, then so is _sig. This is an unloaded klass.
...@@ -724,7 +724,7 @@ public: ...@@ -724,7 +724,7 @@ public:
// corresponding pointer to klass, for a given instance // corresponding pointer to klass, for a given instance
const TypeKlassPtr* as_klass_type() const; 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 *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now. virtual const Type *xdual() const; // Compute dual right now.
...@@ -793,7 +793,7 @@ class TypeInstPtr : public TypeOopPtr { ...@@ -793,7 +793,7 @@ class TypeInstPtr : public TypeOopPtr {
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const; 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 Type *xmeet( const Type *t ) const;
virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const; virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const;
...@@ -842,7 +842,7 @@ public: ...@@ -842,7 +842,7 @@ public:
virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const; virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
virtual bool empty(void) const; // TRUE if type is vacuous 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 *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now. virtual const Type *xdual() const; // Compute dual right now.
...@@ -896,7 +896,7 @@ public: ...@@ -896,7 +896,7 @@ public:
// corresponding pointer to instance, for a given class // corresponding pointer to instance, for a given class
const TypeOopPtr* as_instance_type() const; 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 *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now. virtual const Type *xdual() const; // Compute dual right now.
......
/*
* 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();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册