--- /dev/null 2018-05-14 10:15:02.574213890 -0700 +++ new/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/README 2018-05-21 10:49:50.581497408 -0700 @@ -0,0 +1,261 @@ +Copyright (c) 2014, 2018, 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. + + +ABOUT + + Once published, it is impossible to add methods to an interface without + breaking existing implementations (specifically, adding a method to an + interface is not a source-compatible change). The longer the time since a + library has been published, the more likely it is that this restriction will + cause grief for its maintainers. + + The addition of closures to the Java language in JDK 8 place additional stress + on the aging Collection interfaces; one of the most significant benefits of + closures is that it enables the development of more powerful libraries. It + would be disappointing to add a language feature that enables better libraries + while at the same time not extending the core libraries to take advantage of + that feature. + + A mechanism for adding new methods to existing interfaces is proposed, which is + called virtual extension (or default) methods. Existing interfaces can be + augmented without compromising backward compatibility by adding extension + methods to the interface, whose declaration would contain instructions for + finding the default implementation in the event that implementers do not + provide a method body. A key characteristic of extension methods is that they + are virtual methods just like other interface methods, but provide a default + implementation in the event that the implementing class does not provide a + method body. + + VM support is necessary to implement virtual extension methods. + + +OVERVIEW + + The test suite is organized in the following manner. + + The tests rely on a framework to generate class hierarchies and tests + directly in bytecode from a pseudo-code in Java. Pseudo-code is written + using builder pattern and fluent coding style. + + The framework is located in src/vm/runtime/defmeth/shared and divided into + /data and /builder sections. + + As an example, the following code: + + TestBuilder b = factory.getBuilder(); + + Interface I = b.intf("I") + .defaultMethod("m", "()I").returns(1).build() + .build(); + + ConcreteClass C = b.clazz("C").implement(I) + .concreteMethod("m", "()I").returns(2).build() + .build(); + + b.test().callSite(I, C, "m", "()I").returns(2).done() + .test().callSite(C, C, "m", "()I").returns(2).done() + + .run(); + + translates into bytecode equivalent of: + + 2-class hierarchy: + + interface I { + int m() default { return 1; } + } + + class C implements I { + public int m() { return 2; } + } + + and 2 tests: + + Test1_I_C_m { + static void test() { + I i = new C(); + if (i.m() != 2) throw new TestFailure(); + } + } + + Test2_C_C_m { + static void test() { + C c = new C(); + if (c.m() != 2) throw new TestFailure(); + } + } + + TestBuilder.run() calls Test1_I_C_m.test() and Test2_C_C_m.test() and + performs failure reporting, if necessary. + + All tests are located in src/vm/runtime/defmeth and are grouped according + to the area they excercise. The test groups are: + - AccessibilityFlagsTest + - BasicTest + - ConflictingDefaultsTest + - DefaultVsAbstractTest + - MethodResolutionTest + - ObjectMethodOverridesTest + - PrivateMethodsTest + - RedefineTest + - StaticMethodsTest + - StressTest + - SuperCallTest + + Each test group can be executed in different modes. For each mode there's a + corresponding scenario in src/vm/runtime/defmeth/scenarios. + + Scenarios are organized in the following manner: + + .../scenarios/[test_group]_[majorVer]_[methodFlags]_[invocationType]_[shouldRedefine] + + where + + majorVer - major version of class files for generated concrete classes + values: ver49, ver50, ver51, ver52 + + methodFlags - additional access flags for methods in generated classes + values: + none == no additional flags + sync == ACC_SYNCHRONIZED + strict == ACC_STRICT + syncstrict == ACC_SYNCHRONIZED | ACC_STRICT + + invocationType - how methods in test hiearchies are invoked during testing + values: + direct - using invoke* bytecodes + reflect - using Reflection API + invoke - using invokedynamic & java.lang.invoke API (MethodHandles/JSR292) + + redefine - whether to preload and redefine classes before running individual tests + values: redefine, noredefine + + testGroup - name of test group being used + values: BasicTests/BridgeMethod/etc + + +STRESS TESTING + + Stress test differs from other scenarios - it has only 2 modes: redefine and noredefine. + + Stress scenario is the following: + - in multiple threads (5 by default)... + - ... continuously run random vm.runtime.defmeth.* tests ... + - ... in random configurations ... + - ... until predefined period of time is over... + - ... or any failures occured. + + +HOW TO RUN + + Directly from command-line: + + $ java -cp ${VMTESTBASE}/bin/classes vm.runtime.defmeth.shared.DefMethTest + + Specify testing mode: + -flags + additional access flags on default methods (default: 0) + + -ver + class file major version (default: 52) + + -redefine + redefine classes during execution (default: false) + + -mode [direct|reflect|invoke] + specify method invocation mechanism (default: direct): + - direct - invoke* instructions in bytecode + - reflect - Reflection API + - invoke - invokedynamic & MethodHandle.invoke* + + -execMode [DIRECT|REFLECTION|INVOKE_EXACT|INVOKE_GENERIC|INVOKE_WITH_ARGS|INDY] + specify concrete execution mode + + Execution-specific flags: + -list + list available tests + + -filter + filter tests by name + (default: .* ) + + If you run tests directly from command line, in order to make "-redefine true", + StressTest or RedefineTest work, additional steps are necessary: + add -agentlib:redefineClasses to JVM options + set correct LD_LIBRARY_PATH: + LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${VM_TESTBASE}/bin/lib/${PLATFORM}/vm/runtime/defmeth/shared/ + + Also, it is possible to run any test group directly: + + $ java -cp ${VMTESTBASE}/bin/classes vm.runtime.defmeth.BasicTest + + StressTest has some specific options: + -stressTime + Stress execution time in seconds (default: 60) + + -stressThreadsFactor + Stress threads factor (default: 1) + + -seed + force deterministic behavior (default: 0) + + -redefine + use scenarios w/ class redefinition (default: false) + + -ver + minimum class file version to be used in the tests (default: 49) + + -ignoreTestFailures + ignore failures of individual tests + + To simplify failure analysis, the framework has some additional flags to produce + diagnostics output: + + -Dvm.runtime.defmeth.printTests + print pseudo-code for each test; + + -Dvm.runtime.defmeth.printAssembly + print bytecode assembly for all generated class files; + + -Dvm.runtime.defmeth.printASMify + print "asmified" version of generated class files; + very useful when preparing reduced test cases. + + -Dvm.runtime.defmeth.dumpClasses + dump class files under DUMP_CLASS_FILES in folder + + -Dvm.runtime.defmeth.printStackTrace + print full stack traces for all errors and test failures + + -Dvm.runtime.defmeth.traceClassRedefinition + trace class redefinition during testing + +LINKS + + [1] "Design and Implementation of Default Methods in Hotspot JVM", by Keith McGuigan, 09/18/2012 + http://cr.openjdk.java.net/~kamg/default_methods_in_hotspot.txt + + [2] "Featherweight Defenders: A formal model for virtual extension methods in Java", by Brian Goetz, Robert Field, 03/27/2012 + http://cr.openjdk.java.net/~briangoetz/lambda/featherweight-defenders.pdf + + [3] "Interface evolution via virtual extension methods", by Brian Goetz, 4th draft, 06/2011 + http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf