changeset 376:39e191f3e52e

7901907: Avoid putting entire jcstress.jar into bootclasspath, push WhiteBox only there Contributed-by: Jerzy Krolak <j.krolak@gmail.com>
author shade
date Thu, 02 Mar 2017 14:31:08 +0100
parents 3dfd10339436
children 623f0f01fa13
files jcstress-core/pom.xml jcstress-core/src/main/java/org/openjdk/jcstress/util/ArrayUtils.java jcstress-core/src/main/java/org/openjdk/jcstress/util/FileUtils.java jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java jcstress-core/src/test/java/org/openjdk/jcstress/util/ArrayUtilsTest.java jcstress-core/src/test/java/org/openjdk/jcstress/util/FileUtilsTest.java
diffstat 7 files changed, 158 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/jcstress-core/pom.xml	Thu Mar 02 10:46:14 2017 +0100
+++ b/jcstress-core/pom.xml	Thu Mar 02 14:31:08 2017 +0100
@@ -71,6 +71,33 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>whitebox</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <includes>
+                                <include>sun/hotspot/WhiteBox.class</include>
+                            </includes>
+                            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
+                            <finalName>whitebox-api</finalName>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <excludes>
+                                <exclude>sun/hotspot/WhiteBox.class</exclude>
+                            </excludes>
+                        </configuration>
+                    </execution>
+                </executions>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/util/ArrayUtils.java	Thu Mar 02 10:46:14 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/ArrayUtils.java	Thu Mar 02 14:31:08 2017 +0100
@@ -24,6 +24,7 @@
  */
 package org.openjdk.jcstress.util;
 
+import java.util.Arrays;
 import java.util.Random;
 
 public class ArrayUtils {
@@ -49,4 +50,10 @@
         return res;
     }
 
+    public static String[] concat(String[] arr, String value) {
+        String[] newS = Arrays.copyOf(arr, arr.length + 1);
+        newS[arr.length] = value;
+        return newS;
+    }
+
 }
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/util/FileUtils.java	Thu Mar 02 10:46:14 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/FileUtils.java	Thu Mar 02 14:31:08 2017 +0100
@@ -24,12 +24,13 @@
  */
 package org.openjdk.jcstress.util;
 
-import java.io.Closeable;
-import java.io.Flushable;
-import java.io.IOException;
+import java.io.*;
+import java.util.Objects;
 
 public class FileUtils {
 
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
+
     public static <T extends Flushable & Closeable> void safelyClose(T obj) {
         if (obj != null) {
             try {
@@ -55,5 +56,36 @@
         }
     }
 
+    public static String copyFileToTemp(String cpLocation, String prefix, String suffix) throws IOException {
+        InputStream is = null;
+        OutputStream os = null;
+        try {
+            is = FileUtils.class.getResourceAsStream(cpLocation);
+            if (is == null) {
+                throw new IOException("Resource not found: " + cpLocation);
+            }
+            File file = File.createTempFile(prefix, suffix);
+            os = new FileOutputStream(file);
+            transferTo(is, os);
+            return file.getAbsolutePath();
+        } finally {
+            safelyClose(is);
+            safelyClose(os);
+        }
+    }
+
+    private static long transferTo(InputStream inputStream, OutputStream outputStream) throws IOException {
+        Objects.requireNonNull(inputStream, "inputStream");
+        Objects.requireNonNull(outputStream, "outputStream");
+        long transferred = 0;
+        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+        int read;
+        while ((read = inputStream.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
+            outputStream.write(buffer, 0, read);
+            transferred += read;
+        }
+        return transferred;
+    }
+
 
 }
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java	Thu Mar 02 10:46:14 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java	Thu Mar 02 14:31:08 2017 +0100
@@ -25,6 +25,7 @@
 package org.openjdk.jcstress.util;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
@@ -83,4 +84,7 @@
         return Character.toUpperCase(s.charAt(0)) + s.substring(1);
     }
 
+    private static boolean hasText(String s) {
+        return (s != null) && !s.isEmpty();
+    }
 }
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java	Thu Mar 02 10:46:14 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/vm/VMSupport.java	Thu Mar 02 14:31:08 2017 +0100
@@ -24,8 +24,10 @@
  */
 package org.openjdk.jcstress.vm;
 
-import org.openjdk.jcstress.Main;
+import org.openjdk.jcstress.util.ArrayUtils;
+import org.openjdk.jcstress.util.FileUtils;
 import org.openjdk.jcstress.util.InputStreamDrainer;
+import org.openjdk.jcstress.util.StringUtils;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -34,6 +36,7 @@
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 public class VMSupport {
@@ -51,59 +54,63 @@
         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);
+                SimpleTestMain.class,
+                "-XX:+UnlockDiagnosticVMOptions"
+        );
 
         detect("Trimming down the number of compiler threads",
-                "-XX:CICompilerCount=4",
-                SimpleTestMain.class);
+                SimpleTestMain.class,
+                "-XX:CICompilerCount=4"
+        );
 
         detect("Trimming down the number of parallel GC threads",
-                "-XX:ParallelGCThreads=4",
-                SimpleTestMain.class);
+                SimpleTestMain.class,
+                "-XX:ParallelGCThreads=4"
+        );
 
         detect("Trimming down the number of concurrent GC threads",
-                "-XX:ConcGCThreads=4",
-                SimpleTestMain.class);
+                SimpleTestMain.class,
+                "-XX:ConcGCThreads=4"
+        );
 
         detect("Trimming down the number of G1 concurrent refinement GC threads",
-                "-XX:G1ConcRefinementThreads=4",
-                SimpleTestMain.class);
+                SimpleTestMain.class,
+                "-XX:G1ConcRefinementThreads=4"
+        );
 
         detect("Testing @Contended works on all results and infra objects",
-                "-XX:-RestrictContended",
-                ContendedTestMain.class);
+                ContendedTestMain.class,
+                "-XX:-RestrictContended"
+        );
 
-        detect("Unlocking Whitebox API for online de-optimization",
-                "-XX:+WhiteBoxAPI",
-                DeoptTestMain.class);
+        try {
+            String whiteBoxJarName = FileUtils.copyFileToTemp("/whitebox-api.jar", "whitebox", ".jar");
+            detect("Unlocking Whitebox API for online de-optimization",
+                    DeoptTestMain.class,
+                    "-XX:+WhiteBoxAPI", "-Xbootclasspath/a:" + whiteBoxJarName
+            );
+        } catch (IOException e) {
+            throw new IllegalStateException("Fatal error: WhiteBoxAPI JAR problems.", e);
+        }
 
         detect("Testing allocation profiling",
-                "",
-                AllocProfileMain.class);
+                AllocProfileMain.class
+        );
 
         THREAD_SPIN_WAIT_AVAILABLE =
                 detect("Trying Thread.onSpinWait",
-                "",
-                ThreadSpinWaitTestMain.class);
+                        ThreadSpinWaitTestMain.class
+                );
 
         System.out.println();
     }
 
-    private static boolean detect(String label, String opt, Class<?> mainClass) {
+    private static boolean detect(String label, Class<?> mainClass, String... opts) {
         try {
-            tryWith(opt, mainClass.getName());
-            if (!opt.isEmpty()) {
-                ADD_JVM_FLAGS.add(opt);
-            }
+            String[] arguments = ArrayUtils.concat(opts, mainClass.getName());
+            tryWith(arguments);
+            ADD_JVM_FLAGS.addAll(Arrays.asList(opts));
             System.out.printf("----- %s %s%n", "[OK]", label);
             return true;
         } catch (VMSupportException ex) {
@@ -271,7 +278,7 @@
 
         @Override
         public void run() {
-            while (!Thread.interrupted()); // burn;
+            while (!Thread.interrupted()) ; // burn;
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-core/src/test/java/org/openjdk/jcstress/util/ArrayUtilsTest.java	Thu Mar 02 14:31:08 2017 +0100
@@ -0,0 +1,19 @@
+package org.openjdk.jcstress.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ArrayUtilsTest {
+
+    @Test
+    public void testConcat() throws Exception {
+        Assert.assertArrayEquals("add one element to array of two",
+                new String[]{"1", "2", "3"},
+                ArrayUtils.concat(new String[]{"1", "2"}, "3"));
+
+        Assert.assertArrayEquals("add one element to empty array",
+                new String[]{"1"},
+                ArrayUtils.concat(new String[0], "1"));
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-core/src/test/java/org/openjdk/jcstress/util/FileUtilsTest.java	Thu Mar 02 14:31:08 2017 +0100
@@ -0,0 +1,26 @@
+package org.openjdk.jcstress.util;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class FileUtilsTest {
+
+    @Test
+    public void testCopyFile() throws IOException {
+        String tempFile = FileUtils.copyFileToTemp("/org/openjdk/jcstress/util/FileUtils.class", "fileutils", ".class");
+
+        assertNotNull("File name returned", tempFile);
+        assertTrue("File exists on disk", new File(tempFile).exists());
+    }
+
+    @Test(expected = IOException.class)
+    public void testCopyFileThrowsNullPointerOnError() throws IOException {
+        FileUtils.copyFileToTemp("/org/openjdk/jcstress/util/FileUtils.cl", "fileutils", ".class");
+    }
+
+}
\ No newline at end of file