6885584: A particular class structure causes large allocation spike for jit
Reviewed-by: kvn
--- a/hotspot/src/share/vm/opto/phaseX.cpp Wed Oct 07 12:43:50 2009 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Wed Oct 07 15:38:37 2009 -0700
@@ -1502,7 +1502,7 @@
//---------------------------------saturate------------------------------------
const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type,
const Type* limit_type) const {
- const Type* wide_type = new_type->widen(old_type);
+ const Type* wide_type = new_type->widen(old_type, limit_type);
if (wide_type != new_type) { // did we widen?
// If so, we may have widened beyond the limit type. Clip it back down.
new_type = wide_type->filter(limit_type);
--- a/hotspot/src/share/vm/opto/type.cpp Wed Oct 07 12:43:50 2009 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Oct 07 15:38:37 2009 -0700
@@ -1115,7 +1115,7 @@
//------------------------------widen------------------------------------------
// Only happens for optimistic top-down optimizations.
-const Type *TypeInt::widen( const Type *old ) const {
+const Type *TypeInt::widen( const Type *old, const Type* limit ) const {
// Coming from TOP or such; no widening
if( old->base() != Int ) return this;
const TypeInt *ot = old->is_int();
@@ -1134,15 +1134,21 @@
// Now widen new guy.
// Check for widening too far
if (_widen == WidenMax) {
- if (min_jint < _lo && _hi < max_jint) {
+ int max = max_jint;
+ int min = min_jint;
+ if (limit->isa_int()) {
+ max = limit->is_int()->_hi;
+ min = limit->is_int()->_lo;
+ }
+ if (min < _lo && _hi < max) {
// If neither endpoint is extremal yet, push out the endpoint
// which is closer to its respective limit.
if (_lo >= 0 || // easy common case
- (juint)(_lo - min_jint) >= (juint)(max_jint - _hi)) {
+ (juint)(_lo - min) >= (juint)(max - _hi)) {
// Try to widen to an unsigned range type of 31 bits:
- return make(_lo, max_jint, WidenMax);
+ return make(_lo, max, WidenMax);
} else {
- return make(min_jint, _hi, WidenMax);
+ return make(min, _hi, WidenMax);
}
}
return TypeInt::INT;
@@ -1357,7 +1363,7 @@
//------------------------------widen------------------------------------------
// Only happens for optimistic top-down optimizations.
-const Type *TypeLong::widen( const Type *old ) const {
+const Type *TypeLong::widen( const Type *old, const Type* limit ) const {
// Coming from TOP or such; no widening
if( old->base() != Long ) return this;
const TypeLong *ot = old->is_long();
@@ -1376,18 +1382,24 @@
// Now widen new guy.
// Check for widening too far
if (_widen == WidenMax) {
- if (min_jlong < _lo && _hi < max_jlong) {
+ jlong max = max_jlong;
+ jlong min = min_jlong;
+ if (limit->isa_long()) {
+ max = limit->is_long()->_hi;
+ min = limit->is_long()->_lo;
+ }
+ if (min < _lo && _hi < max) {
// If neither endpoint is extremal yet, push out the endpoint
// which is closer to its respective limit.
if (_lo >= 0 || // easy common case
- (julong)(_lo - min_jlong) >= (julong)(max_jlong - _hi)) {
+ (julong)(_lo - min) >= (julong)(max - _hi)) {
// Try to widen to an unsigned range type of 32/63 bits:
- if (_hi < max_juint)
+ if (max >= max_juint && _hi < max_juint)
return make(_lo, max_juint, WidenMax);
else
- return make(_lo, max_jlong, WidenMax);
+ return make(_lo, max, WidenMax);
} else {
- return make(min_jlong, _hi, WidenMax);
+ return make(min, _hi, WidenMax);
}
}
return TypeLong::LONG;
--- a/hotspot/src/share/vm/opto/type.hpp Wed Oct 07 12:43:50 2009 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp Wed Oct 07 15:38:37 2009 -0700
@@ -168,7 +168,7 @@
// MEET operation; lower in lattice.
const Type *meet( const Type *t ) const;
// WIDEN: 'widens' for Ints and other range types
- virtual const Type *widen( const Type *old ) const { return this; }
+ virtual const Type *widen( const Type *old, const Type* limit ) const { return this; }
// NARROW: complement for widen, used by pessimistic phases
virtual const Type *narrow( const Type *old ) const { return this; }
@@ -409,7 +409,7 @@
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
- virtual const Type *widen( const Type *t ) const;
+ virtual const Type *widen( const Type *t, const Type* limit_type ) const;
virtual const Type *narrow( const Type *t ) const;
// Do not kill _widen bits.
virtual const Type *filter( const Type *kills ) const;
@@ -465,7 +465,7 @@
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
- virtual const Type *widen( const Type *t ) const;
+ virtual const Type *widen( const Type *t, const Type* limit_type ) const;
virtual const Type *narrow( const Type *t ) const;
// Do not kill _widen bits.
virtual const Type *filter( const Type *kills ) const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6885584/Test6885584.java Wed Oct 07 15:38:37 2009 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2009 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 6885584
+ * @summary A particular class structure causes large allocation spike for jit
+ *
+ * @run main/othervm -Xbatch Test6885584
+ */
+
+
+
+public class Test6885584 {
+ static private int i1;
+ static private int i2;
+ static private int i3;
+
+ static int limit = Integer.MAX_VALUE - 8;
+
+ public static void main(String args[]) {
+ // Run long enough to trigger an OSR
+ for(int j = 200000; j != 0; j--) {
+ }
+
+ // This must reference a field
+ i1 = i2;
+
+ // The resource leak is roughly proportional to this initial value
+ for(int k = Integer.MAX_VALUE - 1; k != 0; k--) {
+ // Make sure the body does some work
+ if(i2 > i3)i1 = k;
+ if (k <= limit) break;
+ }
+ }
+
+}