8226956: Add invocation tests for Graal and C1

Add new tests for these JIT's

Reviewed-by: lfoltan, coleenp
This commit is contained in:
Harold Seigel 2019-07-02 13:20:27 -04:00
parent 4902fc723a
commit 72bb0855ad
7 changed files with 181 additions and 32 deletions
test/hotspot/jtreg/runtime/InvocationTests

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019, 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
* @bug 8226956
* @summary Run invocation tests against C1 compiler
* @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
* shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
* shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
* @compile invokespecial/Checker.java invokespecial/ClassGenerator.java invokespecial/Generator.java
* invokevirtual/Checker.java invokevirtual/ClassGenerator.java invokevirtual/Generator.java
* invokeinterface/Checker.java invokeinterface/ClassGenerator.java invokeinterface/Generator.java
*
* @run main/othervm/timeout=1800 invocationC1Tests
*/
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.compiler.InMemoryJavaCompiler;
public class invocationC1Tests {
public static void runTest(String whichTests, String classFileVersion) throws Exception {
System.out.println("\nC1 invocation tests, Tests: " + whichTests +
", class file version: " + classFileVersion);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M",
"-Xcomp", "-XX:TieredStopAtLevel=1", whichTests,
"--classfile_version=" + classFileVersion);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
try {
output.shouldContain("EXECUTION STATUS: PASSED");
output.shouldHaveExitValue(0);
} catch (Throwable e) {
System.out.println(
"\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
" the test case failed because method B.m was invoked but the test " +
"expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
" means that an AbstractMethodError exception was thrown but the test" +
" case expected method C.m to be invoked.");
System.out.println(
"\nAlso note that passing --dump to invoke*.Generator will" +
" dump the generated classes (for debugging purposes).\n");
System.exit(1);
}
}
public static void main(String args[]) throws Throwable {
// Get current major class file version and test with it.
byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
int major_version = klassbuf[6] << 8 | klassbuf[7];
runTest("invokespecial.Generator", String.valueOf(major_version));
runTest("invokeinterface.Generator", String.valueOf(major_version));
// Uncomment this test once JDK-8226588 is fixed
// runTest("invokevirtual.Generator", String.valueOf(major_version));
}
}

@ -0,0 +1,81 @@
/*
* Copyright (c) 2019, 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
* @bug 8226956
* @requires vm.jvmci
* @summary Run invocation tests against Graal compiler
* @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
* shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
* shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
* @compile invokespecial/Checker.java invokespecial/ClassGenerator.java invokespecial/Generator.java
* invokevirtual/Checker.java invokevirtual/ClassGenerator.java invokevirtual/Generator.java
* invokeinterface/Checker.java invokeinterface/ClassGenerator.java invokeinterface/Generator.java
*
* @run main/othervm/timeout=1800 invocationGraalTests
*/
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.compiler.InMemoryJavaCompiler;
public class invocationGraalTests {
public static void runTest(String whichTests, String classFileVersion) throws Exception {
System.out.println("\nGraal invocation tests, Tests: " + whichTests +
", class file version: " + classFileVersion);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M",
"-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:+UseJVMCICompiler",
whichTests, "--classfile_version=" + classFileVersion);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
try {
output.shouldContain("EXECUTION STATUS: PASSED");
output.shouldHaveExitValue(0);
} catch (Throwable e) {
System.out.println(
"\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
" the test case failed because method B.m was invoked but the test " +
"expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
" means that an AbstractMethodError exception was thrown but the test" +
" case expected method C.m to be invoked.");
System.out.println(
"\nAlso note that passing --dump to invoke*.Generator will" +
" dump the generated classes (for debugging purposes).\n");
System.exit(1);
}
}
public static void main(String args[]) throws Throwable {
// Get current major class file version and test with it.
byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
int major_version = klassbuf[6] << 8 | klassbuf[7];
runTest("invokevirtual.Generator", String.valueOf(major_version));
runTest("invokespecial.Generator", String.valueOf(major_version));
runTest("invokeinterface.Generator", String.valueOf(major_version));
}
}

@ -67,15 +67,13 @@ public class Checker extends shared.Checker {
int modifiers = method.getModifiers();
// Check whether obtained method is public and isn't abstract
if ( Modifier.isPublic(modifiers))
{
if ( Modifier.isPublic(modifiers)) {
if (Modifier.isAbstract(modifiers)) {
return "java.lang.AbstractMethodError";
} else {
return String.format("%s.%s"
, method.getDeclaringClass().getSimpleName()
, methodName
);
return String.format("%s.%s",
method.getDeclaringClass().getSimpleName(),
methodName);
}
} else {
// IAE is thrown when located method isn't PUBLIC

@ -34,16 +34,12 @@ public class Checker extends shared.Checker {
}
public String check (Class callerClass) {
/*
* If objectref is null, the invokespecial instruction throws a NullPointerException.
*/
// If objectref is null, the invokespecial instruction throws a NullPointerException.
if (dynamicTargetClass == null) {
return "java.lang.NullPointerException";
}
/*
* TODO: find a citiation from spec for this case
*/
// TODO: find a citation from spec for this case
Method resolvedMethod;
try {
// May throw VerifyError
@ -56,15 +52,13 @@ public class Checker extends shared.Checker {
return "java.lang.NoSuchMethodError";
}
/*
* If:
* - the resolved method is protected (4.7)
* - it is a member of a superclass of the current class
* - the method is not declared in the same run-time package (5.3) as the current class
* then:
* the class of objectref must be either the current class or a subclass of the
* current class.
*/
// If:
// - the resolved method is protected (4.7)
// - it is a member of a superclass of the current class
// - the method is not declared in the same run-time package (5.3) as the current class
// then:
// the class of objectref must be either the current class or a subclass of the
// current class.
if (Modifier.isProtected(resolvedMethod.getModifiers())) {
Method methodInSuperclass = getMethodInHierarchy(resolvedMethod.getDeclaringClass().getSuperclass());

@ -88,7 +88,7 @@ public class Checker extends shared.Checker {
return null;
}
// Dynamic target doesn't have desired method, so check it's superclass
// Dynamic target doesn't have desired method, so check its superclass
if (dynamicTargetMethod == null) {
return getOverriddenMethod(staticTarget, dynamicTarget.getSuperclass());
} else {
@ -109,11 +109,9 @@ public class Checker extends shared.Checker {
String staticTargetPkg = getClassPackageName(staticTarget);
String dynamicTargetPkg = getClassPackageName(dynamicTarget);
if ( isPublic || isProtected
|| ( !isPublic && !isProtected && !isPrivate
&& staticTargetPkg.equals(dynamicTargetPkg)
))
{
if (isPublic || isProtected
|| (!isPublic && !isProtected && !isPrivate
&& staticTargetPkg.equals(dynamicTargetPkg))) {
return dynamicTargetMethod;
}
}

@ -31,9 +31,6 @@ import java.util.Map;
import java.util.List;
import java.util.ArrayList;
/**
*
*/
public abstract class AbstractGenerator {
protected final boolean dumpClasses;
protected final boolean executeTests;

@ -26,8 +26,7 @@ package shared;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
/**
*
/*
* @author vi158347
*/
public class AccessCheck {