提交 7a81f161 编写于 作者: A adlertz

Merge

......@@ -48,7 +48,7 @@ public class TestVerifyDuringStartup {
"-XX:+VerifyDuringStartup",
"-version"});
System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java"));
System.out.print("Testing:\n" + JDKToolFinder.getCurrentJDKTool("java"));
for (int i = 0; i < vmOpts.size(); i += 1) {
System.out.print(" " + vmOpts.get(i));
}
......
......@@ -27,24 +27,43 @@ import java.io.File;
public final class JDKToolFinder {
private JDKToolFinder() {
}
/**
* Returns the full path to an executable in jdk/bin based on System property
* test.jdk (set by jtreg test suite)
*
* @return Full path to an executable in jdk/bin
*/
public static String getJDKTool(String tool) {
String binPath = System.getProperty("test.jdk");
if (binPath == null) {
throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
+ "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
private JDKToolFinder() {
}
binPath += File.separatorChar + "bin" + File.separatorChar + tool;
/**
* Returns the full path to an executable in jdk/bin based on System
* property {@code compile.jdk} (set by jtreg test suite)
*
* @return Full path to an executable in jdk/bin
*/
public static String getJDKTool(String tool) {
String binPath = System.getProperty("compile.jdk");
if (binPath == null) {
throw new RuntimeException("System property 'compile.jdk' not set. "
+ "This property is normally set by jtreg. "
+ "When running test separately, set this property using "
+ "'-Dcompile.jdk=/path/to/jdk'.");
}
binPath += File.separatorChar + "bin" + File.separatorChar + tool;
return binPath;
}
/**
* Returns the full path to an executable in &lt;current jdk&gt;/bin based
* on System property {@code test.jdk} (set by jtreg test suite)
*
* @return Full path to an executable in jdk/bin
*/
public static String getCurrentJDKTool(String tool) {
String binPath = System.getProperty("test.jdk");
if (binPath == null) {
throw new RuntimeException("System property 'test.jdk' not set. "
+ "This property is normally set by jtreg. "
+ "When running test separately, set this property using "
+ "'-Dtest.jdk=/path/to/jdk'.");
}
binPath += File.separatorChar + "bin" + File.separatorChar + tool;
return binPath;
}
return binPath;
}
}
#
# Copyright (c) 2013, 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.
#
# 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.
#
#
ifneq "x$(ALT_BOOTDIR)" "x"
BOOTDIR := $(ALT_BOOTDIR)
endif
ifeq "x$(BOOTDIR)" "x"
JDK_HOME := $(shell dirname $(shell which java))/..
else
JDK_HOME := $(BOOTDIR)
endif
SRC_DIR = src
BUILD_DIR = build
OUTPUT_DIR = $(BUILD_DIR)/classes
WHITEBOX_DIR = ../whitebox
JAVAC = $(JDK_HOME)/bin/javac
JAR = $(JDK_HOME)/bin/jar
SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld
.PHONY: clean cleantmp
all: ctw.jar cleantmp
clean: cleantmp
@rm -rf ctw.jar wb.jar
cleantmp:
@rm -rf filelist manifest.mf
@rm -rf $(BUILD_DIR)
ctw.jar: filelist wb.jar manifest.mf
@mkdir -p $(OUTPUT_DIR)
$(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
$(JAR) cfm ctw.jar manifest.mf -C $(OUTPUT_DIR) .
wb.jar:
make -C ${WHITEBOX_DIR} wb.jar
cp ${WHITEBOX_DIR}/wb.jar ./
make -C ${WHITEBOX_DIR} clean
filelist: $(SRC_FILES)
@rm -f $@
@echo $(SRC_FILES) > $@
manifest.mf:
@echo "Main-Class: ${MAIN_CLASS}" > manifest.mf
#
# Copyright (c) 2013, 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.
#
# 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.
#
#
DESCRIPTION
This is replacement for CompileTheWorld (CTW) written on java. Its purpose is
to make possible the use of CTW in product builds.
DEPENDENCES
The tool depends on Whitebox API. Assumed, that the sources of whitebox are
located in '../whitebox' directory.
BUILDING
Simple way to build, just type 'make'.
Makefile uses environment variables 'ALT_BOOTDIR', 'BOOTDIR' as root-dir of jdk
that will be used for compilation and creating jar.
On successful building 'ctw.jar' will be created.
RUNNING
Since the tool uses WhiteBox API, options 'UnlockDiagnosticVMOptions' and
'WhiteBoxAPI' should be specified, and 'wb.jar' should be added to
boot-classpath:
$ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar
Arguments can be paths to '.jar, '.zip', '.lst' files or directories with
classes, that define which classes will be compiled:
- '.jar', '.zip' files and directories are interpreted like in classpath
(including '<dir>/*' syntax)
- '.lst' files -- files with class names (in java notation) to compile.
CTW will try to find these classes with default class loader, so they should
be located in classpath.
Without arguments it would work as old version of CTW: all classes in
boot-classpath will be compiled, excluding classes in 'rt.jar' if 'rt.jar' isn't
first in boot-classpath.
Due CTW's flags also are not available in product builds, the tool uses
properties with the same names:
- 'CompileTheWorldPreloadClasses' -- type:boolean, default:true, description:
Preload all classes used by a class before start loading
- 'CompileTheWorldStartAt' -- type:long, default:1, description: First class
to consider
- 'CompileTheWorldStopAt' -- type:long, default:Long.MAX_VALUE, description:
Last class to consider
Also it uses additional properties:
- 'sun.hotspot.tools.ctw.verbose' -- type:boolean, default:false,
description: Verbose output, adds additional information about compilation
- 'sun.hotspot.tools.ctw.logfile' -- type:string, default:null,
description: Path to logfile, if it's null, cout will be used.
EXAMPLES
compile classes from 'rt.jar':
$ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ${JAVA_HOME}/jre/lib/rt.jar
compile classes from all '.jar' in './testjars' directory:
$ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./testjars/*
compile classes from './build/classes' directory:
$ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./build/classes
compile only java.lang.String, java.lang.Object classes:
$ echo java.lang.String > classes.lst
$ echo java.lang.Object >> classes.lst
$ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar classes.lst
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Set;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.concurrent.Executor;
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
/**
* * Handler for dirs containing classes to compile.
* @author igor.ignatyev@oracle.com
*/
public class ClassPathDirEntry extends PathHandler {
private final int rootLength = root.toString().length();
public ClassPathDirEntry(Path root, Executor executor) {
super(root, executor);
try {
URL url = root.toUri().toURL();
setLoader(new URLClassLoader(new URL[]{url}));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@Override
public void process() {
System.out.println("# dir: " + root);
if (!Files.exists(root)) {
return;
}
try {
Files.walkFileTree(root, EnumSet.of(FileVisitOption.FOLLOW_LINKS),
Integer.MAX_VALUE, new CompileFileVisitor());
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private void processFile(Path file) {
if (Utils.isClassFile(file.toString())) {
processClass(pathToClassName(file));
}
}
private String pathToClassName(Path file) {
String fileString;
if (root == file) {
fileString = file.normalize().toString();
} else {
fileString = file.normalize().toString().substring(rootLength + 1);
}
return Utils.fileNameToClassName(fileString);
}
private class CompileFileVisitor extends SimpleFileVisitor<Path> {
private final Set<Path> ready = new HashSet<>();
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
if (ready.contains(dir)) {
return FileVisitResult.SKIP_SUBTREE;
}
ready.add(dir);
return super.preVisitDirectory(dir, attrs);
}
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
if (!ready.contains(file)) {
processFile(file);
}
return isFinished() ? FileVisitResult.TERMINATE
: FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file,
IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.jar.*;
import java.util.concurrent.Executor;
import java.io.*;
import java.nio.file.*;
/**
* Handler for jar-files containing classes to compile.
* @author igor.ignatyev@oracle.com
*/
public class ClassPathJarEntry extends PathHandler {
public ClassPathJarEntry(Path root, Executor executor) {
super(root, executor);
try {
URL url = root.toUri().toURL();
setLoader(new URLClassLoader(new URL[]{url}));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@Override
public void process() {
System.out.println("# jar: " + root);
if (!Files.exists(root)) {
return;
}
try {
JarFile jarFile = new JarFile(root.toFile());
JarEntry entry;
for (Enumeration<JarEntry> e = jarFile.entries();
e.hasMoreElements(); ) {
entry = e.nextElement();
processJarEntry(entry);
if (isFinished()) {
return;
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private void processJarEntry(JarEntry entry) {
String filename = entry.getName();
if (Utils.isClassFile(filename)) {
processClass(Utils.fileNameToClassName(filename));
}
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Executor;
/**
* Handler for dirs containing jar-files with classes to compile.
*
* @author igor.ignatyev@oracle.com
*/
public class ClassPathJarInDirEntry extends PathHandler {
public ClassPathJarInDirEntry(Path root, Executor executor) {
super(root, executor);
}
@Override
public void process() {
System.out.println("# jar_in_dir: " + root);
if (!Files.exists(root)) {
return;
}
try (DirectoryStream<Path> ds
= Files.newDirectoryStream(root, "*.jar")) {
for (Path p : ds) {
new ClassPathJarEntry(p, executor).process();
if (isFinished()) {
return;
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Executor;
/**
* Handler for files containing a list of classes to compile.
*
* @author igor.ignatyev@oracle.com
*/
public class ClassesListInFile extends PathHandler {
public ClassesListInFile(Path root, Executor executor) {
super(root, executor);
}
@Override
public void process() {
System.out.println("# list: " + root);
if (!Files.exists(root)) {
return;
}
try {
try (BufferedReader reader = Files.newBufferedReader(root,
StandardCharsets.UTF_8)) {
String line;
while (!isFinished() && ((line = reader.readLine()) != null)) {
processClass(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import sun.management.ManagementFactoryHelper;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.*;
/**
* @author igor.ignatyev@oracle.com
*/
public class CompileTheWorld {
/**
* Entry point. Compiles classes in {@code args}, or all classes in
* boot-classpath if args is empty
*
* @param args paths to jar/zip, dir contains classes, or to .lst file
* contains list of classes to compile
*/
public static void main(String[] args) {
String logfile = Utils.LOG_FILE;
PrintStream os = null;
if (logfile != null) {
try {
os = new PrintStream(Files.newOutputStream(Paths.get(logfile)));
} catch (IOException io) {
}
}
if (os != null) {
System.setOut(os);
}
try {
try {
if (ManagementFactoryHelper.getCompilationMXBean() == null) {
throw new RuntimeException(
"CTW can not work in interpreted mode");
}
} catch (java.lang.NoClassDefFoundError e) {
// compact1, compact2 support
}
String[] paths = args;
boolean skipRtJar = false;
if (args.length == 0) {
paths = getDefaultPaths();
skipRtJar = true;
}
ExecutorService executor = createExecutor();
long start = System.currentTimeMillis();
try {
String path;
for (int i = 0, n = paths.length; i < n
&& !PathHandler.isFinished(); ++i) {
path = paths[i];
if (skipRtJar && i > 0 && isRtJar(path)) {
// rt.jar is not first, so skip it
continue;
}
PathHandler.create(path, executor).process();
}
} finally {
await(executor);
}
System.out.printf("Done (%d classes, %d methods, %d ms)%n",
Compiler.getClassCount(),
Compiler.getMethodCount(),
System.currentTimeMillis() - start);
} finally {
if (os != null) {
os.close();
}
}
}
private static ExecutorService createExecutor() {
final int threadsCount = Math.min(
Runtime.getRuntime().availableProcessors(),
Utils.CI_COMPILER_COUNT);
ExecutorService result;
if (threadsCount > 1) {
result = new ThreadPoolExecutor(threadsCount, threadsCount,
/* keepAliveTime */ 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(threadsCount),
new ThreadPoolExecutor.CallerRunsPolicy());
} else {
result = new CurrentThreadExecutor();
}
return result;
}
private static String[] getDefaultPaths() {
String property = System.getProperty("sun.boot.class.path");
System.out.println(
"# use 'sun.boot.class.path' as args: " + property);
return Utils.PATH_SEPARATOR.split(property);
}
private static void await(ExecutorService executor) {
executor.shutdown();
while (!executor.isTerminated()) {
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}
}
private static boolean isRtJar(String path) {
return Utils.endsWithIgnoreCase(path, File.separator + "rt.jar");
}
private static class CurrentThreadExecutor extends AbstractExecutorService {
private boolean isShutdown;
@Override
public void shutdown() {
this.isShutdown = true;
}
@Override
public List<Runnable> shutdownNow() {
return null;
}
@Override
public boolean isShutdown() {
return isShutdown;
}
@Override
public boolean isTerminated() {
return isShutdown;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
return isShutdown;
}
@Override
public void execute(Runnable command) {
command.run();
}
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import sun.hotspot.WhiteBox;
import sun.misc.SharedSecrets;
import sun.reflect.ConstantPool;
import java.lang.reflect.Executable;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicLong;
/**
* Provide method to compile whole class.
* Also contains compiled methods and classes counters.
*
* @author igor.ignatyev@oracle.com
*/
public class Compiler {
private Compiler() { }
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final AtomicLong CLASS_COUNT = new AtomicLong(0L);
private static final AtomicLong METHOD_COUNT = new AtomicLong(0L);
private static volatile boolean CLASSES_LIMIT_REACHED = false;
/**
* @return count of processed classes
*/
public static long getClassCount() {
return CLASS_COUNT.get();
}
/**
* @return count of processed methods
*/
public static long getMethodCount() {
return METHOD_COUNT.get();
}
/**
* @return {@code true} if classes limit is reached
*/
public static boolean isLimitReached() {
return CLASSES_LIMIT_REACHED;
}
/**
* Compiles all methods and constructors.
*
* @param aClass class to compile
* @param executor executor used for compile task invocation
* @throws NullPointerException if {@code class} or {@code executor}
* is {@code null}
*/
public static void compileClass(Class aClass, Executor executor) {
Objects.requireNonNull(aClass);
Objects.requireNonNull(executor);
long id = CLASS_COUNT.incrementAndGet();
if (id > Utils.COMPILE_THE_WORLD_STOP_AT) {
CLASS_COUNT.decrementAndGet();
CLASSES_LIMIT_REACHED = true;
return;
}
if (id >= Utils.COMPILE_THE_WORLD_START_AT) {
String name = aClass.getName();
try {
System.out.printf("[%d]\t%s%n", id, name);
ConstantPool constantPool = SharedSecrets.getJavaLangAccess().
getConstantPool(aClass);
if (Utils.COMPILE_THE_WORLD_PRELOAD_CLASSES) {
preloadClasses(name, id, constantPool);
}
long methodCount = 0;
for (Executable e : aClass.getDeclaredConstructors()) {
++methodCount;
executor.execute(new CompileMethodCommand(id, name, e));
}
for (Executable e : aClass.getDeclaredMethods()) {
++methodCount;
executor.execute(new CompileMethodCommand(id, name, e));
}
METHOD_COUNT.addAndGet(methodCount);
if (Utils.DEOPTIMIZE_ALL_CLASSES_RATE > 0
&& (id % Utils.DEOPTIMIZE_ALL_CLASSES_RATE == 0)) {
WHITE_BOX.deoptimizeAll();
}
} catch (Throwable t) {
System.out.printf("[%d]\t%s\tskipping %s%n", id, name, t);
t.printStackTrace();
}
}
}
private static void preloadClasses(String className, long id,
ConstantPool constantPool) {
try {
for (int i = 0, n = constantPool.getSize(); i < n; ++i) {
try {
constantPool.getClassAt(i);
} catch (IllegalArgumentException ignore) {
}
}
} catch (Throwable t) {
System.out.printf("[%d]\t%s\tpreloading failed : %s%n", id,
className, t);
}
}
/**
* Compilation of method.
* Will compile method on all available comp levels.
*/
private static class CompileMethodCommand implements Runnable {
private final long classId;
private final String className;
private final Executable method;
/**
* @param classId id of class
* @param className name of class
* @param method compiled for compilation
*/
public CompileMethodCommand(long classId, String className,
Executable method) {
this.classId = classId;
this.className = className;
this.method = method;
}
@Override
public final void run() {
int compLevel = Utils.INITIAL_COMP_LEVEL;
if (Utils.TIERED_COMPILATION) {
for (int i = compLevel; i <= Utils.TIERED_STOP_AT_LEVEL; ++i) {
WHITE_BOX.deoptimizeMethod(method);
compileMethod(method, i);
}
} else {
compileMethod(method, compLevel);
}
}
private void waitCompilation() {
if (!Utils.BACKGROUND_COMPILATION) {
return;
}
final Object obj = new Object();
synchronized (obj) {
for (int i = 0;
i < 10 && WHITE_BOX.isMethodQueuedForCompilation(method);
++i) {
try {
obj.wait(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
private void compileMethod(Executable method, int compLevel) {
if (WHITE_BOX.isMethodCompilable(method, compLevel)) {
try {
WHITE_BOX.enqueueMethodForCompilation(method, compLevel);
waitCompilation();
int tmp = WHITE_BOX.getMethodCompilationLevel(method);
if (tmp != compLevel) {
logMethod(method, "compilation level = " + tmp
+ ", but not " + compLevel);
} else if (Utils.IS_VERBOSE) {
logMethod(method, "compilation level = " + tmp + ". OK");
}
} catch (Throwable t) {
logMethod(method, "error on compile at " + compLevel
+ " level");
t.printStackTrace();
}
} else if (Utils.IS_VERBOSE) {
logMethod(method, "not compilable at " + compLevel);
}
}
private void logMethod(Executable method, String message) {
StringBuilder builder = new StringBuilder("[");
builder.append(classId);
builder.append("]\t");
builder.append(className);
builder.append("::");
builder.append(method.getName());
builder.append('(');
Class[] params = method.getParameterTypes();
for (int i = 0, n = params.length - 1; i < n; ++i) {
builder.append(params[i].getName());
builder.append(", ");
}
if (params.length != 0) {
builder.append(params[params.length - 1].getName());
}
builder.append(')');
if (message != null) {
builder.append('\t');
builder.append(message);
}
System.err.println(builder);
}
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.File;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.concurrent.Executor;
/**
* Abstract handler for path.
* <p/>
* Concrete subclasses should implement method {@link #process()}.
*
* @author igor.ignatyev@oracle.com
*/
public abstract class PathHandler {
private static final Pattern JAR_IN_DIR_PATTERN
= Pattern.compile("^(.*[/\\\\])?\\*$");
protected final Path root;
protected final Executor executor;
private ClassLoader loader;
/**
* @param root root path to process
* @param executor executor used for process task invocation
* @throws NullPointerException if {@code root} or {@code executor} is
* {@code null}
*/
protected PathHandler(Path root, Executor executor) {
Objects.requireNonNull(root);
Objects.requireNonNull(executor);
this.root = root.normalize();
this.executor = executor;
this.loader = ClassLoader.getSystemClassLoader();
}
/**
* Factory method. Construct concrete handler in depends from {@code path}.
*
* @param path the path to process
* @param executor executor used for compile task invocation
* @throws NullPointerException if {@code path} or {@code executor} is
* {@code null}
*/
public static PathHandler create(String path, Executor executor) {
Objects.requireNonNull(path);
Objects.requireNonNull(executor);
Matcher matcher = JAR_IN_DIR_PATTERN.matcher(path);
if (matcher.matches()) {
path = matcher.group(1);
path = path.isEmpty() ? "." : path;
return new ClassPathJarInDirEntry(Paths.get(path), executor);
} else {
path = path.isEmpty() ? "." : path;
Path p = Paths.get(path);
if (isJarFile(p)) {
return new ClassPathJarEntry(p, executor);
} else if (isListFile(p)) {
return new ClassesListInFile(p, executor);
} else {
return new ClassPathDirEntry(p, executor);
}
}
}
private static boolean isJarFile(Path path) {
if (Files.isRegularFile(path)) {
String name = path.toString();
return Utils.endsWithIgnoreCase(name, ".zip")
|| Utils.endsWithIgnoreCase(name, ".jar");
}
return false;
}
private static boolean isListFile(Path path) {
if (Files.isRegularFile(path)) {
String name = path.toString();
return Utils.endsWithIgnoreCase(name, ".lst");
}
return false;
}
/**
* Processes all classes in specified path.
*/
public abstract void process();
/**
* Sets class loader, that will be used to define class at
* {@link #processClass(String)}.
*
* @param loader class loader
* @throws NullPointerException if {@code loader} is {@code null}
*/
protected final void setLoader(ClassLoader loader) {
Objects.requireNonNull(loader);
this.loader = loader;
}
/**
* Processes specificed class.
* @param name fully qualified name of class to process
*/
protected final void processClass(String name) {
try {
Class aClass = Class.forName(name, true, loader);
Compiler.compileClass(aClass, executor);
} catch (ClassNotFoundException | LinkageError e) {
System.out.printf("Class %s loading failed : %s%n", name,
e.getMessage());
}
}
/**
* @return {@code true} if processing should be stopped
*/
public static boolean isFinished() {
return Compiler.isLimitReached();
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.tools.ctw;
import com.sun.management.HotSpotDiagnosticMXBean;
import sun.management.ManagementFactoryHelper;
import java.io.File;
import java.util.regex.Pattern;
/**
* Auxiliary methods.
*
* @author igor.ignatyev@oracle.com
*/
public class Utils {
/**
* Value of {@code -XX:CompileThreshold}
*/
public static final boolean TIERED_COMPILATION
= Boolean.parseBoolean(getVMOption("TieredCompilation", "false"));
/**
* Value of {@code -XX:BackgroundCompilation}
*/
public static final boolean BACKGROUND_COMPILATION
= Boolean.parseBoolean(getVMOption("BackgroundCompilation",
"false"));
/**
* Value of {@code -XX:TieredStopAtLevel}
*/
public static final int TIERED_STOP_AT_LEVEL;
/**
* Value of {@code -XX:CICompilerCount}
*/
public static final Integer CI_COMPILER_COUNT
= Integer.valueOf(getVMOption("CICompilerCount", "1"));
/**
* Initial compilation level.
*/
public static final int INITIAL_COMP_LEVEL;
/**
* Compiled path-separator regexp.
*/
public static final Pattern PATH_SEPARATOR = Pattern.compile(
File.pathSeparator, Pattern.LITERAL);
/**
* Value of {@code -DDeoptimizeAllClassesRate}. Frequency of
* {@code WB.deoptimizeAll()} invocation If it less that {@code 0},
* {@code WB.deoptimizeAll()} will not be invoked.
*/
public static final int DEOPTIMIZE_ALL_CLASSES_RATE
= Integer.getInteger("DeoptimizeAllClassesRate", -1);
/**
* Value of {@code -DCompileTheWorldStopAt}. Last class to consider.
*/
public static final long COMPILE_THE_WORLD_STOP_AT
= Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE);
/**
* Value of {@code -DCompileTheWorldStartAt}. First class to consider.
*/
public static final long COMPILE_THE_WORLD_START_AT
= Long.getLong("CompileTheWorldStartAt", 1);
/**
* Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes
* used by a class before start loading.
*/
public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES;
/**
* Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output,
* adds additional information about compilation.
*/
public static final boolean IS_VERBOSE
= Boolean.getBoolean("sun.hotspot.tools.ctw.verbose");
/**
* Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if
* it's null, cout will be used.
*/
public static final String LOG_FILE
= System.getProperty("sun.hotspot.tools.ctw.logfile");
static {
if (Utils.TIERED_COMPILATION) {
INITIAL_COMP_LEVEL = 1;
} else {
String vmName = System.getProperty("java.vm.name");
if (Utils.endsWithIgnoreCase(vmName, " Server VM")) {
INITIAL_COMP_LEVEL = 4;
} else if (Utils.endsWithIgnoreCase(vmName, " Client VM")
|| Utils.endsWithIgnoreCase(vmName, " Minimal VM")) {
INITIAL_COMP_LEVEL = 1;
} else {
throw new RuntimeException("Unknown VM: " + vmName);
}
}
TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel",
String.valueOf(INITIAL_COMP_LEVEL)));
}
static {
String tmp = System.getProperty("CompileTheWorldPreloadClasses");
if (tmp == null) {
COMPILE_THE_WORLD_PRELOAD_CLASSES = true;
} else {
COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp);
}
}
public static final String CLASSFILE_EXT = ".class";
private Utils() {
}
/**
* Tests if the string ends with the suffix, ignoring case
* considerations
*
* @param string the tested string
* @param suffix the suffix
* @return {@code true} if {@code string} ends with the {@code suffix}
* @see String#endsWith(String)
*/
public static boolean endsWithIgnoreCase(String string, String suffix) {
if (string == null || suffix == null) {
return false;
}
int length = suffix.length();
int toffset = string.length() - length;
if (toffset < 0) {
return false;
}
return string.regionMatches(true, toffset, suffix, 0, length);
}
/**
* Returns value of VM option.
*
* @param name option's name
* @return value of option or {@code null}, if option doesn't exist
* @throws NullPointerException if name is null
*/
public static String getVMOption(String name) {
String result;
HotSpotDiagnosticMXBean diagnostic
= ManagementFactoryHelper.getDiagnosticMXBean();
result = diagnostic.getVMOption(name).getValue();
return result;
}
/**
* Returns value of VM option or default value.
*
* @param name option's name
* @param defaultValue default value
* @return value of option or {@code defaultValue}, if option doesn't exist
* @throws NullPointerException if name is null
* @see #getVMOption(String)
*/
public static String getVMOption(String name, String defaultValue) {
String result;
try {
result = getVMOption(name);
} catch (NoClassDefFoundError e) {
// compact1, compact2 support
result = defaultValue;
}
return result == null ? defaultValue : result;
}
/**
* Tests if the filename is valid filename for class file.
*
* @param filename tested filename
*/
public static boolean isClassFile(String filename) {
// If the filename has a period after removing '.class', it's not valid class file
return endsWithIgnoreCase(filename, CLASSFILE_EXT)
&& (filename.indexOf('.')
== (filename.length() - CLASSFILE_EXT.length()));
}
/**
* Converts the filename to classname.
*
* @param filename filename to convert
* @return corresponding classname.
* @throws AssertionError if filename isn't valid filename for class file -
* {@link #isClassFile(String)}
*/
public static String fileNameToClassName(String filename) {
assert isClassFile(filename);
return filename.substring(0, filename.length() - CLASSFILE_EXT.length())
.replace(File.separatorChar, '.');
}
}
public class Bar {
private static void staticMethod() { }
public void method() { }
protected Bar() { }
}
/*
* Copyright (c) 2013, 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.
*
* 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.
*/
/*
* @test ClassesDirTest
* @bug 8012447
* @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
* @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesDirTest Foo Bar
* @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
* @run main ClassesDirTest prepare
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes
* @run main ClassesDirTest check ctw.log
* @summary testing of CompileTheWorld :: classes in directory
* @author igor.ignatyev@oracle.com
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class ClassesDirTest extends CtwTest {
private static final String[] SHOULD_CONTAIN
= {"# dir: classes", "Done (2 classes, 6 methods, "};
private ClassesDirTest() {
super(SHOULD_CONTAIN);
}
public static void main(String[] args) throws Exception {
new ClassesDirTest().run(args);
}
protected void prepare() throws Exception {
String path = "classes";
Files.createDirectory(Paths.get(path));
Files.move(Paths.get("Foo.class"), Paths.get(path, "Foo.class"),
StandardCopyOption.REPLACE_EXISTING);
Files.move(Paths.get("Bar.class"), Paths.get(path, "Bar.class"),
StandardCopyOption.REPLACE_EXISTING);
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.
*/
/*
* @test ClassesListTest
* @bug 8012447
* @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
* @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesListTest Foo Bar
* @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
* @run main ClassesListTest prepare
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst
* @run main ClassesListTest check ctw.log
* @summary testing of CompileTheWorld :: list of classes in file
* @author igor.ignatyev@oracle.com
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class ClassesListTest extends CtwTest {
private static final String[] SHOULD_CONTAIN
= {"# list: classes.lst", "Done (4 classes, "};
private ClassesListTest() {
super(SHOULD_CONTAIN);
}
public static void main(String[] args) throws Exception {
new ClassesListTest().run(args);
}
protected void prepare() throws Exception {
String path = "classes.lst";
Files.copy(Paths.get(System.getProperty("test.src"), path),
Paths.get(path), StandardCopyOption.REPLACE_EXISTING);
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.
*/
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.charset.Charset;
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
public abstract class CtwTest {
protected final String[] shouldContain;
protected CtwTest(String[] shouldContain) {
this.shouldContain = shouldContain;
}
public void run(String[] args) throws Exception {
if (args.length == 0) {
throw new Error("args is empty");
}
switch (args[0]) {
case "prepare":
prepare();
break;
case "check":
check(args);
break;
default:
throw new Error("unregonized action -- " + args[0]);
}
}
protected void prepare() throws Exception { }
protected void check(String[] args) throws Exception {
if (args.length < 2) {
throw new Error("logfile isn't specified");
}
String logfile = args[1];
try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile),
Charset.defaultCharset())) {
OutputAnalyzer output = readOutput(r);
for (String test : shouldContain) {
output.shouldContain(test);
}
}
}
private static OutputAnalyzer readOutput(BufferedReader reader)
throws IOException {
StringBuilder builder = new StringBuilder();
String eol = String.format("%n");
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(eol);
}
return new OutputAnalyzer(builder.toString(), "");
}
protected void dump(OutputAnalyzer output, String name) {
try (Writer w = new FileWriter(name + ".out")) {
String s = output.getStdout();
w.write(s, s.length(), 0);
} catch (IOException io) {
io.printStackTrace();
}
try (Writer w = new FileWriter(name + ".err")) {
String s = output.getStderr();
w.write(s, s.length(), 0);
} catch (IOException io) {
io.printStackTrace();
}
}
protected ProcessBuilder createJarProcessBuilder(String... command)
throws Exception {
String javapath = JDKToolFinder.getJDKTool("jar");
ArrayList<String> args = new ArrayList<>();
args.add(javapath);
Collections.addAll(args, command);
return new ProcessBuilder(args.toArray(new String[args.size()]));
}
}
public class Foo {
private static void staticMethod() { }
public void method() { }
protected Foo() { }
}
/*
* Copyright (c) 2013, 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.
*
* 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.
*/
/*
* @test JarDirTest
* @bug 8012447
* @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
* @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarDirTest Foo Bar
* @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
* @run main JarDirTest prepare
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/*
* @run main JarDirTest check ctw.log
* @summary testing of CompileTheWorld :: jars in directory
* @author igor.ignatyev@oracle.com
*/
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import com.oracle.java.testlibrary.OutputAnalyzer;
public class JarDirTest extends CtwTest {
private static final String[] SHOULD_CONTAIN
= {"# jar_in_dir: jars",
"# jar: jars" + File.separator +"foo.jar",
"# jar: jars" + File.separator +"bar.jar",
"Done (4 classes, 12 methods, "};
private JarDirTest() {
super(SHOULD_CONTAIN);
}
public static void main(String[] args) throws Exception {
new JarDirTest().run(args);
}
protected void prepare() throws Exception {
String path = "jars";
Files.createDirectory(Paths.get(path));
ProcessBuilder pb = createJarProcessBuilder("cf", "jars/foo.jar",
"Foo.class", "Bar.class");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
dump(output, "ctw-foo.jar");
output.shouldHaveExitValue(0);
pb = createJarProcessBuilder("cf", "jars/bar.jar", "Foo.class",
"Bar.class");
output = new OutputAnalyzer(pb.start());
dump(output, "ctw-bar.jar");
output.shouldHaveExitValue(0);
}
}
/*
* Copyright (c) 2013, 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.
*
* 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.
*/
/*
* @test JarsTest
* @bug 8012447
* @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src
* @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarsTest Foo Bar
* @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
* @run main JarsTest prepare
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar
* @run main JarsTest check ctw.log
* @summary testing of CompileTheWorld :: jars
* @author igor.ignatyev@oracle.com
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
public class JarsTest extends CtwTest {
private static final String[] SHOULD_CONTAIN
= {"# jar: foo.jar", "# jar: bar.jar",
"Done (4 classes, 12 methods, "};
private JarsTest() {
super(SHOULD_CONTAIN);
}
public static void main(String[] args) throws Exception {
new JarsTest().run(args);
}
protected void prepare() throws Exception {
ProcessBuilder pb = createJarProcessBuilder("cf", "foo.jar",
"Foo.class", "Bar.class");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
dump(output, "ctw-foo.jar");
output.shouldHaveExitValue(0);
pb = createJarProcessBuilder("cf", "bar.jar", "Foo.class", "Bar.class");
output = new OutputAnalyzer(pb.start());
dump(output, "ctw-bar.jar");
output.shouldHaveExitValue(0);
}
}
java.lang.String
java.lang.Object
Foo
Bar
#
# Copyright (c) 2013, 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.
#
# 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.
#
#
ifneq "x$(ALT_BOOTDIR)" "x"
BOOTDIR := $(ALT_BOOTDIR)
endif
ifeq "x$(BOOTDIR)" "x"
JDK_HOME := $(shell dirname $(shell which java))/..
else
JDK_HOME := $(BOOTDIR)
endif
SRC_DIR = ./
BUILD_DIR = build
OUTPUT_DIR = $(BUILD_DIR)/classes
JAVAC = $(JDK_HOME)/bin/javac
JAR = $(JDK_HOME)/bin/jar
SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
.PHONY: filelist clean cleantmp
all: wb.jar cleantmp
wb.jar: filelist
@mkdir -p $(OUTPUT_DIR)
$(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp $(OUTPUT_DIR) @filelist
$(JAR) cf wb.jar -C $(OUTPUT_DIR) .
@rm -rf $(OUTPUT_DIR)
filelist: $(SRC_FILES)
@rm -f $@
@echo $(SRC_FILES) > $@
clean: cleantmp
@rm -rf wb.jar
cleantmp:
@rm -rf filelist
@rm -rf $(BUILD_DIR)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册