# HG changeset patch # User never # Date 1467144523 0 # Node ID bae79d28e9b1aa5b153dd4101aeb653e1bf4d702 # Parent 4a288aaf85118c1a6cbdef8e26fa595c69d2c6aa# Parent dbd5f98380498560364cbfc6f99d265580dceca4 Merge diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java Tue Jun 28 20:08:43 2016 +0000 @@ -28,6 +28,8 @@ import sun.hotspot.code.NMethod; import sun.hotspot.cpuinfo.CPUInfo; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.util.concurrent.Callable; diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/Makefile --- a/hotspot/test/testlibrary/ctw/Makefile Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/Makefile Tue Jun 28 20:08:43 2016 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2016. Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,13 @@ SRC_DIR = src BUILD_DIR = build OUTPUT_DIR = $(BUILD_DIR)/classes -WHITEBOX_DIR = ../whitebox +TESTLIBRARY_DIR = ../../../../test/lib JAVAC = $(JDK_HOME)/bin/javac JAR = $(JDK_HOME)/bin/jar -SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') +SRC_FILES = $(shell find $(SRC_DIR) $(TESTLIBRARY_DIR)/share/classes -name '*.java') +WB_SRC_FILES = $(shell find $(TESTLIBRARY_DIR)/sun/hotspot -name '*.java') MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld @@ -52,22 +53,29 @@ @rm -rf ctw.jar wb.jar cleantmp: - @rm -rf filelist manifest.mf + @rm -rf filelist wb_filelist manifest.mf @rm -rf $(BUILD_DIR) -ctw.jar: filelist wb.jar manifest.mf +ctw.jar: filelist wb.jar @mkdir -p $(OUTPUT_DIR) - $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist - $(JAR) cfm ctw.jar manifest.mf -C $(OUTPUT_DIR) . + $(JAVAC) -XaddExports:java.base/jdk.internal.jimage=ALL-UNNAMED \ + -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED \ + -XaddExports:java.base/jdk.internal.reflect=ALL-UNNAMED \ + -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist + $(JAR) --create --file=$@ --main-class $(MAIN_CLASS) -C $(OUTPUT_DIR) . -wb.jar: - make -C ${WHITEBOX_DIR} wb.jar - cp ${WHITEBOX_DIR}/wb.jar ./ - make -C ${WHITEBOX_DIR} clean +wb.jar: wb_filelist + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -sourcepath $(TESTLIBRARY_DIR) \ + -d $(OUTPUT_DIR) \ + -cp $(OUTPUT_DIR) \ + @wb_filelist + $(JAR) --create --file=$@ -C $(OUTPUT_DIR) . + +wb_filelist: $(WB_SRC_FILES) + @rm -f $@ + @echo $(WB_SRC_FILES) > $@ filelist: $(SRC_FILES) @rm -f $@ @echo $(SRC_FILES) > $@ - -manifest.mf: - @echo "Main-Class: ${MAIN_CLASS}" > manifest.mf diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java Tue Jun 28 20:08:43 2016 +0000 @@ -54,7 +54,7 @@ @Override public void process() { - System.out.println("# dir: " + root); + CompileTheWorld.OUT.println("# dir: " + root); if (!Files.exists(root)) { return; } diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java Tue Jun 28 20:08:43 2016 +0000 @@ -50,7 +50,7 @@ @Override public void process() { - System.out.println("# jar: " + root); + CompileTheWorld.OUT.println("# jar: " + root); if (!Files.exists(root)) { return; } diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java Tue Jun 28 20:08:43 2016 +0000 @@ -40,7 +40,7 @@ @Override public void process() { - System.out.println("# jar_in_dir: " + root); + CompileTheWorld.OUT.println("# jar_in_dir: " + root); if (!Files.exists(root)) { return; } diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java Tue Jun 28 20:08:43 2016 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 jdk.internal.jimage.ImageReader; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.concurrent.Executor; + +/** + * Handler for jimage-files containing classes to compile. + */ +public class ClassPathJimageEntry extends PathHandler { + public ClassPathJimageEntry(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() { + CompileTheWorld.OUT.println("# jimage: " + root); + if (!Files.exists(root)) { + return; + } + try { + ImageReader reader = ImageReader.open(root); + Arrays.stream(reader.getEntryNames()) + .filter(name -> name.endsWith(".class")) + .filter(name -> !name.endsWith("module-info.class")) + .map(Utils::fileNameToClassName) + .forEach(this::processClass); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } +} diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java Tue Jun 28 20:08:43 2016 +0000 @@ -40,7 +40,7 @@ @Override public void process() { - System.out.println("# list: " + root); + CompileTheWorld.OUT.println("# list: " + root); if (!Files.exists(root)) { return; } diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Tue Jun 28 20:08:43 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,14 +33,20 @@ import java.util.concurrent.*; public class CompileTheWorld { + // in case when a static constructor changes System::out and System::err + // we hold these values of output streams + public static final PrintStream OUT = System.out; + public static final PrintStream ERR = System.err; /** - * Entry point. Compiles classes in {@code args}, or all classes in - * boot-classpath if args is empty + * Entry point. Compiles classes in {@code paths} * - * @param args paths to jar/zip, dir contains classes, or to .lst file - * contains list of classes to compile + * @param paths paths to jar/zip, dir contains classes, or to .lst file + * contains list of classes to compile */ - public static void main(String[] args) { + public static void main(String[] paths) { + if (paths.length == 0) { + throw new IllegalArgumentException("Expect a path to a compile target."); + } String logfile = Utils.LOG_FILE; PrintStream os = null; if (logfile != null) { @@ -62,12 +68,6 @@ } 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 { @@ -75,17 +75,13 @@ 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(), + CompileTheWorld.OUT.printf("Done (%d classes, %d methods, %d ms)%n", + PathHandler.getClassCount(), Compiler.getMethodCount(), System.currentTimeMillis() - start); } finally { @@ -93,6 +89,9 @@ os.close(); } } + // in case when a static constructor creates and runs a new thread + // we force it to exit + System.exit(0); } private static ExecutorService createExecutor() { @@ -111,13 +110,6 @@ 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()) { @@ -130,10 +122,6 @@ } } - private static boolean isRtJar(String path) { - return Utils.endsWithIgnoreCase(path, File.separator + "rt.jar"); - } - private static class CurrentThreadExecutor extends AbstractExecutorService { private boolean isShutdown; diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java Tue Jun 28 20:08:43 2016 +0000 @@ -26,7 +26,6 @@ import sun.hotspot.WhiteBox; import jdk.internal.misc.SharedSecrets; import jdk.internal.reflect.ConstantPool; - import java.lang.reflect.Executable; import java.util.Objects; @@ -38,18 +37,11 @@ * Also contains compiled methods and classes counters. */ 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(); - } + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final AtomicLong METHOD_COUNT = new AtomicLong(0L); + + private Compiler() { } /** * @return count of processed methods @@ -59,58 +51,41 @@ } /** - * @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 id an id of the class * @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) { + public static void compileClass(Class aClass, long id, 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; - } + try { + ConstantPool constantPool = SharedSecrets.getJavaLangAccess(). + getConstantPool(aClass); + if (Utils.COMPILE_THE_WORLD_PRELOAD_CLASSES) { + preloadClasses(aClass.getName(), id, constantPool); + } + long methodCount = 0; + for (Executable e : aClass.getDeclaredConstructors()) { + ++methodCount; + executor.execute(new CompileMethodCommand(id, e)); + } + for (Executable e : aClass.getDeclaredMethods()) { + ++methodCount; + executor.execute(new CompileMethodCommand(id, e)); + } + METHOD_COUNT.addAndGet(methodCount); - 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(); + if (Utils.DEOPTIMIZE_ALL_CLASSES_RATE > 0 + && (id % Utils.DEOPTIMIZE_ALL_CLASSES_RATE == 0)) { + WHITE_BOX.deoptimizeAll(); } + } catch (Throwable t) { + CompileTheWorld.OUT.printf("[%d]\t%s\tskipping %s%n", id, aClass.getName(), t); + t.printStackTrace(); } } @@ -124,8 +99,8 @@ } } } catch (Throwable t) { - System.out.printf("[%d]\t%s\tpreloading failed : %s%n", id, - className, t); + CompileTheWorld.OUT.printf("[%d]\t%s\tpreloading failed : %s%n", + id, className, t); } } @@ -142,13 +117,11 @@ /** * @param classId id of class - * @param className name of class * @param method compiled for compilation */ - public CompileMethodCommand(long classId, String className, - Executable method) { + public CompileMethodCommand(long classId, Executable method) { this.classId = classId; - this.className = className; + this.className = method.getDeclaringClass().getName(); this.method = method; } @@ -158,10 +131,10 @@ if (Utils.TIERED_COMPILATION) { for (int i = compLevel; i <= Utils.TIERED_STOP_AT_LEVEL; ++i) { WHITE_BOX.deoptimizeMethod(method); - compileMethod(method, i); + compileAtLevel(i); } } else { - compileMethod(method, compLevel); + compileAtLevel(compLevel); } } @@ -183,29 +156,29 @@ } } - private void compileMethod(Executable method, int compLevel) { + private void compileAtLevel(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 + log("compilation level = " + tmp + ", but not " + compLevel); } else if (Utils.IS_VERBOSE) { - logMethod(method, "compilation level = " + tmp + ". OK"); + log("compilation level = " + tmp + ". OK"); } } catch (Throwable t) { - logMethod(method, "error on compile at " + compLevel + log("error on compile at " + compLevel + " level"); t.printStackTrace(); } } else if (Utils.IS_VERBOSE) { - logMethod(method, "not compilable at " + compLevel); + log("not compilable at " + compLevel); } } - private void logMethod(Executable method, String message) { + private void log(String message) { StringBuilder builder = new StringBuilder("["); builder.append(classId); builder.append("]\t"); @@ -226,7 +199,7 @@ builder.append('\t'); builder.append(message); } - System.err.println(builder); + CompileTheWorld.ERR.println(builder); } } diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Tue Jun 28 20:08:43 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,14 @@ package sun.hotspot.tools.ctw; +import jdk.internal.misc.Unsafe; + 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.concurrent.atomic.AtomicLong; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.concurrent.Executor; @@ -38,6 +40,8 @@ * Concrete subclasses should implement method {@link #process()}. */ public abstract class PathHandler { + private static final AtomicLong CLASS_COUNT = new AtomicLong(0L); + private static volatile boolean CLASSES_LIMIT_REACHED = false; private static final Pattern JAR_IN_DIR_PATTERN = Pattern.compile("^(.*[/\\\\])?\\*$"); protected final Path root; @@ -81,6 +85,8 @@ return new ClassPathJarEntry(p, executor); } else if (isListFile(p)) { return new ClassesListInFile(p, executor); + } else if (isJimageFile(p)) { + return new ClassPathJimageEntry(p, executor); } else { return new ClassPathDirEntry(p, executor); } @@ -96,6 +102,13 @@ return false; } + private static boolean isJimageFile(Path path) { + String filename = path.getFileName().toString(); + return Files.isRegularFile(path) + && ("modules".equals(filename) + || Utils.endsWithIgnoreCase(filename, ".jimage")); + } + private static boolean isListFile(Path path) { if (Files.isRegularFile(path)) { String name = path.toString(); @@ -122,24 +135,50 @@ } /** - * Processes specificed class. + * Processes specified 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()); + Objects.requireNonNull(name); + if (CLASSES_LIMIT_REACHED) { + return; + } + long id = CLASS_COUNT.incrementAndGet(); + if (id > Utils.COMPILE_THE_WORLD_STOP_AT) { + CLASSES_LIMIT_REACHED = true; + return; + } + if (id >= Utils.COMPILE_THE_WORLD_START_AT) { + try { + Class aClass = loader.loadClass(name); + CompileTheWorld.OUT.printf("[%d]\t%s%n", id, name); + Compiler.compileClass(aClass, id, executor); + } catch (ClassNotFoundException e) { + CompileTheWorld.OUT.printf("Class %s loading failed : %s%n", + name, e.getMessage()); + } } } /** - * @return {@code true} if processing should be stopped + * @return count of processed classes + */ + public static long getClassCount() { + long id = CLASS_COUNT.get(); + if (id < Utils.COMPILE_THE_WORLD_START_AT) { + return 0; + } + if (id > Utils.COMPILE_THE_WORLD_STOP_AT) { + return Utils.COMPILE_THE_WORLD_STOP_AT - Utils.COMPILE_THE_WORLD_START_AT + 1; + } + return id - Utils.COMPILE_THE_WORLD_START_AT + 1; + } + + /** + * @return {@code true} if classes limit is reached and processing should be stopped */ public static boolean isFinished() { - return Compiler.isLimitReached(); + return CLASSES_LIMIT_REACHED; } } diff -r 4a288aaf8511 -r bae79d28e9b1 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java Tue Jun 28 17:22:56 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java Tue Jun 28 20:08:43 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,7 +207,12 @@ */ public static String fileNameToClassName(String filename) { assert isClassFile(filename); - return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) - .replace(File.separatorChar, '.'); + // workaround for the class naming in jimage : // + final char nameSeparator = '/'; + int nameStart = filename.charAt(0) == nameSeparator + ? filename.indexOf(nameSeparator, 1) + 1 + : 0; + return filename.substring(nameStart, filename.length() - CLASSFILE_EXT.length()) + .replace(nameSeparator, '.'); } }