changeset 242:5ce9bc3415f5

Runners: fix up WhiteBox API support.
author shade
date Thu, 12 May 2016 18:29:36 +0300
parents 5349847b972e
children 13d571fe4348
files jcstress-core/src/main/java/org/openjdk/jcstress/infra/processors/JCStressTestProcessor.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/vm/PrivilegedTestMain.java jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java jcstress-core/src/main/java/org/openjdk/jcstress/vm/WhiteBoxSupport.java jcstress-core/src/main/java/sun/hotspot/WhiteBox.java jcstress-core/src/main/java/sun/hotspot/parser/DiagnosticCommand.java
diffstat 7 files changed, 137 insertions(+), 220 deletions(-) [+]
line wrap: on
line diff
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/processors/JCStressTestProcessor.java	Thu May 12 15:20:16 2016 +0300
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/processors/JCStressTestProcessor.java	Thu May 12 18:29:36 2016 +0300
@@ -557,7 +557,7 @@
         pw.println("        testLog.print(\"Iterations \");");
         pw.println("        for (int c = 0; c < control.iters; c++) {");
         pw.println("            try {");
-        pw.println("                WhiteBoxSupport.tryDeoptimizeAllInfra(control.deoptRatio);");
+        pw.println("                WhiteBoxSupport.tryDeopt(control.deoptRatio);");
         pw.println("            } catch (NoClassDefFoundError err) {");
         pw.println("                // gracefully \"handle\"");
         pw.println("            }");
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java	Thu May 12 15:20:16 2016 +0300
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java	Thu May 12 18:29:36 2016 +0300
@@ -90,7 +90,7 @@
         testLog.print("Iterations ");
         for (int c = 0; c < control.iters; c++) {
             try {
-                WhiteBoxSupport.tryDeoptimizeAllInfra(control.deoptRatio);
+                WhiteBoxSupport.tryDeopt(control.deoptRatio);
             } catch (NoClassDefFoundError err) {
                 // gracefully "handle"
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/vm/PrivilegedTestMain.java	Thu May 12 18:29:36 2016 +0300
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.vm;
+
+public class PrivilegedTestMain {
+
+    public static void main(String... args) {
+        ClassLoader cl = PrivilegedTestMain.class.getClassLoader();
+        if (cl != null) {
+            throw new IllegalStateException("We are not loaded with a privileged classloader: " + cl);
+        }
+    }
+
+}
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java	Thu May 12 15:20:16 2016 +0300
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java	Thu May 12 18:29:36 2016 +0300
@@ -24,6 +24,7 @@
  */
 package org.openjdk.jcstress.vm;
 
+import org.openjdk.jcstress.Main;
 import org.openjdk.jcstress.util.InputStreamDrainer;
 
 import java.io.ByteArrayOutputStream;
@@ -41,15 +42,22 @@
         System.out.println(" (all failures are non-fatal, but may affect testing accuracy)");
         System.out.println();
 
+        String jarName = new File(Main.class.getProtectionDomain()
+                .getCodeSource().getLocation().getPath()).getPath();
+
+        detect("Adding ourselves to bootclasspath: " + jarName,
+                "-Xbootclasspath/a:" + jarName,
+                PrivilegedTestMain.class);
+
         detect("Unlocking diagnostic VM options",
                 "-XX:+UnlockDiagnosticVMOptions",
                 SimpleTestMain.class);
 
-        detect("@Contended support for avoiding false sharing",
+        detect("Testing @Contended support for avoiding false sharing",
                 "-XX:-RestrictContended",
                 ContendedTestMain.class);
 
-        detect("Whitebox API for online de-optimization",
+        detect("Unlocking Whitebox API for online de-optimization",
                 "-XX:+WhiteBoxAPI",
                 DeoptTestMain.class);
 
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/vm/WhiteBoxSupport.java	Thu May 12 15:20:16 2016 +0300
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/vm/WhiteBoxSupport.java	Thu May 12 18:29:36 2016 +0300
@@ -38,25 +38,59 @@
 
     private static WhiteBox whiteBox;
     private static volatile boolean tried;
+    private static volatile Mode mode;
     private static volatile Collection<Method> infraMethods;
 
+    enum Mode {
+        DEOPT_ALL,
+        DEOPT_METHOD,
+    }
+
     public static void init() throws Throwable {
         if (tried) return;
         try {
-            WhiteBox w = WhiteBox.getWhiteBox();
-            w.deoptimizeAll();
-            whiteBox = w;
+            initAndTest();
         } finally {
             tried = true;
         }
     }
 
+    private static void initAndTest() {
+        WhiteBox.registerNatives();
+        WhiteBox w = new WhiteBox();
+
+        Throwable deoptMethod = null;
+        try {
+            w.deoptimizeMethod(WhiteBoxSupport.class.getMethod("initSafely"));
+            w.isClassAlive(WhiteBoxSupport.class.getName());
+        } catch (Throwable ex) {
+            deoptMethod = ex;
+        }
+
+        Throwable deoptAll = null;
+        try {
+            w.deoptimizeAll();
+        } catch (Throwable ex) {
+            deoptAll = ex;
+        }
+
+        if (deoptMethod == null) {
+            mode = Mode.DEOPT_METHOD;
+        } else if (deoptAll == null) {
+            mode = Mode.DEOPT_ALL;
+        } else {
+            IllegalStateException whiteBoxFailed = new IllegalStateException();
+            whiteBoxFailed.addSuppressed(deoptAll);
+            whiteBoxFailed.addSuppressed(deoptMethod);
+            throw whiteBoxFailed;
+        }
+        whiteBox = w;
+    }
+
     public static void initSafely() {
         if (tried) return;
         try {
-            WhiteBox w = WhiteBox.getWhiteBox();
-            w.deoptimizeAll();
-            whiteBox = w;
+            initAndTest();
         } catch (Throwable e) {
             // expected
         } finally {
@@ -64,37 +98,49 @@
         }
     }
 
-    public static void tryDeoptimizeAllInfra(int actionProbRatio) {
+    public static void tryDeopt(int actionProbRatio) {
         WhiteBox w = whiteBox;
         if (w != null) {
             if (ThreadLocalRandom.current().nextInt(actionProbRatio) != 0)
                 return;
 
-            try {
-                Collection<Method> im = infraMethods;
-                if (im == null) {
-                    im = new ArrayList<>();
-                    Collection<String> infraNames = new ArrayList<>();
-                    infraNames.addAll(Reflections.getClassNames("org.openjdk.jcstress.infra"));
-                    infraNames.addAll(Reflections.getClassNames("org.openjdk.jcstress.util"));
-                    for (String name : infraNames) {
-                        try {
-                            Class<?> aClass = Class.forName(name);
-                            Collections.addAll(im, aClass.getDeclaredMethods());
-                        } catch (ClassNotFoundException e) {
-                            throw new IllegalStateException();
+            switch (mode) {
+                case DEOPT_ALL:
+                    w.deoptimizeAll();
+                    break;
+                case DEOPT_METHOD:
+                    try {
+                        for (Method m : getJCStressMethods()) {
+                            w.deoptimizeMethod(m);
                         }
+                    } catch (IOException e) {
+                        throw new IllegalStateException();
                     }
-                    infraMethods = im;
-                }
-
-                for (Method m : im) {
-                    w.deoptimizeMethod(m);
-                }
-            } catch (IOException e) {
-                throw new IllegalStateException();
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown deopt mode: " + mode);
             }
         }
     }
 
+    private static Collection<Method> getJCStressMethods() throws IOException {
+        Collection<Method> im = infraMethods;
+        if (im == null) {
+            im = new ArrayList<>();
+            Collection<String> names = new ArrayList<>();
+            names.addAll(Reflections.getClassNames("org.openjdk.jcstress"));
+            for (String name : names) {
+                // Avoid loading classes
+                if (!whiteBox.isClassAlive(name)) continue;
+                try {
+                    Class<?> aClass = Class.forName(name);
+                    Collections.addAll(im, aClass.getDeclaredMethods());
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException();
+                }
+            }
+            infraMethods = im;
+        } return im;
+    }
+
 }
--- a/jcstress-core/src/main/java/sun/hotspot/WhiteBox.java	Thu May 12 15:20:16 2016 +0300
+++ b/jcstress-core/src/main/java/sun/hotspot/WhiteBox.java	Thu May 12 18:29:36 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. 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
@@ -25,133 +25,27 @@
 package sun.hotspot;
 
 import java.lang.reflect.Executable;
-import java.security.BasicPermission;
-import sun.hotspot.parser.DiagnosticCommand;
+import java.util.Objects;
 
 public class WhiteBox {
 
-  @SuppressWarnings("serial")
-  public static class WhiteBoxPermission extends BasicPermission {
-    public WhiteBoxPermission(String s) {
-      super(s);
-    }
+  public WhiteBox() {}
+  public static native void registerNatives();
+
+  public native void    deoptimizeAll();
+
+  public        int     deoptimizeMethod(Executable method) {
+    return deoptimizeMethod(method, false /*not osr*/);
+  }
+  private native int     deoptimizeMethod0(Executable method, boolean isOsr);
+  public         int     deoptimizeMethod(Executable method, boolean isOsr) {
+    Objects.requireNonNull(method);
+    return deoptimizeMethod0(method, isOsr);
   }
 
-  private WhiteBox() {}
-  private static final WhiteBox instance = new WhiteBox();
-  private static native void registerNatives();
-
-  /**
-   * Returns the singleton WhiteBox instance.
-   *
-   * The returned WhiteBox object should be carefully guarded
-   * by the caller, since it can be used to read and write data
-   * at arbitrary memory addresses. It must never be passed to
-   * untrusted code.
-   */
-  public synchronized static WhiteBox getWhiteBox() {
-    SecurityManager sm = System.getSecurityManager();
-    if (sm != null) {
-      sm.checkPermission(new WhiteBoxPermission("getInstance"));
-    }
-    return instance;
-  }
-
-  static {
-    registerNatives();
-  }
-
-  // Get the maximum heap size supporting COOPs
-  public native long getCompressedOopsMaxHeapSize();
-  // Arguments
-  public native void printHeapSizes();
-
-  // Memory
-  public native long getObjectAddress(Object o);
-  public native int  getHeapOopSize();
-
-  // Runtime
-  // Make sure class name is in the correct format
   public boolean isClassAlive(String name) {
     return isClassAlive0(name.replace('.', '/'));
   }
   private native boolean isClassAlive0(String name);
 
-  // G1
-  public native boolean g1InConcurrentMark();
-  public native boolean g1IsHumongous(Object o);
-  public native long    g1NumFreeRegions();
-  public native int     g1RegionSize();
-  public native Object[]    parseCommandLine(String commandline, DiagnosticCommand[] args);
-
-  // NMT
-  public native long NMTMalloc(long size);
-  public native void NMTFree(long mem);
-  public native long NMTReserveMemory(long size);
-  public native void NMTCommitMemory(long addr, long size);
-  public native void NMTUncommitMemory(long addr, long size);
-  public native void NMTReleaseMemory(long addr, long size);
-  public native boolean NMTWaitForDataMerge();
-  public native boolean NMTIsDetailSupported();
-
-  // Compiler
-  public native void    deoptimizeAll();
-  public        boolean isMethodCompiled(Executable method) {
-    return isMethodCompiled(method, false /*not osr*/);
-  }
-  public native boolean isMethodCompiled(Executable method, boolean isOsr);
-  public        boolean isMethodCompilable(Executable method) {
-    return isMethodCompilable(method, -1 /*any*/);
-  }
-  public        boolean isMethodCompilable(Executable method, int compLevel) {
-    return isMethodCompilable(method, compLevel, false /*not osr*/);
-  }
-  public native boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr);
-  public native boolean isMethodQueuedForCompilation(Executable method);
-  public        int     deoptimizeMethod(Executable method) {
-    return deoptimizeMethod(method, false /*not osr*/);
-  }
-  public native int     deoptimizeMethod(Executable method, boolean isOsr);
-  public        void    makeMethodNotCompilable(Executable method) {
-    makeMethodNotCompilable(method, -1 /*any*/);
-  }
-  public        void    makeMethodNotCompilable(Executable method, int compLevel) {
-    makeMethodNotCompilable(method, compLevel, false /*not osr*/);
-  }
-  public native void    makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr);
-  public        int     getMethodCompilationLevel(Executable method) {
-    return getMethodCompilationLevel(method, false /*not ost*/);
-  }
-  public native int     getMethodCompilationLevel(Executable method, boolean isOsr);
-  public native boolean testSetDontInlineMethod(Executable method, boolean value);
-  public        int     getCompileQueuesSize() {
-    return getCompileQueueSize(-1 /*any*/);
-  }
-  public native int     getCompileQueueSize(int compLevel);
-  public native boolean testSetForceInlineMethod(Executable method, boolean value);
-  public boolean        enqueueMethodForCompilation(Executable method, int compLevel) {
-    return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/);
-  }
-  public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci);
-  public native void    clearMethodState(Executable method);
-  public native int     getMethodEntryBci(Executable method);
-  public native Object[] getNMethod(Executable method, boolean isOsr);
-
-  // Intered strings
-  public native boolean isInStringTable(String str);
-
-  // Memory
-  public native void readReservedMemory();
-
-  // force Full GC
-  public native void fullGC();
-
-  // Tests on ReservedSpace/VirtualSpace classes
-  public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations);
-  public native void runMemoryUnitTests();
-  public native void readFromNoaccessArea();
-
-  // CPU features
-  public native String getCPUFeatures();
-
-}
+}
\ No newline at end of file
--- a/jcstress-core/src/main/java/sun/hotspot/parser/DiagnosticCommand.java	Thu May 12 15:20:16 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.hotspot.parser;
-
-public class DiagnosticCommand {
-
-    public enum DiagnosticArgumentType {
-        JLONG, BOOLEAN, STRING, NANOTIME, STRINGARRAY, MEMORYSIZE
-    }
-
-    private String name;
-    private String desc;
-    private DiagnosticArgumentType type;
-    private boolean mandatory;
-    private String defaultValue;
-
-    public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
-            boolean mandatory, String defaultValue) {
-        this.name = name;
-        this.desc = desc;
-        this.type = type;
-        this.mandatory = mandatory;
-        this.defaultValue = defaultValue;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDesc() {
-        return desc;
-    }
-
-    public DiagnosticArgumentType getType() {
-        return type;
-    }
-
-    public boolean isMandatory() {
-        return mandatory;
-    }
-
-    public String getDefaultValue() {
-        return defaultValue;
-    }
-}