mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 03:54:33 +02:00
8012447: Java CTW implementation
Reviewed-by: vlivanov, kvn, twisti
This commit is contained in:
parent
547f4dea7b
commit
c73d393947
21 changed files with 1752 additions and 18 deletions
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -31,18 +31,37 @@ public final class JDKToolFinder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the full path to an executable in jdk/bin based on System property
|
||||
* test.jdk (set by jtreg test suite)
|
||||
* 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 <current jdk>/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'.");
|
||||
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;
|
||||
|
|
73
hotspot/test/testlibrary/ctw/Makefile
Normal file
73
hotspot/test/testlibrary/ctw/Makefile
Normal file
|
@ -0,0 +1,73 @@
|
|||
#
|
||||
# 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
|
93
hotspot/test/testlibrary/ctw/README
Normal file
93
hotspot/test/testlibrary/ctw/README
Normal file
|
@ -0,0 +1,93 @@
|
|||
#
|
||||
# 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
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* 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, '.');
|
||||
}
|
||||
}
|
5
hotspot/test/testlibrary/ctw/test/Bar.java
Normal file
5
hotspot/test/testlibrary/ctw/test/Bar.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
public class Bar {
|
||||
private static void staticMethod() { }
|
||||
public void method() { }
|
||||
protected Bar() { }
|
||||
}
|
61
hotspot/test/testlibrary/ctw/test/ClassesDirTest.java
Normal file
61
hotspot/test/testlibrary/ctw/test/ClassesDirTest.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
58
hotspot/test/testlibrary/ctw/test/ClassesListTest.java
Normal file
58
hotspot/test/testlibrary/ctw/test/ClassesListTest.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
118
hotspot/test/testlibrary/ctw/test/CtwTest.java
Normal file
118
hotspot/test/testlibrary/ctw/test/CtwTest.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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()]));
|
||||
}
|
||||
}
|
5
hotspot/test/testlibrary/ctw/test/Foo.java
Normal file
5
hotspot/test/testlibrary/ctw/test/Foo.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
public class Foo {
|
||||
private static void staticMethod() { }
|
||||
public void method() { }
|
||||
protected Foo() { }
|
||||
}
|
75
hotspot/test/testlibrary/ctw/test/JarDirTest.java
Normal file
75
hotspot/test/testlibrary/ctw/test/JarDirTest.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
65
hotspot/test/testlibrary/ctw/test/JarsTest.java
Normal file
65
hotspot/test/testlibrary/ctw/test/JarsTest.java
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
4
hotspot/test/testlibrary/ctw/test/classes.lst
Normal file
4
hotspot/test/testlibrary/ctw/test/classes.lst
Normal file
|
@ -0,0 +1,4 @@
|
|||
java.lang.String
|
||||
java.lang.Object
|
||||
Foo
|
||||
Bar
|
63
hotspot/test/testlibrary/whitebox/Makefile
Normal file
63
hotspot/test/testlibrary/whitebox/Makefile
Normal file
|
@ -0,0 +1,63 @@
|
|||
#
|
||||
# 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)
|
Loading…
Add table
Add a link
Reference in a new issue