This commit is contained in:
Alejandro Murillo 2016-10-20 16:54:00 -07:00
commit ae7aae8464
8 changed files with 183 additions and 37 deletions

View File

@ -0,0 +1,34 @@
# Copyright (c) 2011, 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. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# 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.
#
# List of JVMs that can be used as an option to java, javac, etc.
# Order is important -- first in this list is the default JVM.
# NOTE that this both this file and its format are UNSUPPORTED and
# WILL GO AWAY in a future release.
#
# You may also select a JVM in an arbitrary location with the
# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
# and may not be available in a future release.
#
-server KNOWN
-client IGNORE

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -246,9 +246,9 @@ public interface ObjectReference extends Value {
* @throws java.lang.IllegalArgumentException if the method is not * @throws java.lang.IllegalArgumentException if the method is not
* a member of this object's class, if the size of the argument list * a member of this object's class, if the size of the argument list
* does not match the number of declared arguments for the method, * does not match the number of declared arguments for the method,
* if the method is a constructor or static intializer, or * if the method is a constructor or static initializer, or
* if {@link #INVOKE_NONVIRTUAL} is specified and the method is * if {@link #INVOKE_NONVIRTUAL} is specified and the method is
* either abstract or a non-default interface member. * abstract.
* @throws {@link InvalidTypeException} if any argument in the * @throws {@link InvalidTypeException} if any argument in the
* argument list is not assignable to the corresponding method argument * argument list is not assignable to the corresponding method argument
* type. * type.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -347,10 +347,12 @@ public class ObjectReferenceImpl extends ValueImpl
throws InvalidTypeException, throws InvalidTypeException,
InvocationException { InvocationException {
/* /*
* Only default methods allowed for nonvirtual invokes * For nonvirtual invokes, method must have a body
*/ */
if (isNonVirtual(options) && !method.isDefault()) { if (isNonVirtual(options)) {
throw new IllegalArgumentException("Not a default method"); if (method.isAbstract()) {
throw new IllegalArgumentException("Abstract method");
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,7 +32,6 @@ module jdk.jdi {
exports com.sun.jdi.connect.spi; exports com.sun.jdi.connect.spi;
exports com.sun.jdi.event; exports com.sun.jdi.event;
exports com.sun.jdi.request; exports com.sun.jdi.request;
exports com.sun.tools.jdi to jdk.hotspot.agent;
uses com.sun.jdi.connect.Connector; uses com.sun.jdi.connect.Connector;
uses com.sun.jdi.connect.spi.TransportService; uses com.sun.jdi.connect.spi.TransportService;

View File

@ -134,8 +134,6 @@ java/lang/instrument/RetransformBigClass.sh 8065756 generic-
java/lang/instrument/BootClassPath/BootClassPathTest.sh 8072130 macosx-all java/lang/instrument/BootClassPath/BootClassPathTest.sh 8072130 macosx-all
java/lang/instrument/DaemonThread/TestDaemonThread.java 8167001 generic-all
java/lang/management/MemoryMXBean/Pending.java 8158837 generic-all java/lang/management/MemoryMXBean/Pending.java 8158837 generic-all
java/lang/management/MemoryMXBean/PendingAllGC.sh 8158760 generic-all java/lang/management/MemoryMXBean/PendingAllGC.sh 8158760 generic-all

View File

@ -25,7 +25,8 @@
* @test * @test
* @bug 8031195 * @bug 8031195
* @bug 8071657 * @bug 8071657
* @summary JDI: Add support for static and default methods in interfaces * @bug 8165827
* @summary JDI: Add support for static, private and default methods in interfaces
* *
* @modules jdk.jdi * @modules jdk.jdi
* @run build TestScaffold VMConnection TargetListener TargetAdapter * @run build TestScaffold VMConnection TargetListener TargetAdapter
@ -35,11 +36,13 @@
import com.sun.jdi.*; import com.sun.jdi.*;
import com.sun.jdi.event.*; import com.sun.jdi.event.*;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class InterfaceMethodsTest extends TestScaffold { public class InterfaceMethodsTest extends TestScaffold {
private static final int RESULT_A = 1; private static final int RESULT_A = 1;
private static final int RESULT_B = 1; private static final int RESULT_B = 2;
private static final int RESULT_TARGET = 1; private static final int RESULT_TARGET = 3;
static interface InterfaceA { static interface InterfaceA {
static int staticMethodA() { static int staticMethodA() {
@ -62,7 +65,10 @@ public class InterfaceMethodsTest extends TestScaffold {
System.out.println("-InterfaceA: default interface method C-"); System.out.println("-InterfaceA: default interface method C-");
return RESULT_A; return RESULT_A;
} }
private int privateMethodA() {
System.out.println("-InterfaceA: private interface method A-");
return RESULT_A;
}
int implementedMethod(); int implementedMethod();
} }
@ -76,16 +82,18 @@ public class InterfaceMethodsTest extends TestScaffold {
System.out.println("-InterfaceB: default interface method D-"); System.out.println("-InterfaceB: default interface method D-");
return RESULT_B; return RESULT_B;
} }
static int staticMethodB() { static int staticMethodB() {
System.out.println("-InterfaceB: overridden static interface method B-"); System.out.println("-InterfaceB: overridden static interface method B-");
return RESULT_B; return RESULT_B;
} }
static int staticMethodC() { static int staticMethodC() {
System.out.println("-InterfaceB: static interface method C-"); System.out.println("-InterfaceB: static interface method C-");
return RESULT_B; return RESULT_B;
} }
private int privateMethodB() {
System.out.println("-InterfaceB: private interface method B-");
return RESULT_B;
}
} }
final static class TargetClass implements InterfaceB { final static class TargetClass implements InterfaceB {
@ -102,7 +110,7 @@ public class InterfaceMethodsTest extends TestScaffold {
@Override @Override
public int defaultMethodB() { public int defaultMethodB() {
System.out.println("-TargetClass: overridden default interface method D"); System.out.println("-TargetClass: overridden default interface method B");
return RESULT_TARGET; return RESULT_TARGET;
} }
@ -169,9 +177,18 @@ public class InterfaceMethodsTest extends TestScaffold {
} }
private void testInterfaceA(ObjectReference ref) { private void testInterfaceA(ObjectReference ref) {
// Test non-virtual calls on InterfaceA
ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0); ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0);
/* Private method calls */
Method m = testLookup(ifaceClass, "privateMethodA", "()I", true, null); // should succeed
testInvokePos(m, ref, vm().mirrorOf(RESULT_A), false);
testInvokePos(m, ref, vm().mirrorOf(RESULT_A), true);
// Test non-virtual calls on InterfaceA
/* Default method calls */ /* Default method calls */
// invoke the InterfaceA's "defaultMethodA" // invoke the InterfaceA's "defaultMethodA"
@ -187,14 +204,13 @@ public class InterfaceMethodsTest extends TestScaffold {
testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B), testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B),
"Attempted to invoke non-existing method"); "Attempted to invoke non-existing method");
// trying to invoke the asbtract method "implementedMethod" // non-virtual invoke of the abstract method "implementedMethod" fails
testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME), testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME),
"Invocation of non-default methods is not supported"); "Invocation of abstract methods is not supported");
/* Static method calls */ /* Static method calls */
// invoke interface static method A // invoke static interface method A
testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A)); testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
// invoking static method A on the instance fails because static method A is // invoking static method A on the instance fails because static method A is
@ -202,7 +218,7 @@ public class InterfaceMethodsTest extends TestScaffold {
testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A), testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
"Invalid MethodID"); "Invalid MethodID");
// invoke interface static method B // invoke static interface method B
testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A)); testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
// invoking static method B on the instance fails because static method B is // invoking static method B on the instance fails because static method B is
@ -211,13 +227,23 @@ public class InterfaceMethodsTest extends TestScaffold {
"Invalid MethodID"); "Invalid MethodID");
// try to invoke a virtual method // try to invoke a virtual method
testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true); testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET), true);
} }
private void testInterfaceB(ObjectReference ref) { private void testInterfaceB(ObjectReference ref) {
// Test non-virtual calls on InterfaceB // Test non-virtual calls on InterfaceB
ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0); ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0);
/* private method calls */
/* These should fail but won't because of JDK-8167416
testLookup(ifaceClass, "privateMethodA", "()I", true, NoSuchMethodError.class); // should fail
testLookup(ifaceClass, "privateMethodA", "()I", false, NoSuchMethodError.class); // should fail
*/
Method m = testLookup(ifaceClass, "privateMethodB", "()I", true, null); // should succeed
testInvokePos(m, ref, vm().mirrorOf(RESULT_B), false);
testInvokePos(m, ref, vm().mirrorOf(RESULT_B), true);
/* Default method calls */ /* Default method calls */
// invoke the inherited "defaultMethodA" // invoke the inherited "defaultMethodA"
@ -267,19 +293,21 @@ public class InterfaceMethodsTest extends TestScaffold {
private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) { private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) {
// Test invocations on the implementation object // Test invocations on the implementation object
// Note: private interface calls have already been tested
/* Default method calls */ /* Default method calls */
// "defaultMethodA" is accessible and not overridden // "defaultMethodA" is accessible and not overridden
testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_TARGET)); testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
// "defaultMethodB" is accessible and overridden in TargetClass // "defaultMethodB" is accessible and overridden in TargetClass
testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET)); testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET));
// "defaultMethodC" is accessible and overridden in InterfaceB // "defaultMethodC" is accessible and overridden in InterfaceB
testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_TARGET)); testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B));
// "defaultMethodD" is accessible // "defaultMethodD" is accessible
testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_TARGET)); testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B));
/* Non-default instance method calls */ /* Non-default instance method calls */
@ -314,11 +342,16 @@ public class InterfaceMethodsTest extends TestScaffold {
"Static interface methods are not inheritable"); "Static interface methods are not inheritable");
} }
// Non-virtual invocation
private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value) { String methodSig, Value value) {
testInvokePos(targetClass, ref, methodName, methodSig, value, false); testInvokePos(targetClass, ref, methodName, methodSig, value, false);
} }
// Lookup the named method in the targetClass and invoke on the given object (for instance methods)
// using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
// expected return value.
// Should succeed.
private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, boolean virtual) { String methodSig, Value value, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass); logInvocation(ref, methodName, methodSig, targetClass);
@ -331,11 +364,31 @@ public class InterfaceMethodsTest extends TestScaffold {
} }
} }
// Invoke the given Method on the given object (for instance methods)
// using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
// expected return value.
// Should succeed.
private void testInvokePos(Method method, ObjectReference ref, Value value, boolean virtual) {
logInvocation(ref, method.name(), method.signature(), method.declaringType());
try {
invoke(method.declaringType(), ref, method, value, virtual);
System.err.println("--- PASSED");
} catch (Exception e) {
System.err.println("--- FAILED");
failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage());
}
}
// Non-virtual invocation - with lookup in targetClass
private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, String msg) { String methodSig, Value value, String msg) {
testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false); testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false);
} }
// Lookup the named method in the targetClass and invoke on the given object (for instance methods)
// using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
// expected return value.
// Should fail - with msg decribing why failure was expected
private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, String msg, boolean virtual) { String methodSig, Value value, String msg, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass); logInvocation(ref, methodName, methodSig, targetClass);
@ -350,12 +403,17 @@ public class InterfaceMethodsTest extends TestScaffold {
} }
private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName, private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, boolean virtual) String methodSig, Value value, boolean virtual) throws Exception {
throws Exception {
Method method = getMethod(targetClass, methodName, methodSig); Method method = getMethod(targetClass, methodName, methodSig);
if (method == null) { if (method == null) {
throw new Exception("Can't find method: " + methodName + " for class = " + targetClass); throw new Exception("Can't find method: " + methodName + " for class = " + targetClass);
} }
invoke(targetClass, ref, method, value, virtual);
}
private void invoke(ReferenceType targetClass, ObjectReference ref, Method method,
Value value, boolean virtual) throws Exception {
println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method); println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
println(method.declaringType().toString()); println(method.declaringType().toString());
@ -365,7 +423,7 @@ public class InterfaceMethodsTest extends TestScaffold {
if (virtual) { if (virtual) {
returnValue = invokeVirtual(ref, method); returnValue = invokeVirtual(ref, method);
} else { } else {
returnValue = invokeInstance(ref, method); returnValue = invokeNonVirtual(ref, method);
} }
} else { } else {
returnValue = invokeStatic(targetClass, method); returnValue = invokeStatic(targetClass, method);
@ -387,7 +445,7 @@ public class InterfaceMethodsTest extends TestScaffold {
} }
} }
private Value invokeInstance(ObjectReference ref, Method method) throws Exception { private Value invokeNonVirtual(ObjectReference ref, Method method) throws Exception {
return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
} }
@ -449,4 +507,58 @@ public class InterfaceMethodsTest extends TestScaffold {
methodName + methodSig); methodName + methodSig);
} }
} }
private Method testLookup(ReferenceType targetClass, String methodName, String methodSig,
boolean declaredOnly, Class<?> expectedException) {
System.err.println("Looking up " + targetClass.name() + "." + methodName + methodSig);
try {
Method m = declaredOnly ?
lookupDeclaredMethod(targetClass, methodName, methodSig) :
lookupMethod(targetClass, methodName, methodSig);
if (expectedException == null) {
System.err.println("--- PASSED");
return m;
}
else {
System.err.println("--- FAILED");
failure("FAILED: lookup succeeded but expected exception "
+ expectedException.getSimpleName());
return null;
}
}
catch (Throwable t) {
if (t.getClass() != expectedException) {
System.err.println("--- FAILED");
failure("FAILED: got exception " + t + " but expected exception "
+ expectedException.getSimpleName());
return null;
}
else {
System.err.println("--- PASSED");
return null;
}
}
}
private Method lookupMethod(ReferenceType targetClass, String methodName, String methodSig) {
List methods = targetClass.allMethods();
Iterator iter = methods.iterator();
while (iter.hasNext()) {
Method method = (Method)iter.next();
if (method.name().equals(methodName) &&
method.signature().equals(methodSig)) {
return method;
}
}
throw new NoSuchMethodError();
}
private Method lookupDeclaredMethod(ReferenceType targetClass, String methodName, String methodSig) {
Method m = findMethod(targetClass, methodName, methodSig);
if (m == null)
throw new NoSuchMethodError();
return m;
}
} }

View File

@ -29,7 +29,7 @@ import jdk.testlibrary.ProcessTools;
public class TestDaemonThreadLauncher { public class TestDaemonThreadLauncher {
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
for(int i=0; i<50; i++) { for(int i=0; i<50; i++) {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-javaagent:DummyAgent.jar", "TestDaemonThread", "."); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-javaagent:DummyAgent.jar", "TestDaemonThread", ".");
OutputAnalyzer analyzer = ProcessTools.executeProcess(pb); OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
analyzer.shouldNotContain("ASSERTION FAILED"); analyzer.shouldNotContain("ASSERTION FAILED");
analyzer.shouldHaveExitValue(0); analyzer.shouldHaveExitValue(0);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@
* @modules java.management * @modules java.management
* @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil * @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil
* @run main/timeout=600 LowMemoryTest * @run main/timeout=600 LowMemoryTest
* @requires vm.gc == "null"
* @requires vm.opt.ExplicitGCInvokesConcurrent != "true" * @requires vm.opt.ExplicitGCInvokesConcurrent != "true"
* @requires vm.opt.ExplicitGCInvokesConcurrentAndUnloadsClasses != "true" * @requires vm.opt.ExplicitGCInvokesConcurrentAndUnloadsClasses != "true"
* @requires vm.opt.DisableExplicitGC != "true" * @requires vm.opt.DisableExplicitGC != "true"