# HG changeset patch # User amurillo # Date 1433457480 25200 # Node ID 6cf349c0d1a5ece38e835f3fe3c72dbc2790dff4 # Parent a832d39b95a0081ebed52f9ce4062fc63a7ad23f# Parent 317ef3b5d6f6989eceb8d878d5cbf40860ffbf90 Merge diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-java.instrument.gmk --- a/jdk/make/lib/Lib-java.instrument.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-java.instrument.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -61,7 +61,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBINSTRUMENT_SRC), \ OPTIMIZATION := LOW, \ - CFLAGS := $(LIBINSTRUMENT_CFLAGS) $(CFLAGS_WARNINGS_ARE_ERRORS), \ + CFLAGS := $(LIBINSTRUMENT_CFLAGS), \ CFLAGS_debug := -DJPLIS_LOGGING, \ CFLAGS_release := -DNO_JPLIS_LOGGING, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libinstrument/mapfile-vers, \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-java.management.gmk --- a/jdk/make/lib/Lib-java.management.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-java.management.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -50,7 +50,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBMANAGEMENT_SRC), \ OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_CFLAGS), \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_CFLAGS), \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-jdk.attach.gmk --- a/jdk/make/lib/Lib-jdk.attach.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-jdk.attach.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \ + CFLAGS := $(CFLAGS_JDKLIB) \ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.attach \ $(LIBJAVA_HEADER_FLAGS) $(LIBATTACH_CFLAGS), \ CFLAGS_windows := /Gy, \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-jdk.hprof.agent.gmk --- a/jdk/make/lib/Lib-jdk.hprof.agent.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-jdk.hprof.agent.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ BUILD_LIBHPROF_CFLAGS := $(addprefix -I, $(BUILD_LIBHPROF_SRC)) \ -I$(JDK_TOPDIR)/src/demo/share/jvmti/java_crw_demo - + BUILD_LIBHPROF_LDFLAGS := LIBHPROF_OPTIMIZATION := HIGHEST @@ -46,7 +46,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(BUILD_LIBHPROF_SRC), \ OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \ + CFLAGS := $(CFLAGS_JDKLIB) \ $(BUILD_LIBHPROF_CFLAGS), \ CFLAGS_debug := -DHPROF_LOGGING, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libhprof/mapfile-vers, \ @@ -75,7 +75,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBJAVA_CRW_DEMO_SRC), \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \ + CFLAGS := $(CFLAGS_JDKLIB) \ $(addprefix -I, $(LIBJAVA_CRW_DEMO_SRC)), \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjava_crw_demo/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-jdk.jdi.gmk --- a/jdk/make/lib/Lib-jdk.jdi.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-jdk.jdi.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBDT_SHMEM_SRC), \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) -DUSE_MMAP \ + CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \ $(LIBDT_SHMEM_CPPFLAGS), \ LDFLAGS := $(LDFLAGS_JDKLIB), \ LDFLAGS_windows := -export:jdwpTransport_OnLoad, \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-jdk.jdwp.agent.gmk --- a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBDT_SOCKET_SRC), \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_CFLAGS_WARNINGS_ARE_ERRORS) -DUSE_MMAP \ + CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \ $(LIBDT_SOCKET_CPPFLAGS), \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libdt_socket/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ @@ -77,7 +77,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBJDWP_SRC), \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) -DJDWP_LOGGING \ + CFLAGS := $(CFLAGS_JDKLIB) -DJDWP_LOGGING \ $(LIBJDWP_CPPFLAGS) \ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.jdwp.agent, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjdwp/mapfile-vers, \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-jdk.management.gmk --- a/jdk/make/lib/Lib-jdk.management.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-jdk.management.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -59,7 +59,7 @@ SRC := $(LIBMANAGEMENT_EXT_SRC), \ LANG := C, \ OPTIMIZATION := $(LIBMANAGEMENT_EXT_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_EXT_CFLAGS), \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_EXT_CFLAGS), \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement_ext/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/make/lib/Lib-jdk.sctp.gmk --- a/jdk/make/lib/Lib-jdk.sctp.gmk Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/make/lib/Lib-jdk.sctp.gmk Thu Jun 04 15:38:00 2015 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,12 +30,8 @@ ifeq ($(OPENJDK_TARGET_OS_TYPE), unix) ifeq (, $(filter $(OPENJDK_TARGET_OS), macosx aix)) - - # Suppress unused parameters required by exported JNI functions. - SCTP_WERROR := -Werror -Wno-error=unused-parameter - ifeq ($(OPENJDK_TARGET_CPU_ARCH), ppc) - SCTP_WERROR := - endif + # DISABLED_WARNINGS_gcc := unused-parameter needed to + # suppress unused parameters required by exported JNI functions. $(eval $(call SetupNativeCompilation,BUILD_LIBSCTP, \ LIBRARY := sctp, \ @@ -49,7 +45,7 @@ $(LIBJAVA_HEADER_FLAGS) \ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.sctp \ -I$(SUPPORT_OUTPUTDIR)/headers/java.base, \ - CFLAGS_linux := $(SCTP_WERROR), \ + DISABLED_WARNINGS_gcc := unused-parameter, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libsctp/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/src/java.base/share/classes/java/lang/Class.java diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Thu Jun 04 15:38:00 2015 -0700 @@ -27,8 +27,6 @@ import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; -import java.lang.reflect.Field; -import sun.misc.Cleaner; /** * A {@code CallSite} is a holder for a variable {@link MethodHandle}, @@ -138,47 +136,9 @@ /** * {@code CallSite} dependency context. - * VM uses context class to store nmethod dependencies on the call site target. - * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance. - * Lazily initialized when CallSite instance is linked to some indy call site or VM needs - * it to store dependencies. As a corollary, "null" context means there are no dependencies - * registered yet. {@code Cleaner} is used in 2 roles: - * (a) context class access for VM; - * (b) stale context class cleanup. - * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}). - * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly - * from {@code Reference.referent} field. - */ - private volatile Cleaner context = null; - - /** - * Default context. - * VM uses it to initialize non-linked CallSite context. + * JVM uses CallSite.context to store nmethod dependencies on the call site target. */ - private static class DefaultContext {} - private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null); - - private static Cleaner makeContext(Class referent, final CallSite holder) { - return Cleaner.create(referent, - new Runnable() { - @Override public void run() { - MethodHandleNatives.invalidateDependentNMethods(holder); - } - }); - } - - /** Initialize context class used for nmethod dependency tracking */ - /*package-private*/ - void initContext(Class newContext) { - // If there are concurrent actions, exactly one succeeds. - if (context == null) { - UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this)); - // No need to care about failed CAS attempt. - // Since initContext is called from indy call site linkage in newContext class, there's no risk - // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup - // action in the wrong context). - } - } + private final MethodHandleNatives.CallSiteContext context = MethodHandleNatives.CallSiteContext.make(this); /** * Returns the type of this call site's target. diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Jun 04 15:38:00 2015 -0700 @@ -30,6 +30,7 @@ import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; +import sun.misc.Cleaner; /** * The JVM interface for the method handles package is all here. @@ -61,8 +62,27 @@ static native void setCallSiteTargetNormal(CallSite site, MethodHandle target); static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target); - /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */ - static native void invalidateDependentNMethods(CallSite site); + /** Represents a context to track nmethod dependencies on CallSite instance target. */ + static class CallSiteContext implements Runnable { + //@Injected JVM_nmethodBucket* vmdependencies; + + static CallSiteContext make(CallSite cs) { + final CallSiteContext newContext = new CallSiteContext(); + // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context. + // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is + // referenced from Cleaner class) until cleanup is performed. + Cleaner.create(cs, newContext); + return newContext; + } + + @Override + public void run() { + MethodHandleNatives.clearCallSiteContext(this); + } + } + + /** Invalidate all recorded nmethods. */ + private static native void clearCallSiteContext(CallSiteContext context); private static native void registerNatives(); static { @@ -235,7 +255,6 @@ return Invokers.linkToTargetMethod(type); } else { appendixResult[0] = callSite; - callSite.initContext(caller); return Invokers.linkToCallSiteMethod(type); } } diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/src/java.base/share/classes/sun/reflect/Reflection.java diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java --- a/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java Thu Jun 04 15:38:00 2015 -0700 @@ -38,12 +38,19 @@ failures++; } catch (InvocationTargetException e) { Throwable c = e.getCause(); - if (expected.isInstance(c)) - System.out.println("EXPECTED: " + expected.getName() + ", "+ c); - else { - failures++; - System.out.println("FAIL: Unexpected wrapped exception " + c); - e.printStackTrace(System.out); + if (BootstrapMethodError.class.isInstance(c)) { + c = c.getCause(); + if (expected.isInstance(c)) + System.out.println("EXPECTED: " + expected.getName() + ", "+ c); + else { + failures++; + System.out.println("FAIL: Unexpected wrapped exception " + c); + e.printStackTrace(System.out); + } + } else { + failures++; + System.out.println("FAIL: Exception from MethodHandle invocation not wrapped in BootstrapMethodError " + c); + e.printStackTrace(System.out); } } catch (Throwable e) { failures++; @@ -74,14 +81,19 @@ Invoker.invoke(); System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier"); failures++; - } catch (Throwable e) { - if (expected.isInstance(e)) - System.out.println("EXPECTED: " + expected.getName() + ", "+ e); + } catch (BootstrapMethodError e) { + Throwable c = e.getCause(); + if (expected.isInstance(c)) + System.out.println("EXPECTED: " + expected.getName() + ", "+ c); else { + failures++; + System.out.println("FAIL: Unexpected exception has been caught " + c); + e.printStackTrace(System.out); + } + } catch (Throwable e) { failures++; - System.out.println("FAIL: Unexpected exception has been caught " + e); + System.out.println("FAIL: Exception from MethodHandle invocation not wrapped in BootstrapMethodError " + e); e.printStackTrace(System.out); - } } System.out.println(); try { diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java --- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Thu Jun 04 15:38:00 2015 -0700 @@ -21,25 +21,29 @@ * questions. */ -/* - * @test - * @bug 8042397 - * @summary Unit test for jmap utility test heap configuration reader - * @library /lib/testlibrary - * @modules java.management - * @build jdk.testlibrary.* - * @build JMapHeapConfigTest LingeredApp TmtoolTestScenario - * @run main JMapHeapConfigTest - */ import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; + +import jdk.test.lib.apps.LingeredApp; import jdk.testlibrary.Utils; import jdk.testlibrary.Platform; +/* + * @test + * @bug 8042397 + * @summary Unit test for jmap utility test heap configuration reader + * @library /../../test/lib/share/classes + * @library /lib/testlibrary + * @modules java.management + * @build jdk.testlibrary.* + * @build jdk.test.lib.apps.* + * @build JMapHeapConfigTest TmtoolTestScenario + * @run main JMapHeapConfigTest + */ public class JMapHeapConfigTest { static final String expectedJMapValues[] = { diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java --- a/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java Thu Jun 04 19:28:45 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * This is a framework to launch an app that could be synchronized with caller - * to make further attach actions reliable across supported platforms - - * Caller example: - * SmartTestApp a = SmartTestApp.startApp(cmd); - * // do something - * a.stopApp(); - * - * or fine grained control - * - * a = new SmartTestApp("MyLock.lck"); - * a.createLock(); - * a.runApp(); - * a.waitAppReady(); - * // do something - * a.deleteLock(); - * a.waitAppTerminate(); - * - * Then you can work with app output and process object - * - * output = a.getAppOutput(); - * process = a.getProcess(); - * - */ -public class LingeredApp { - - private static final long spinDelay = 1000; - - private final String lockFileName; - private long lockCreationTime; - private Process appProcess; - private final ArrayList storedAppOutput; - - /* - * Drain child process output, store it into string array - */ - class InputGobbler extends Thread { - - InputStream is; - List astr; - - InputGobbler(InputStream is, List astr) { - this.is = is; - this.astr = astr; - } - - public void run() { - try { - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - String line = null; - while ((line = br.readLine()) != null) { - astr.add(line); - } - } catch (IOException ex) { - // pass - } - } - } - - /** - * Create LingeredApp object on caller side. Lock file have be a valid filename - * at writable location - * - * @param lockFileName - the name of lock file - */ - public LingeredApp(String lockFileName) { - this.lockFileName = lockFileName; - this.storedAppOutput = new ArrayList(); - } - - /** - * - * @return name of lock file - */ - public String getLockFileName() { - return this.lockFileName; - } - - /** - * - * @return name of testapp - */ - public String getAppName() { - return this.getClass().getName(); - } - - /** - * - * @return pid of java process running testapp - */ - public long getPid() { - if (appProcess == null) { - throw new RuntimeException("Process is not alive"); - } - return appProcess.getPid(); - } - - /** - * - * @return process object - */ - public Process getProcess() { - return appProcess; - } - - /** - * - * @return application output as string array. Empty array if application produced no output - */ - List getAppOutput() { - if (appProcess.isAlive()) { - throw new RuntimeException("Process is still alive. Can't get its output."); - } - return storedAppOutput; - } - - /* Make sure all part of the app use the same method to get dates, - as different methods could produce different results - */ - private static long epoch() { - return new Date().getTime(); - } - - private static long lastModified(String fileName) throws IOException { - Path path = Paths.get(fileName); - BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); - return attr.lastModifiedTime().toMillis(); - } - - private static void setLastModified(String fileName, long newTime) throws IOException { - Path path = Paths.get(fileName); - FileTime fileTime = FileTime.fromMillis(newTime); - Files.setLastModifiedTime(path, fileTime); - } - - /** - * create lock - * - * @throws IOException - */ - public void createLock() throws IOException { - Path path = Paths.get(lockFileName); - // Files.deleteIfExists(path); - Files.createFile(path); - lockCreationTime = lastModified(lockFileName); - } - - /** - * Delete lock - * - * @throws IOException - */ - public void deleteLock() throws IOException { - try { - Path path = Paths.get(lockFileName); - Files.delete(path); - } catch (NoSuchFileException ex) { - // Lock already deleted. Ignore error - } - } - - public void waitAppTerminate() { - while (true) { - try { - appProcess.waitFor(); - break; - } catch (InterruptedException ex) { - // pass - } - } - } - - /** - * The app touches the lock file when it's started - * wait while it happens. Caller have to delete lock on wait error. - * - * @param timeout - * @throws java.io.IOException - */ - public void waitAppReady(long timeout) throws IOException { - long here = epoch(); - while (true) { - long epoch = epoch(); - if (epoch - here > (timeout * 1000)) { - throw new IOException("App waiting timeout"); - } - - // Live process should touch lock file every second - long lm = lastModified(lockFileName); - if (lm > lockCreationTime) { - break; - } - - // Make sure process didn't already exit - if (!appProcess.isAlive()) { - throw new IOException("App exited unexpectedly with " + appProcess.exitValue()); - } - - try { - Thread.sleep(spinDelay); - } catch (InterruptedException ex) { - // pass - } - } - } - - /** - * Run the app - * - * @param vmArguments - * @throws IOException - */ - public void runApp(List vmArguments) - throws IOException { - - // We should always use testjava or throw an exception, - // so we can't use JDKToolFinder.getJDKTool("java"); - // that falls back to compile java on error - String jdkPath = System.getProperty("test.jdk"); - if (jdkPath == null) { - // we are not under jtreg, try env - Map env = System.getenv(); - jdkPath = env.get("TESTJAVA"); - } - - if (jdkPath == null) { - throw new RuntimeException("Can't determine jdk path neither test.jdk property no TESTJAVA env are set"); - } - - String osname = System.getProperty("os.name"); - String javapath = jdkPath + ((osname.startsWith("window")) ? "/bin/java.exe" : "/bin/java"); - - List cmd = new ArrayList(); - cmd.add(javapath); - - - if (vmArguments == null) { - // Propagate test.vm.options to LingeredApp, filter out possible empty options - String testVmOpts[] = System.getProperty("test.vm.opts","").split("\\s+"); - for (String s : testVmOpts) { - if (!s.equals("")) { - cmd.add(s); - } - } - } - else{ - // Lets user manage LingerApp options - cmd.addAll(vmArguments); - } - - // Make sure we set correct classpath to run the app - cmd.add("-cp"); - String classpath = System.getProperty("test.class.path"); - cmd.add((classpath == null) ? "." : classpath); - - cmd.add(this.getAppName()); - cmd.add(lockFileName); - - // Reporting - StringBuilder cmdLine = new StringBuilder(); - for (String strCmd : cmd) { - cmdLine.append("'").append(strCmd).append("' "); - } - - // A bit of verbosity - System.out.println("Command line: [" + cmdLine.toString() + "]"); - - ProcessBuilder pb = new ProcessBuilder(cmd); - // we don't expect any error output but make sure we are not stuck on pipe - // pb.redirectErrorStream(false); - pb.redirectError(ProcessBuilder.Redirect.INHERIT); - - appProcess = pb.start(); - - // Create pipe reader for process, and read stdin and stderr to array of strings - InputGobbler gb = new InputGobbler(appProcess.getInputStream(), storedAppOutput); - gb.start(); - } - - /** - * High level interface for test writers - */ - /** - * Factory method that creates SmartAppTest object with ready to use application - * lock name is autogenerated, wait timeout is hardcoded - * @param cmd - vm options, could be null to auto add testvm.options - * @return LingeredApp object - * @throws IOException - */ - public static LingeredApp startApp(List cmd) throws IOException { - final String lockName = UUID.randomUUID().toString() + ".lck"; - final int waitTime = 10; - - LingeredApp a = new LingeredApp(lockName); - a.createLock(); - try { - a.runApp(cmd); - a.waitAppReady(waitTime); - } catch (Exception ex) { - a.deleteLock(); - throw ex; - } - - return a; - } - - public static LingeredApp startApp() throws IOException { - return startApp(null); - } - - /** - * Delete lock file that signal app to terminate, then - * waits until app is actually terminated. - * @throws IOException - */ - public void stopApp() throws IOException { - deleteLock(); - waitAppTerminate(); - int exitcode = appProcess.exitValue(); - if (exitcode != 0) { - throw new IOException("LingeredApp terminated with non-zero exit code " + exitcode); - } - } - - /** - * LastModified time might not work correctly in some cases it might - * cause later failures - */ - - public static boolean isLastModifiedWorking() { - boolean sane = true; - try { - long lm = lastModified("."); - if (lm == 0) { - System.err.println("SANITY Warning! The lastModifiedTime() doesn't work on this system, it returns 0"); - sane = false; - } - - long now = epoch(); - if (lm > now) { - System.err.println("SANITY Warning! The Clock is wrong on this system lastModifiedTime() > getTime()"); - sane = false; - } - - setLastModified(".", epoch()); - long lm1 = lastModified("."); - if (lm1 <= lm) { - System.err.println("SANITY Warning! The setLastModified doesn't work on this system"); - sane = false; - } - } - catch(IOException e) { - System.err.println("SANITY Warning! IOException during sanity check " + e); - sane = false; - } - - return sane; - } - - /** - * This part is the application it self - */ - public static void main(String args[]) { - - if (args.length != 1) { - System.err.println("Lock file name is not specified"); - System.exit(7); - } - - String theLockFileName = args[0]; - - try { - Path path = Paths.get(theLockFileName); - - while (Files.exists(path)) { - // Touch the lock to indicate our readiness - setLastModified(theLockFileName, epoch()); - Thread.sleep(spinDelay); - } - } catch (NoSuchFileException ex) { - // Lock deleted while we are setting last modified time. - // Ignore error and lets the app exits - } catch (Exception ex) { - System.err.println("LingeredApp ERROR: " + ex); - // Leave exit_code = 1 to Java launcher - System.exit(3); - } - - System.exit(0); - } -} diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java --- a/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java Thu Jun 04 19:28:45 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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 - * @summary Unit test for LingeredApp - * @compile LingeredAppTest.java - * @compile LingeredApp.java - * @run main LingeredAppTest - */ -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -public class LingeredAppTest { - - public static void main(String[] args) { - try { - System.out.println("Starting LingeredApp with default parameters"); - - ArrayList cmd = new ArrayList(); - - // Propagate test.vm.options to LingeredApp, filter out possible empty options - String testVmOpts[] = System.getProperty("test.vm.opts","").split("\\s+"); - for (String s : testVmOpts) { - if (!s.equals("")) { - cmd.add(s); - } - } - - cmd.add("-XX:+PrintFlagsFinal"); - - LingeredApp a = LingeredApp.startApp(cmd); - System.out.printf("App pid: %d\n", a.getPid()); - a.stopApp(); - - System.out.println("App output:"); - int count = 0; - for (String line : a.getAppOutput()) { - count += 1; - } - System.out.println("Found " + count + " lines in VM output"); - System.out.println("Test PASSED"); - } catch (IOException ex) { - ex.printStackTrace(); - System.out.println("Test ERROR"); - System.exit(3); - } - } -} diff -r a832d39b95a0 -r 6cf349c0d1a5 jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java --- a/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java Thu Jun 04 19:28:45 2015 +0100 +++ b/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java Thu Jun 04 15:38:00 2015 -0700 @@ -31,6 +31,8 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; + +import jdk.test.lib.apps.LingeredApp; import jdk.testlibrary.JDKToolLauncher; import jdk.testlibrary.Utils;