MH inlining fails for a package-private and protected calls
Paul Sandoz
paul.sandoz at oracle.com
Fri Oct 24 20:52:33 UTC 2014
Hi,
I am observing that inlining of a MH invocation to a package private method fails.
Below is a simple test that test MHs to a public, package-private and protected methods.
Using the tip of JDK 9 with "java -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining MHInlineTest" produces the following:
! @ 10 MHInlineTest::testPublicMH (24 bytes) inline (hot)
@ 7 java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes) force inline by annotation
@ 2 java.lang.invoke.Invokers::checkExactType (30 bytes) force inline by annotation
@ 11 java.lang.invoke.MethodHandle::type (5 bytes) accessor
@ 13 java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15 bytes) force inline by annotation
@ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) force inline by annotation
@ 11 MHInlineTest$B::public_x (6 bytes) inline (hot)
! @ 29 MHInlineTest::testProtectedMH (24 bytes) inline (hot)
@ 7 java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes) force inline by annotation
@ 2 java.lang.invoke.Invokers::checkExactType (30 bytes) force inline by annotation
@ 11 java.lang.invoke.MethodHandle::type (5 bytes) accessor
@ 13 java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15 bytes) force inline by annotation
@ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) force inline by annotation
@ 11 MHInlineTest$A::protected_x (6 bytes) virtual call
! @ 48 MHInlineTest::testPackageMH (24 bytes) inline (hot)
@ 7 java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes) force inline by annotation
@ 2 java.lang.invoke.Invokers::checkExactType (30 bytes) force inline by annotation
@ 11 java.lang.invoke.MethodHandle::type (5 bytes) accessor
@ 13 java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15 bytes) force inline by annotation
@ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) force inline by annotation
@ 11 MHInlineTest$A::package_x (6 bytes) virtual call
! @ 67 MHInlineTest::testPackageFinalMH (24 bytes) inline (hot)
@ 7 java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes) force inline by annotation
@ 2 java.lang.invoke.Invokers::checkExactType (30 bytes) force inline by annotation
@ 11 java.lang.invoke.MethodHandle::type (5 bytes) accessor
@ 13 java.lang.invoke.LambdaForm$DMH/344560770::invokeSpecial_LL_V (15 bytes) force inline by annotation
@ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) force inline by annotation
@ 11 MHInlineTest$A::package_final_x (6 bytes) inline (hot)
@ 86 MHInlineTest::testPackage (8 bytes) inline (hot)
@ 4 MHInlineTest$B::package_x (6 bytes) inline (hot)
Note that:
- inlining bails out for the MH to the package-private and and protected method, but does not bail out for an explicit package-protected call.
- the same LambdaForms are used for all virtual invocations.
Is that the expected behaviour?
Paul.
public class MHInlineTest {
public static class A {
volatile String s;
public void public_x(String s) {
this.s = s;
}
void protected_x(String s) {
this.s = s;
}
void package_x(String s) {
this.s = s;
}
final void package_final_x(String s) {
this.s = s;
}
}
public static final class B extends A {
volatile String s;
@Override
public void public_x(String s) {
this.s = s;
}
@Override
void protected_x(String s) {
this.s = s;
}
@Override
void package_x(String s) {
this.s = s;
}
}
static final MethodHandle A_PUBLIC_X;
static final MethodHandle A_PROTECTED_X;
static final MethodHandle A_PACKAGE_X;
static final MethodHandle A_PACKAGE_FINAL_X;
static {
try {
A_PUBLIC_X = MethodHandles.lookup().findVirtual(
A.class, "public_x", MethodType.methodType(void.class, String.class));
A_PROTECTED_X = MethodHandles.lookup().findVirtual(
A.class, "protected_x", MethodType.methodType(void.class, String.class));
A_PACKAGE_X = MethodHandles.lookup().findVirtual(
A.class, "package_x", MethodType.methodType(void.class, String.class));
A_PACKAGE_FINAL_X = MethodHandles.lookup().findVirtual(
A.class, "package_final_x", MethodType.methodType(void.class, String.class));
}
catch (Exception e) {
throw new Error(e);
}
}
static final A a = new B();
public static void main(String[] args) {
for (int i = 0; i < 1000_0000; i++) {
testPublicMH("X");
}
for (int i = 0; i < 1000_0000; i++) {
testProtectedMH("X");
}
for (int i = 0; i < 1000_0000; i++) {
testPackageMH("X");
}
for (int i = 0; i < 1000_0000; i++) {
testPackageFinalMH("X");
}
for (int i = 0; i < 1000_0000; i++) {
testPackage("X");
}
System.out.println("END");
}
private static void testPublicMH(String x) {
try {
A_PUBLIC_X.invokeExact(a, x);
}
catch (Throwable throwable) {
throw new Error(throwable);
}
}
private static void testProtectedMH(String x) {
try {
A_PROTECTED_X.invokeExact(a, x);
}
catch (Throwable throwable) {
throw new Error(throwable);
}
}
private static void testPackageMH(String x) {
try {
A_PACKAGE_X.invokeExact(a, x);
}
catch (Throwable throwable) {
throw new Error(throwable);
}
}
private static void testPackageFinalMH(String x) {
try {
A_PACKAGE_FINAL_X.invokeExact(a, x);
}
catch (Throwable throwable) {
throw new Error(throwable);
}
}
private static void testPackage(String x) {
a.package_x(x);
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 841 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20141024/f8bbda05/signature.asc>
More information about the hotspot-compiler-dev
mailing list