6885584: A particular class structure causes large allocation spike for jit
authornever
Wed, 07 Oct 2009 15:38:37 -0700
changeset 4012 579b7bad9983
parent 4011 3329fe39ad1a
child 4013 b154310845de
6885584: A particular class structure causes large allocation spike for jit Reviewed-by: kvn
hotspot/src/share/vm/opto/phaseX.cpp
hotspot/src/share/vm/opto/type.cpp
hotspot/src/share/vm/opto/type.hpp
hotspot/test/compiler/6885584/Test6885584.java
--- 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;
+       }
+   }
+
+}