Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/StaticMethodsTest.java
41159 views
/*1* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25*26* @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open27* @library /vmTestbase /test/lib28*29* @comment build retransform.jar in current dir30* @run driver vm.runtime.defmeth.shared.BuildJar31*32* @run driver jdk.test.lib.FileInstaller . .33* @run main/othervm/native34* -agentlib:redefineClasses35* -javaagent:retransform.jar36* vm.runtime.defmeth.StaticMethodsTest37*/38package vm.runtime.defmeth;3940import java.util.Set;4142import vm.runtime.defmeth.shared.DefMethTest;43import vm.runtime.defmeth.shared.data.*;44import vm.runtime.defmeth.shared.builder.TestBuilder;45import vm.runtime.defmeth.shared.annotation.NotApplicableFor;4647import static jdk.internal.org.objectweb.asm.Opcodes.*;48import static vm.runtime.defmeth.shared.data.method.body.CallMethod.Invoke.*;49import static vm.runtime.defmeth.shared.data.method.body.CallMethod.IndexbyteOp.*;50import static vm.runtime.defmeth.shared.ExecutionMode.*;5152/*53* Scenarios on static methods in interfaces.54*/55public class StaticMethodsTest extends DefMethTest {5657public static void main(String[] args) {58DefMethTest.runTest(StaticMethodsTest.class,59/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),60/* flags */ Set.of(0, ACC_SYNCHRONIZED),61/* redefine */ Set.of(false, true),62/* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY));63}6465// static method in interface66/*67* testStaticMethod68*69* interface I {70* default static public int m() { return 1; }71* }72*73* class C implements I {}74*/75public void testStaticMethod(TestBuilder b) {76Interface I = b.intf("I")77.defaultMethod("m", "()I")78.static_().public_().returns(1).build()79.build();8081ConcreteClass C = b.clazz("C").implement(I).build();8283b.test().staticCallSite(I, "m", "()I").returns(1).done();84b.test().staticCallSite(C, "m", "()I").throws_(NoSuchMethodError.class).done();85}8687// invoke[virtual|interface|special] from same/subintf88/*89* testInvokeVirtual90*91* interface I {92* default static public int staticM() { return 1; }93* default public int m() { return ((I)this).staticM(); }94* }95*96* class C implements I {}97*/98public void testInvokeVirtual(TestBuilder b) {99Interface I = b.intf("I")100.defaultMethod("staticM", "()I")101.static_().public_().returns(1).build()102103// force an invokevirtual MR of staticM()104.defaultMethod("m", "()I")105.invoke(VIRTUAL, b.intfByName("I"), null, "staticM", "()I", METHODREF).build()106.build();107108ConcreteClass C = b.clazz("C").implement(I).build();109110b.test().staticCallSite(I, "staticM", "()I").returns(1).done();111112b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();113b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();114}115116/*117* testInvokeIntf118*119* interface I {120* default static public int staticM() { return 1; }121* default public int m() { return ((I)this).staticM(); }122* }123*124* class C implements I {}125*/126public void testInvokeIntf(TestBuilder b) {127Interface I = b.intf("I")128.defaultMethod("staticM", "()I")129.static_().public_().returns(1).build()130131.defaultMethod("m", "()I")132.invoke(INTERFACE, b.intfByName("I"), null, "staticM", "()I", CALLSITE).build()133.build();134135ConcreteClass C = b.clazz("C").implement(I).build();136137b.test().staticCallSite(I, "staticM", "()I").returns(1).done();138139b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();140b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();141}142143/*144* testInvokeSpecial145*146* interface I {147* default static public int staticM() { return 1; }148* default public int m() { return I.super.staticM(); }149* }150*151* class C implements I {}152*/153public void testInvokeSpecial(TestBuilder b) {154Interface I = b.intf("I")155.defaultMethod("staticM", "()I")156.static_().public_().returns(1).build()157158.defaultMethod("m", "()I")159.invoke(SPECIAL, b.intfByName("I"), null, "staticM", "()I", CALLSITE).build()160.build();161162ConcreteClass C = b.clazz("C").implement(I).build();163164b.test().staticCallSite(I, "staticM", "()I").returns(1).done();165166b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();167b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();168}169170/*171* testStaticVsDefault172*173* interface I {174* default static public int m() { return 1; }175* default public int m() { return 2; }176* }177*178* class C implements I {}179*/180public void testStaticVsDefault(TestBuilder b) {181Interface I = b.intf("I")182.defaultMethod("m", "()I")183.static_().public_().returns(1).build()184.defaultMethod("m", "()I")185.public_().returns(2).build()186.build();187188ConcreteClass C = b.clazz("C").implement(I).build();189190b.test().staticCallSite(I, "m", "()I").throws_(ClassFormatError.class).done();191192// FIXME: throws exception during an attempt to lookup Test2.test() method193194// Invalid test. ClassFormatError is thrown at verification time, rather195// than execution time.196// .test().callSite(I, C, "m", "()I").throws_(ClassFormatError.class).done()197b.test().callSite(C, C, "m", "()I").throws_(ClassFormatError.class).done();198}199200// call static method from default method201/*202* testInvokeFromDefaultMethod203*204* interface I {205* default static public int staticPublicM() { return 1; }206* default public int invokePublic() { return I.staticPublicM(); }207* default static private int staticPrivateM() { return 1; }208* default public int invokePrivate() { return I.staticPrivateM(); }209* }210*211* class C implements I {}212*/213public void testInvokeFromDefaultMethod(TestBuilder b) {214Interface I = b.intf("I")215.defaultMethod("staticPublicM", "()I")216.static_().public_().returns(1).build()217.defaultMethod("invokePublic", "()I")218.invokeStatic(b.intfByName("I"), "staticPublicM", "()I").build()219220.defaultMethod("staticPrivateM", "()I")221.static_().private_().returns(1).build()222.defaultMethod("invokePrivate", "()I")223.invokeStatic(b.intfByName("I"), "staticPrivateM", "()I").build()224.build();225226ConcreteClass C = b.clazz("C").implement(I).build();227228// call static method from another class229b.test().staticCallSite(I, "staticPublicM", "()I").returns(1).done()230231.test().callSite(I, "staticPrivateM", "()I", ACC_STATIC | ACC_PRIVATE).throws_(IllegalAccessError.class).done()232233// call public static method from default method234.test().callSite(I, C, "invokePublic", "()I").returns(1).done()235.test().callSite(C, C, "invokePublic", "()I").returns(1).done()236237// call private static method from default method238.test().callSite(I, C, "invokePrivate", "()I").returns(1).done()239.test().callSite(C, C, "invokePrivate", "()I").returns(1).done();240}241242// call static method from implementing subclass243/*244* testInvokeFromSubclass245*246* interface I {247* default static public int staticPublicM() { return 1; }248* default static private int staticPrivateM() { return 1; }249* }250*251* class C implements I {252* public int invokePublic() { return I.staticPublicM(); }253* public int invokePrivate() { return I.staticPublicM(); }254*255* I.staticPublicM(); ==> returns 1;256* I.staticPrivateM(); ==> Either NSME or IAE depending on execution mode257* C c = new C(); c.invokePublic(); ==> returns 1 or if -ver < 52 IAE or VerifyError258* C c = new C(); c.invokePrivate() ==> IAE or if -ver < 52, IAE or VerifyError259* }260*/261@NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading262public void testInvokeFromSubclass(TestBuilder b) {263Interface I = b.intf("I")264.defaultMethod("staticPublicM", "()I")265.static_().public_().returns(1).build()266267.defaultMethod("staticPrivateM", "()I")268.static_().private_().returns(1).build()269.build();270271ConcreteClass C = b.clazz("C").implement(I)272.concreteMethod("invokePublic", "()I")273.invokeStatic(b.intfByName("I"), "staticPublicM", "()I").build()274.concreteMethod("invokePrivate", "()I")275.invokeStatic(b.intfByName("I"), "staticPrivateM", "()I").build()276.build();277278// call static method from another class279b.test().staticCallSite(I, "staticPublicM", "()I").returns(1).done()280.test().callSite(I, "staticPrivateM", "()I", ACC_STATIC | ACC_PRIVATE).throws_(IllegalAccessError.class).done();281282// call static method from implementing subclass283if (factory.getVer() >=52) {284b.test().callSite(C, C, "invokePublic", "()I").returns(1).done()285.test().callSite(C, C, "invokePrivate", "()I").throws_(IllegalAccessError.class).done();286} else {287// invokestatic IMR - not supported for ver < 52288b.test().callSite(C, C, "invokePublic", "()I").throws_(VerifyError.class).done()289.test().callSite(C, C, "invokePrivate", "()I").throws_(VerifyError.class).done();290}291}292293// static method doesn't participate in default method analysis:294// method overriding295/*296* testNotInherited297*298* interface I {299* default static public int m() { return 1; }300* }301*302* class C implements I {}303*/304public void testNotInherited(TestBuilder b) {305Interface I = b.intf("I")306.defaultMethod("m", "()I")307.static_().public_().returns(1).build()308.build();309310ConcreteClass C = b.clazz("C").implement(I).build();311312b.test().staticCallSite(I, "m", "()I").returns(1).done();313314b.test().callSite(C, C, "m", "()I").throws_(NoSuchMethodError.class).done();315316if (factory.getExecutionMode().equals("REFLECTION")) {317b.test().callSite(I, C, "m", "()I").returns(1).done();318} else {319// invokeinterface to static method ==> ICCE320b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();321}322}323324/*325* testDefaultVsConcrete326*327* interface I {328* default static public int m() { return 1; }329* }330*331* class C implements I {332* public int m() { return 2; }333* }334* TEST: I o = new C(); o.m()I throws ICCE335* TEST: C o = new C(); o.m()I == 2336*/337public void testDefaultVsConcrete(TestBuilder b) {338Interface I = b.intf("I")339.defaultMethod("m", "()I")340.static_().public_().returns(1).build()341.build();342343ConcreteClass C = b.clazz("C").implement(I)344.concreteMethod("m", "()I").returns(2).build()345.build();346347if (factory.getExecutionMode().equals("REFLECTION")) {348b.test().callSite(I, C, "m", "()I").returns(1).done();349} else {350// invokeinterface to static method ==> ICCE351b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();352}353354b.test().callSite(C, C, "m", "()I").returns(2).done();355}356357/*358* TEST: StaticMethodsTest.testOverrideStatic359*360* interface I {361* default static public int m() { return 1; }362* }363*364* interface J extends I {365* default public int m() { return 2; }366* }367*368* class C implements J {369* }370*/371public void testOverrideStatic(TestBuilder b) {372Interface I = b.intf("I")373.defaultMethod("m", "()I")374.static_().public_().returns(1).build()375.build();376377Interface J = b.intf("J").extend(I)378.defaultMethod("m", "()I")379.returns(2).build()380.build();381382ConcreteClass C = b.clazz("C").implement(J).build();383384b.test().staticCallSite(I, "m", "()I").returns(1).done();385386b.test().callSite(J, C, "m", "()I").returns(2).done();387b.test().callSite(C, C, "m", "()I").returns(2).done();388389if (factory.getExecutionMode().equals("REFLECTION")) {390b.test().callSite(I, C, "m", "()I").returns(1).done();391} else {392b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();393}394}395396/*397* testOverrideDefault398*399* interface I {400* default public int m() { return 1; }401* }402*403* interface J extends I {404* default static public int m() { return 2; }405* }406*407* class C implements J {}408*409* TEST: I o = new C(); o.m()I == 1410* TEST: J o = new C(); o.m()I == ICCE411* TEST: C o = new C(); o.m()I == 1412*/413public void testOverrideDefault(TestBuilder b) {414Interface I = b.intf("I")415.defaultMethod("m", "()I")416.returns(1).build()417.build();418419Interface J = b.intf("J").extend(I)420.defaultMethod("m", "()I")421.static_().public_().returns(2).build()422.build();423424ConcreteClass C = b.clazz("C").implement(J).build();425426b.test().callSite(I, C, "m", "()I").returns(1).done();427b.test().callSite(C, C, "m", "()I").returns(1).done();428429if (factory.getExecutionMode().equals("REFLECTION")) {430// Reflection correctly finds the static method defined in J and431// calls it with invokestatic.432b.test().callSite(J, C, "m", "()I").returns(2).done();433} else {434b.test().callSite(J, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();435}436}437438/*439* testReabstract440*441* interface I {442* default static public int m() { return 1; }443* }444*445* interface J extends I {446* abstract public int m();447* }448*449* class C implements J {}450*451* TEST: I o = new C(); o.m()I throws ICCE452* -mode reflect returns 1453* TEST: J o = new C(); o.m()I throws AME454* TEST: C o = new C(); o.m()I throws AME455*/456public void testReabstract(TestBuilder b) {457Interface I = b.intf("I")458.defaultMethod("m", "()I")459.static_().public_().returns(1).build()460.build();461462Interface J = b.intf("J").extend(I)463.abstractMethod("m", "()I").build()464.build();465466ConcreteClass C = b.clazz("C").implement(J).build();467468if (factory.getExecutionMode().equals("REFLECTION")) {469b.test().callSite(I, C, "m", "()I").returns(1).done();470} else {471b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();472}473474b.test().callSite(J, C, "m", "()I").throws_(AbstractMethodError.class).done();475b.test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done();476}477478/*479* testOverrideAbstract480*481* interface I {482* abstract public int m();483* }484*485* interface J extends I {486* default static public int m() { return 1; }487* }488*489* class C implements J {}490*491* TEST: I o = new C(); o.m()I throws AME492* TEST: J o = new C(); o.m()I throws ICCE493* -mode reflect returns 1494* TEST: C o = new C(); o.m()I throws AME495*/496public void testOverrideAbstract(TestBuilder b) {497Interface I = b.intf("I")498.abstractMethod("m", "()I").build()499.build();500501Interface J = b.intf("J").extend(I)502.defaultMethod("m", "()I")503.static_().public_().returns(1).build()504.build();505506ConcreteClass C = b.clazz("C").implement(J).build();507508b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done();509b.test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done();510511if (factory.getExecutionMode().equals("REFLECTION")) {512b.test().callSite(J, C, "m", "()I").returns(1).done();513} else {514b.test().callSite(J, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();515}516}517518/*519* testInheritedDefault520*521* interface I {522* default static public int m() { return 1; }523* }524*525* class B implements I {}526*527* class C extends B {}528*529* TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError530* -mode reflect returns 1531* TEST: B o = new C(); o.m()I throws NoSuchMethodError532* TEST: C o = new C(); o.m()I throws NoSuchMethodError533*/534public void testInheritedDefault(TestBuilder b) {535Interface I = b.intf("I")536.defaultMethod("m", "()I")537.static_().public_().returns(1).build()538.build();539540ConcreteClass B = b.clazz("B").implement(I).build();541ConcreteClass C = b.clazz("C").extend(B).build();542543b.test().callSite(B, C, "m","()I").throws_(NoSuchMethodError.class).done();544b.test().callSite(C, C, "m","()I").throws_(NoSuchMethodError.class).done();545546if (factory.getExecutionMode().equals("REFLECTION")) {547b.test().callSite(I, C, "m","()I").returns(1).done();548} else {549b.test().callSite(I, C, "m","()I").throws_(IncompatibleClassChangeError.class).done();550}551}552553/*554* testDefaultVsConcreteInherited555*556* interface I {557* default static public int m() { return 1; }558* }559*560* class B {561* public int m() { return 2; }562* }563*564* class C extends B implements I {}565*566*/567public void testDefaultVsConcreteInherited(TestBuilder b) {568Interface I = b.intf("I")569.defaultMethod("m", "()I")570.static_().public_().returns(1).build()571.build();572573ConcreteClass B = b.clazz("B")574.concreteMethod("m", "()I").returns(2).build()575.build();576577ConcreteClass C = b.clazz("C").extend(B).implement(I).build();578579b.test().staticCallSite(I, "m","()I").returns(1).done();580581b.test().callSite(B, C, "m","()I").returns(2).done();582b.test().callSite(C, C, "m","()I").returns(2).done();583584if (factory.getExecutionMode().equals("REFLECTION")) {585b.test().callSite(I, C, "m","()I").returns(1).done();586} else {587b.test().callSite(I, C, "m","()I").throws_(IncompatibleClassChangeError.class).done();588}589}590591/*592* testDefaultVsStaticConflict593*594* interface I {595* default static public int m() { return 1; }596* }597*598* interface J {599* default public int m() { return 2; }600* }601*602* class C implements I, J {}603*604* TEST: I o = new C(); o.m()I throws ICCE605* -mode reflect returns 1606* TEST: J o = new C(); o.m()I == 2607* TEST: C o = new C(); o.m()I == 2608*/609public void testDefaultVsStaticConflict(TestBuilder b) {610Interface I = b.intf("I")611.defaultMethod("m", "()I")612.static_().public_().returns(1).build()613.build();614615Interface J = b.intf("J")616.defaultMethod("m", "()I").returns(2).build()617.build();618619ConcreteClass C = b.clazz("C").implement(I,J).build();620621b.test().callSite(J, C, "m", "()I").returns(2).done();622b.test().callSite(C, C, "m", "()I").returns(2).done();623624if (factory.getExecutionMode().equals("REFLECTION")) {625b.test().callSite(I, C, "m", "()I").returns(1).done();626} else {627b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();628}629}630631/*632* testStaticSuperClassVsDefaultSuperInterface633*634* interface I {635* default public int m() { return 1; }636* }637*638* class A {639* public static int m() { return 2; }640* }641*642* class C extends A implements I {}643*644* TEST: C o = new C(); o.m()I throws ICCE645* -mode reflect returns 2646* TEST: I o = new C(); o.m()I == 1647*/648public void testStaticSuperClassVsDefaultSuperInterface(TestBuilder b) {649Interface I = b.intf("I")650.defaultMethod("m", "()I")651.public_().returns(1).build()652.build();653654ConcreteClass A = b.clazz("A")655.concreteMethod("m", "()I")656.static_().public_().returns(2).build()657.build();658659ConcreteClass C = b.clazz("C").extend(A).implement(I).build();660661b.test().callSite(I, C, "m", "()I").returns(1).done();662663if (factory.getExecutionMode().equals("REFLECTION")) {664b.test().callSite(C, C, "m", "()I").returns(2).done();665} else {666b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();667}668}669670/*671* testStaticLocalVsDefaultSuperInterface672*673* interface I {674* default public int m() { return 1; }675* }676*677* class A implements I {678* public static int m() { return 2; }679* }680*681* class C extends A implements I {}682*683* TEST: A o = new A(); o.m()I throws ICCE684* -mode reflect returns 2685* TEST: I o = new A(); o.m()I == 1686*/687public void testStaticLocalVsDefaultSuperInterface(TestBuilder b) {688Interface I = b.intf("I")689.defaultMethod("m", "()I")690.public_().returns(1).build()691.build();692693ConcreteClass A = b.clazz("A").implement(I)694.concreteMethod("m", "()I")695.static_().public_().returns(2).build()696.build();697698ConcreteClass C = b.clazz("C").extend(A).implement(I).build();699700b.test().callSite(I, A, "m", "()I").returns(1).done();701b.test().callSite(I, C, "m", "()I").returns(1).done();702703if (factory.getExecutionMode().equals("REFLECTION")) {704b.test().callSite(A, A, "m", "()I").returns(2).done();705b.test().callSite(C, C, "m", "()I").returns(2).done();706} else {707b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();708b.test().callSite(A, A, "m", "()I").throws_(IncompatibleClassChangeError.class).done();709}710}711712/*713* testConflictingDefaultsandStaticMethod714* @bug 8033150715*716* interface I {717* default public int m() { return 1; }718* }719*720* interface J {721* default public int m() { return 2; }722* }723*724* class A implements I, J {725* public static int m() { return 3; }726* }727*728* class C extends A {}729*730* TEST: C.m(); should call A.m, return value = 3731*/732public void testConflictingDefaultsandStaticMethod(TestBuilder b) {733Interface I = b.intf("I")734.defaultMethod("m", "()I")735.public_().returns(1).build()736.build();737738Interface J = b.intf("J")739.defaultMethod("m", "()I")740.public_().returns(2).build()741.build();742743ConcreteClass A = b.clazz("A").implement(I,J)744.concreteMethod("m", "()I")745.static_().public_().returns(3).build()746.build();747748ConcreteClass C = b.clazz("C").extend(A).build();749750b.test().staticCallSite(C, "m", "()I").returns(3).done();751}752}753754755