mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +02:00
6741738: TypePtr::add_offset() set incorrect offset when the add overflows
Set offset to OffsetBot when the add overflows in TypePtr::add_offset() Reviewed-by: jrose, never
This commit is contained in:
parent
37306315b2
commit
3c4879eb9a
6 changed files with 84 additions and 40 deletions
|
@ -573,8 +573,6 @@ const Type *AddPNode::bottom_type() const {
|
|||
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 @@ const Type *AddPNode::Value( PhaseTransform *phase ) const {
|
|||
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 @@ const Type *AddPNode::mach_bottom_type( const MachNode* n) {
|
|||
// 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();
|
||||
|
|
|
@ -501,7 +501,7 @@ bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
|
|||
// 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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
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 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
|
|||
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;
|
||||
|
|
|
@ -1956,14 +1956,25 @@ const Type *TypePtr::xdual() const {
|
|||
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 @@ const Type *TypeRawPtr::xdual() const {
|
|||
}
|
||||
|
||||
//------------------------------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 @@ bool TypeOopPtr::singleton(void) const {
|
|||
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 @@ void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
|||
#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 @@ bool TypeAryPtr::empty(void) const {
|
|||
}
|
||||
|
||||
//------------------------------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 @@ ciKlass* TypeAryPtr::klass() const {
|
|||
|
||||
//------------------------------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) );
|
||||
}
|
||||
|
||||
|
|
|
@ -581,7 +581,8 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
};
|
||||
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 @@ public:
|
|||
// 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 @@ class TypeInstPtr : public TypeOopPtr {
|
|||
|
||||
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 @@ public:
|
|||
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 @@ public:
|
|||
// 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.
|
||||
|
||||
|
|
50
hotspot/test/compiler/6741738/Tester.java
Normal file
50
hotspot/test/compiler/6741738/Tester.java
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue