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