Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/RedefineTest.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.RedefineTest37*/38package vm.runtime.defmeth;3940import java.util.HashMap;41import java.util.List;42import java.util.Map;43import java.util.Set;4445import nsk.share.Pair;46import vm.runtime.defmeth.shared.DefMethTest;47import vm.runtime.defmeth.shared.DefMethTestFailure;48import vm.runtime.defmeth.shared.MemoryClassLoader;49import vm.runtime.defmeth.shared.annotation.NotApplicableFor;50import vm.runtime.defmeth.shared.builder.TestBuilder;51import vm.runtime.defmeth.shared.executor.TestExecutor;52import vm.runtime.defmeth.shared.data.Clazz;53import vm.runtime.defmeth.shared.data.ConcreteClass;54import vm.runtime.defmeth.shared.data.Interface;55import vm.runtime.defmeth.shared.data.Tester;5657import static jdk.internal.org.objectweb.asm.Opcodes.*;58import static vm.runtime.defmeth.shared.ExecutionMode.*;5960/*61* Basic scenarios on class redefinition.62*/63public class RedefineTest extends DefMethTest {6465public static void main(String[] args) {66DefMethTest.runTest(RedefineTest.class,67/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),68/* flags */ Set.of(0, ACC_SYNCHRONIZED),69/* redefine */ Set.of(true),70/* execMode */ Set.of(DIRECT, INVOKE_EXACT, INVOKE_GENERIC, INDY));71}7273@Override74protected void configure() {75// There are no testers being generated for reflection-based scenarios,76// so scenarios on class redefinition don't work77String mode = factory.getExecutionMode();78if ("REFLECTION".equals(mode) || "INVOKE_WITH_ARGS".equals(mode)) {79getLog().warn("RedefineTest isn't applicable to reflection-based execution scenario (REDEFINE & INVOKE_WITH_ARGS).");80}81}8283/**84* Run test {@code b1} w/ redefined {@code classes} from {@code b2}.85*86* @param b187* @param b288* @param classes89*/90private void redefineAndRun(TestBuilder b1, TestBuilder b2, Clazz... classes) {91TestExecutor executor = b1.prepare();9293getLog().info("Before");94List<Pair<Tester,Throwable>> errorsBefore =95executor.run(); // run b19697// redefine in b198MemoryClassLoader cl = executor.getLoader(); // b1.cl99Map<String,byte[]> cf = b2.produce(); //100Map<String,byte[]> forRedef = new HashMap<>();101for (Clazz clz : classes) {102String name = clz.name();103forRedef.put(name, cf.get(name));104}105106cl.modifyClasses(forRedef, factory.isRetransformClasses());107108getLog().info("After");109List<Pair<Tester,Throwable>> errorsAfter =110executor.run();111112if (!errorsBefore.isEmpty()) {113throw new DefMethTestFailure(errorsBefore);114}115116if (!errorsAfter.isEmpty()) {117throw new DefMethTestFailure(errorsAfter);118}119}120121/*122* Before redefinition:123* interface I { public int m() { return 1; } }124* class C extends I { public int m() { return 2; } }125*126* TEST: I i = new C(); i.m() == 2127* TEST: C c = new C(); c.m() == 2128*129* After redefinition:130* interface I { public int m() { return 1; } }131* class C extends I { public int m() { return 3; } }132*133* TEST: I i = new C(); i.m() == 3134* TEST: C c = new C(); c.m() == 3135*/136@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS }) // reflection-based scenarios rely on checks in bytecode137public void testRedefineConcreteMethod() {138TestBuilder before = factory.getBuilder();139{ // Before redefinition140Interface I = before.intf("I")141.defaultMethod("m", "()I").returns(1).build()142.build();143ConcreteClass C = before.clazz("C").implement(I)144.concreteMethod("m", "()I").returns(2).build()145.build();146147before.test().callSite(I, C, "m", "()I").returns(2).done()148.test().callSite(C, C, "m", "()I").returns(2).done();149}150151{ // After redefinition152TestBuilder after = factory.getBuilder();153154Interface I = after.intf("I")155.defaultMethod("m", "()I").returns(1).build()156.build();157ConcreteClass C = after.clazz("C").implement(I)158.concreteMethod("m", "()I").returns(3).build()159.build();160161Tester T1 = after.test().callSite(I, C, "m", "()I").returns(3).build();162Tester T2 = after.test().callSite(C, C, "m", "()I").returns(3).build();163164redefineAndRun(before, after, C, T1, T2);165}166}167168/*169* Before redefinition:170* interface I { public int m() { return 1; } }171* class C extends I { public int m() { return 2; } }172*173* TEST: I i = new C(); i.m() == 2174* TEST: C c = new C(); c.m() == 2175*176* After redefinition:177* interface I { public int m() { return 3; } }178* class C extends I { public int m() { return 2; } }179*180* TEST: I i = new C(); i.m() == 2181* TEST: C c = new C(); c.m() == 2182*/183@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS }) // reflection-based scenarios rely on checks in bytecode184public void testRedefineDefaultMethod() {185TestBuilder before = factory.getBuilder();186{ // Before redefinition187Interface I = before.intf("I")188.defaultMethod("m", "()I").returns(1).build()189.build();190ConcreteClass C = before.clazz("C").implement(I)191.concreteMethod("m", "()I").returns(2).build()192.build();193194before.test().callSite(I, C, "m", "()I").returns(2).done()195.test().callSite(C, C, "m", "()I").returns(2).done();196}197198{ // After redefinition199TestBuilder after = factory.getBuilder();200201Interface I = after.intf("I")202.defaultMethod("m", "()I").returns(3).build()203.build();204ConcreteClass C = after.clazz("C").implement(I)205.concreteMethod("m", "()I").returns(2).build()206.build();207208redefineAndRun(before, after, C);209}210}211212/*213* Before redefinition:214* interface I { public int m() { return 1; } }215* class C extends I {}216*217* TEST: I i = new C(); i.m() == 1218* TEST: C c = new C(); c.m() == 1219*220* After redefinition:221* interface I { public int m() { return 2; } }222* class C extends I {}223*224* TEST: I i = new C(); i.m() == 2225* TEST: C c = new C(); c.m() == 2226*/227@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS }) // reflection-based scenarios rely on checks in bytecode228public void testRedefineDefMethInConcreteClass() {229TestBuilder before = factory.getBuilder();230{ // Before redefinition231Interface I = before.intf("I")232.defaultMethod("m", "()I").returns(1).build()233.build();234ConcreteClass C = before.clazz("C").implement(I).build();235236before.test().callSite(I, C, "m", "()I").returns(1).done()237.test().callSite(C, C, "m", "()I").returns(1).done();238}239240{ // After redefinition241TestBuilder after = factory.getBuilder();242243Interface I = after.intf("I")244.defaultMethod("m", "()I").returns(2).build()245.build();246ConcreteClass C = after.clazz("C").implement(I).build();247248Tester T1 = after.test().callSite(I, C, "m", "()I").returns(2).build();249Tester T2 = after.test().callSite(C, C, "m", "()I").returns(2).build();250251redefineAndRun(before, after, I, T1, T2);252}253}254}255256257