1 Copyright (c) 2014, 2018, 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 it 5 under the terms of the GNU General Public License version 2 only, as 6 published by the Free Software Foundation. 7 8 This code is distributed in the hope that it will be useful, but WITHOUT 9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 version 2 for more details (a copy is included in the LICENSE file that 12 accompanied this code). 13 14 You should have received a copy of the GNU General Public License version 15 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 USA 19 or visit www.oracle.com if you need additional information or have any 20 questions. 21 22 23 ABOUT 24 25 Once published, it is impossible to add methods to an interface without 26 breaking existing implementations (specifically, adding a method to an 27 interface is not a source-compatible change). The longer the time since a 28 library has been published, the more likely it is that this restriction will 29 cause grief for its maintainers. 30 31 The addition of closures to the Java language in JDK 8 place additional stress 32 on the aging Collection interfaces; one of the most significant benefits of 33 closures is that it enables the development of more powerful libraries. It 34 would be disappointing to add a language feature that enables better libraries 35 while at the same time not extending the core libraries to take advantage of 36 that feature. 37 38 A mechanism for adding new methods to existing interfaces is proposed, which is 39 called virtual extension (or default) methods. Existing interfaces can be 40 augmented without compromising backward compatibility by adding extension 41 methods to the interface, whose declaration would contain instructions for 42 finding the default implementation in the event that implementers do not 43 provide a method body. A key characteristic of extension methods is that they 44 are virtual methods just like other interface methods, but provide a default 45 implementation in the event that the implementing class does not provide a 46 method body. 47 48 VM support is necessary to implement virtual extension methods. 49 50 51 OVERVIEW 52 53 The test suite is organized in the following manner. 54 55 The tests rely on a framework to generate class hierarchies and tests 56 directly in bytecode from a pseudo-code in Java. Pseudo-code is written 57 using builder pattern and fluent coding style. 58 59 The framework is located in src/vm/runtime/defmeth/shared and divided into 60 /data and /builder sections. 61 62 As an example, the following code: 63 64 TestBuilder b = factory.getBuilder(); 65 66 Interface I = b.intf("I") 67 .defaultMethod("m", "()I").returns(1).build() 68 .build(); 69 70 ConcreteClass C = b.clazz("C").implement(I) 71 .concreteMethod("m", "()I").returns(2).build() 72 .build(); 73 74 b.test().callSite(I, C, "m", "()I").returns(2).done() 75 .test().callSite(C, C, "m", "()I").returns(2).done() 76 77 .run(); 78 79 translates into bytecode equivalent of: 80 81 2-class hierarchy: 82 83 interface I { 84 int m() default { return 1; } 85 } 86 87 class C implements I { 88 public int m() { return 2; } 89 } 90 91 and 2 tests: 92 93 Test1_I_C_m { 94 static void test() { 95 I i = new C(); 96 if (i.m() != 2) throw new TestFailure(); 97 } 98 } 99 100 Test2_C_C_m { 101 static void test() { 102 C c = new C(); 103 if (c.m() != 2) throw new TestFailure(); 104 } 105 } 106 107 TestBuilder.run() calls Test1_I_C_m.test() and Test2_C_C_m.test() and 108 performs failure reporting, if necessary. 109 110 All tests are located in src/vm/runtime/defmeth and are grouped according 111 to the area they excercise. The test groups are: 112 - AccessibilityFlagsTest 113 - BasicTest 114 - ConflictingDefaultsTest 115 - DefaultVsAbstractTest 116 - MethodResolutionTest 117 - ObjectMethodOverridesTest 118 - PrivateMethodsTest 119 - RedefineTest 120 - StaticMethodsTest 121 - StressTest 122 - SuperCallTest 123 124 Each test group can be executed in different modes. For each mode there's a 125 corresponding scenario in src/vm/runtime/defmeth/scenarios. 126 127 Scenarios are organized in the following manner: 128 129 .../scenarios/[test_group]_[majorVer]_[methodFlags]_[invocationType]_[shouldRedefine] 130 131 where 132 133 majorVer - major version of class files for generated concrete classes 134 values: ver49, ver52 135 136 methodFlags - additional access flags for methods in generated classes 137 values: 138 none == no additional flags 139 sync == ACC_SYNCHRONIZED 140 strict == ACC_STRICT 141 syncstrict == ACC_SYNCHRONIZED | ACC_STRICT 142 143 invocationType - how methods in test hiearchies are invoked during testing 144 values: 145 direct - using invoke* bytecodes 146 reflect - using Reflection API 147 invoke - using invokedynamic & java.lang.invoke API (MethodHandles/JSR292) 148 149 redefine - whether to preload and redefine classes before running individual tests 150 values: redefine, noredefine 151 152 testGroup - name of test group being used 153 values: BasicTests/BridgeMethod/etc 154 155 156 STRESS TESTING 157 158 Stress test differs from other scenarios - it has only 2 modes: redefine and noredefine. 159 160 Stress scenario is the following: 161 - in multiple threads (5 by default)... 162 - ... continuously run random vm.runtime.defmeth.* tests ... 163 - ... in random configurations ... 164 - ... until predefined period of time is over... 165 - ... or any failures occured. 166 167 168 HOW TO RUN 169 170 Directly from command-line: 171 172 $ java -cp ${VMTESTBASE}/bin/classes vm.runtime.defmeth.shared.DefMethTest 173 174 Specify testing mode: 175 -flags <int> 176 additional access flags on default methods (default: 0) 177 178 -ver <int> 179 class file major version (default: 52) 180 181 -redefine <boolean> 182 redefine classes during execution (default: false) 183 184 -mode [direct|reflect|invoke] 185 specify method invocation mechanism (default: direct): 186 - direct - invoke* instructions in bytecode 187 - reflect - Reflection API 188 - invoke - invokedynamic & MethodHandle.invoke* 189 190 -execMode [DIRECT|REFLECTION|INVOKE_EXACT|INVOKE_GENERIC|INVOKE_WITH_ARGS|INDY] 191 specify concrete execution mode 192 193 Execution-specific flags: 194 -list <boolean> 195 list available tests 196 197 -filter <regex> 198 filter tests by name 199 (default: .* ) 200 201 If you run tests directly from command line, in order to make "-redefine true", 202 StressTest or RedefineTest work, additional steps are necessary: 203 add -agentlib:redefineClasses to JVM options 204 set correct LD_LIBRARY_PATH: 205 LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${VM_TESTBASE}/bin/lib/${PLATFORM}/vm/runtime/defmeth/shared/ 206 207 Also, it is possible to run any test group directly: 208 209 $ java -cp ${VMTESTBASE}/bin/classes vm.runtime.defmeth.BasicTest 210 211 StressTest has some specific options: 212 -stressTime <long> 213 Stress execution time in seconds (default: 60) 214 215 -stressThreadsFactor <int> 216 Stress threads factor (default: 1) 217 218 -seed <int> 219 force deterministic behavior (default: 0) 220 221 -redefine <boolean> 222 use scenarios w/ class redefinition (default: false) 223 224 -ver <int> 225 minimum class file version to be used in the tests (default: 49) 226 227 -ignoreTestFailures 228 ignore failures of individual tests 229 230 To simplify failure analysis, the framework has some additional flags to produce 231 diagnostics output: 232 233 -Dvm.runtime.defmeth.printTests 234 print pseudo-code for each test; 235 236 -Dvm.runtime.defmeth.printAssembly 237 print bytecode assembly for all generated class files; 238 239 -Dvm.runtime.defmeth.printASMify 240 print "asmified" version of generated class files; 241 very useful when preparing reduced test cases. 242 243 -Dvm.runtime.defmeth.dumpClasses 244 dump class files under DUMP_CLASS_FILES in <test_name> folder 245 246 -Dvm.runtime.defmeth.printStackTrace 247 print full stack traces for all errors and test failures 248 249 -Dvm.runtime.defmeth.traceClassRedefinition 250 trace class redefinition during testing 251 252 LINKS 253 254 [1] "Design and Implementation of Default Methods in Hotspot JVM", by Keith McGuigan, 09/18/2012 255 http://cr.openjdk.java.net/~kamg/default_methods_in_hotspot.txt 256 257 [2] "Featherweight Defenders: A formal model for virtual extension methods in Java", by Brian Goetz, Robert Field, 03/27/2012 258 http://cr.openjdk.java.net/~briangoetz/lambda/featherweight-defenders.pdf 259 260 [3] "Interface evolution via virtual extension methods", by Brian Goetz, 4th draft, 06/2011 261 http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf