8027532: nashorn should only use jdk8 apis in the compact1 profile
authorjlaskey
Wed, 30 Oct 2013 11:28:46 -0300
changeset 21461 57b33ebf19db
parent 21460 5fb1bd6fb113
child 21462 44238d753963
8027532: nashorn should only use jdk8 apis in the compact1 profile Reviewed-by: sundar, lagergren, hannesw Contributed-by: james.laskey@oracle.com
nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java	Tue Oct 29 14:22:44 2013 -0300
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java	Wed Oct 30 11:28:46 2013 -0300
@@ -25,10 +25,10 @@
 
 package jdk.nashorn.internal.ir.debug;
 
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryPoolMXBean;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -51,9 +51,9 @@
  * switch, it can not detect
  * this fact and will report incorrect sizes, as it will presume the default JVM
  * behavior.
- *
- * @author Attila Szegedi
  */
+
+@SuppressWarnings("StaticNonFinalUsedInInitialization")
 public class ObjectSizeCalculator {
 
     /**
@@ -368,6 +368,29 @@
                 type.getName());
     }
 
+    // ALERT: java.lang.management is not available in compact 1.  We need
+    // to use reflection to soft link test memory statistics.
+
+    static Class<?>  managementFactory    = null;
+    static Class<?>  memoryPoolMXBean     = null;
+    static Class<?>  memoryUsage          = null;
+    static Method    getMemoryPoolMXBeans = null;
+    static Method    getUsage             = null;
+    static Method    getMax               = null;
+    static {
+        try {
+            managementFactory    = Class.forName("java.lang.management.ManagementFactory");
+            memoryPoolMXBean     = Class.forName("java.lang.management.MemoryPoolMXBean");
+            memoryUsage          = Class.forName("java.lang.management.MemoryUsage");
+
+            getMemoryPoolMXBeans = managementFactory.getMethod("getMemoryPoolMXBeans");
+            getUsage             = memoryPoolMXBean.getMethod("getUsage");
+            getMax               = memoryUsage.getMethod("getMax");
+        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) {
+            // Pass thru, asserts when attempting to use.
+        }
+    }
+
     /**
      * Return the current memory usage
      * @return current memory usage derived from system configuration
@@ -409,9 +432,33 @@
                 strVmVersion.indexOf('.')));
         if (vmVersion >= 17) {
             long maxMemory = 0;
-            for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
-                maxMemory += mp.getUsage().getMax();
+
+            /*
+               See ALERT above.  The reflection code below duplicates the following
+               sequence, and avoids hard coding of java.lang.management.
+
+               for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
+                   maxMemory += mp.getUsage().getMax();
+               }
+            */
+
+            if (getMemoryPoolMXBeans == null) {
+                throw new AssertionError("java.lang.management not available in compact 1");
             }
+
+            try {
+                final List<?> memoryPoolMXBeans = (List<?>)getMemoryPoolMXBeans.invoke(managementFactory);
+                for (final Object mp : memoryPoolMXBeans) {
+                    final Object usage = getUsage.invoke(mp);
+                    final Object max = getMax.invoke(usage);
+                    maxMemory += ((Long)max).longValue();
+                }
+            } catch (IllegalAccessException |
+                     IllegalArgumentException |
+                     InvocationTargetException ex) {
+                throw new AssertionError("java.lang.management not available in compact 1");
+            }
+
             if (maxMemory < 30L * 1024 * 1024 * 1024) {
                 // HotSpot 17.0 and above use compressed OOPs below 30GB of RAM total
                 // for all memory pools (yes, including code cache).