8061281: Microbenchmark suite build support, directory layout and sample benchmarks
authorredestad
Fri, 16 Nov 2018 23:39:51 +0100
changeset 52595 16609197022c
parent 52594 4d8a023c2a03
child 52596 dfa02b3f728c
8061281: Microbenchmark suite build support, directory layout and sample benchmarks 8061282: Migrate jmh-jdk-microbenchmarks into the JDK Reviewed-by: ecaspole, mchung, erikj, ihse Contributed-by: magnus.ihse.bursie@oracle.com, erik.joelsson@oracle.com, claes.redestad@oracle.com, sfriberg@kth.se
doc/testing.html
doc/testing.md
make/Help.gmk
make/InitSupport.gmk
make/Main.gmk
make/RunTests.gmk
make/autoconf/configure.ac
make/autoconf/lib-tests.m4
make/autoconf/spec.gmk.in
make/common/FindTests.gmk
make/common/JarArchive.gmk
make/conf/jib-profiles.js
make/devkit/createJMHBundle.sh
make/test/BuildMicrobenchmark.gmk
test/micro/org/openjdk/bench/java/io/BlackholedOutputStream.java
test/micro/org/openjdk/bench/java/io/FileChannelRead.java
test/micro/org/openjdk/bench/java/io/FileChannelWrite.java
test/micro/org/openjdk/bench/java/io/FileRead.java
test/micro/org/openjdk/bench/java/io/FileWrite.java
test/micro/org/openjdk/bench/java/io/ObjectStreamClasses.java
test/micro/org/openjdk/bench/java/io/RandomAccessRead.java
test/micro/org/openjdk/bench/java/io/RandomAccessWrite.java
test/micro/org/openjdk/bench/java/io/SerializationWriteReplace.java
test/micro/org/openjdk/bench/java/io/UTF8.java
test/micro/org/openjdk/bench/java/lang/ArrayCopy.java
test/micro/org/openjdk/bench/java/lang/ArrayCopyAligned.java
test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedBoth.java
test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedDst.java
test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedSrc.java
test/micro/org/openjdk/bench/java/lang/ClassForName.java
test/micro/org/openjdk/bench/java/lang/Clone.java
test/micro/org/openjdk/bench/java/lang/FloatingDecimal.java
test/micro/org/openjdk/bench/java/lang/GetStackTrace.java
test/micro/org/openjdk/bench/java/lang/Integers.java
test/micro/org/openjdk/bench/java/lang/Longs.java
test/micro/org/openjdk/bench/java/lang/NewInstance.java
test/micro/org/openjdk/bench/java/lang/ObjectHashCode.java
test/micro/org/openjdk/bench/java/lang/StringBuffers.java
test/micro/org/openjdk/bench/java/lang/StringBuilders.java
test/micro/org/openjdk/bench/java/lang/StringConcat.java
test/micro/org/openjdk/bench/java/lang/StringHashCode.java
test/micro/org/openjdk/bench/java/lang/StringHttp.java
test/micro/org/openjdk/bench/java/lang/StringIndexOf.java
test/micro/org/openjdk/bench/java/lang/StringOther.java
test/micro/org/openjdk/bench/java/lang/StringUpperLower.java
test/micro/org/openjdk/bench/java/lang/Systems.java
test/micro/org/openjdk/bench/java/lang/ThreadStartJoin.java
test/micro/org/openjdk/bench/java/lang/invoke/CallSiteSetTarget.java
test/micro/org/openjdk/bench/java/lang/invoke/CallSiteSetTargetSelf.java
test/micro/org/openjdk/bench/java/lang/invoke/CallSiteStable.java
test/micro/org/openjdk/bench/java/lang/invoke/LookupAcquire.java
test/micro/org/openjdk/bench/java/lang/invoke/LookupDefaultFind.java
test/micro/org/openjdk/bench/java/lang/invoke/LookupPublicFind.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsCollector.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsSpreader.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsVarargsCollector.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBasicInvoke.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBindToBinding.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBindToCurry.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertBoxing.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertCast.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnPrimitive.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnReference.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnVoid.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertUnboxing.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertWidening.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleInvokeWithArgs.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleProxiesAsIFInstance.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleProxiesSuppl.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesArrayElementGetter.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesArrayElementSetter.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesCatchException.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesConstant.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesDropArguments.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesExactInvoker.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFilterArgs.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFilterReturn.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFoldArguments.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesGuardWithTest.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesIdentity.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesInsertArguments.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesInvoker.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesPermuteArguments.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesSpreadInvoker.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesThrowException.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAcquire.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAppendParams.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeChangeParam.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeChangeReturn.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeDropParams.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeGenerify.java
test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeInsertParams.java
test/micro/org/openjdk/bench/java/lang/invoke/SwitchPointAdhoc.java
test/micro/org/openjdk/bench/java/lang/invoke/SwitchPointGuard.java
test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java
test/micro/org/openjdk/bench/java/lang/reflect/ClazzWithSecurityManager.java
test/micro/org/openjdk/bench/java/lang/reflect/MethodInvoke.java
test/micro/org/openjdk/bench/java/math/BigDecimals.java
test/micro/org/openjdk/bench/java/math/BigIntegers.java
test/micro/org/openjdk/bench/java/net/DatagramSocketTest.java
test/micro/org/openjdk/bench/java/net/SocketChannelReadWrite.java
test/micro/org/openjdk/bench/java/net/SocketReadWrite.java
test/micro/org/openjdk/bench/java/net/SocketStreaming.java
test/micro/org/openjdk/bench/java/net/URLEncodeDecode.java
test/micro/org/openjdk/bench/java/nio/ByteBuffers.java
test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java
test/micro/org/openjdk/bench/java/security/DoPrivileged.java
test/micro/org/openjdk/bench/java/security/MessageDigests.java
test/micro/org/openjdk/bench/java/util/ArraysEquals.java
test/micro/org/openjdk/bench/java/util/Dates.java
test/micro/org/openjdk/bench/java/util/GregorianCalendars.java
test/micro/org/openjdk/bench/java/util/RandomNext.java
test/micro/org/openjdk/bench/java/util/ZipFind.java
test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java
test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java
test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java
test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java
test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java
test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java
test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java
test/micro/org/openjdk/bench/java/util/concurrent/Locks.java
test/micro/org/openjdk/bench/java/util/concurrent/Maps.java
test/micro/org/openjdk/bench/java/util/concurrent/Problem.java
test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java
test/micro/org/openjdk/bench/java/util/concurrent/Queues.java
test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java
test/micro/org/openjdk/bench/java/util/logging/LogRecord.java
test/micro/org/openjdk/bench/java/util/stream/AllMatcher.java
test/micro/org/openjdk/bench/java/util/stream/AnyMatcher.java
test/micro/org/openjdk/bench/java/util/stream/Decomposition.java
test/micro/org/openjdk/bench/java/util/stream/NoneMatcher.java
test/micro/org/openjdk/bench/java/util/stream/Reducers.java
test/micro/org/openjdk/bench/java/util/stream/ops/LongAccumulator.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/AllMatch.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/AllMatchShort.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/AnyMatch.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/AnyMatchShort.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/Filter.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/FindAny.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/FindFirst.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/ForEach.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/Limit.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/Map.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/NoneMatch.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/NoneMatchShort.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/Reduce.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/ReduceBase.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/Sorted.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/SortedUnique.java
test/micro/org/openjdk/bench/java/util/stream/ops/ref/UniqueElements.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/AllMatch.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/AllMatchShort.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/AnyMatch.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/AnyMatchShort.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/Filter.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/FindAny.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/FindFirst.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/ForEach.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/Limit.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/Map.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/NoneMatch.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/NoneMatchShort.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/Reduce.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/ReduceBase.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/Sorted.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/SortedUnique.java
test/micro/org/openjdk/bench/java/util/stream/ops/value/UniqueElements.java
test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineParMultiple.java
test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineSeqMultiple.java
test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineSetup.java
test/micro/org/openjdk/bench/java/util/stream/pipeline/Terminal.java
test/micro/org/openjdk/bench/java/util/stream/tasks/DataProviders.java
test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/DictionaryProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Lambda.java
test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Xtras.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/IntegerDuplicateProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/Lambda.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/IntegerMaxProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Lambda.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Xtras.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/IntegerSumProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Lambda.java
test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Xtras.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PhoneCode/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PhoneCode/PhoneCodeProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/PrimesProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Lambda.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Xtras.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Lambda.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Xtras.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesSieve/Bulk.java
test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesSieve/PrimesSieveProblem.java
test/micro/org/openjdk/bench/java/util/stream/tasks/README
test/micro/org/openjdk/bench/javax/crypto/AES.java
test/micro/org/openjdk/bench/javax/crypto/Crypto.java
test/micro/org/openjdk/bench/javax/tools/Javac.java
test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java
test/micro/org/openjdk/bench/javax/xml/DOM.java
test/micro/org/openjdk/bench/javax/xml/SAXUsingJDK.java
test/micro/org/openjdk/bench/javax/xml/STAX.java
test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java
test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java
test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java
test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java
test/micro/org/openjdk/bench/vm/compiler/DivRem.java
test/micro/org/openjdk/bench/vm/compiler/Explosion.java
test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java
test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java
test/micro/org/openjdk/bench/vm/compiler/Multiplication.java
test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java
test/micro/org/openjdk/bench/vm/compiler/SpillCode.java
test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java
test/micro/org/openjdk/bench/vm/compiler/Straighten.java
test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java
test/micro/org/openjdk/bench/vm/gc/Alloc.java
test/micro/org/openjdk/bench/vm/lambda/capture/Capture0.java
test/micro/org/openjdk/bench/vm/lambda/capture/Capture2.java
test/micro/org/openjdk/bench/vm/lambda/capture/CaptureMR.java
test/micro/org/openjdk/bench/vm/lambda/capture/FunctionalInterface0.java
test/micro/org/openjdk/bench/vm/lambda/capture/FunctionalInterface1.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap0.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap1.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap4.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainBase.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap0.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap1.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap4.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainMrefBound.java
test/micro/org/openjdk/bench/vm/lambda/chain/ChainMrefUnbound.java
test/micro/org/openjdk/bench/vm/lambda/chain/Level.java
test/micro/org/openjdk/bench/vm/lambda/chain/TopLevel.java
test/micro/org/openjdk/bench/vm/lambda/invoke/AckermannI.java
test/micro/org/openjdk/bench/vm/lambda/invoke/AckermannL.java
test/micro/org/openjdk/bench/vm/lambda/invoke/Function0.java
test/micro/org/openjdk/bench/vm/lambda/invoke/Function1.java
test/micro/org/openjdk/bench/vm/lambda/invoke/Morph0.java
test/micro/org/openjdk/bench/vm/lambda/invoke/Morph1.java
test/micro/org/openjdk/bench/vm/lambda/invoke/Morph2.java
test/micro/org/openjdk/bench/vm/lang/InstanceOf.java
test/micro/org/openjdk/bench/vm/lang/LockUnlock.java
test/micro/org/openjdk/bench/vm/lang/Throw.java
--- a/doc/testing.html	Fri Nov 16 13:23:50 2018 -0500
+++ b/doc/testing.html	Fri Nov 16 23:39:51 2018 +0100
@@ -24,12 +24,14 @@
 <li><a href="#test-selection">Test selection</a><ul>
 <li><a href="#jtreg">JTReg</a></li>
 <li><a href="#gtest">Gtest</a></li>
+<li><a href="#microbenchmarks">Microbenchmarks</a></li>
 <li><a href="#special-tests">Special tests</a></li>
 </ul></li>
 <li><a href="#test-results-and-summary">Test results and summary</a></li>
 <li><a href="#test-suite-control">Test suite control</a><ul>
 <li><a href="#jtreg-keywords">JTReg keywords</a></li>
 <li><a href="#gtest-keywords">Gtest keywords</a></li>
+<li><a href="#microbenchmark-keywords">Microbenchmark keywords</a></li>
 </ul></li>
 </ul>
 </nav>
@@ -44,9 +46,11 @@
 $ make test-only TEST=&quot;gtest:LogTagSet gtest:LogTagSetDescriptions&quot; GTEST=&quot;REPEAT=-1&quot;
 $ make test TEST=&quot;hotspot:hotspot_gc&quot; JTREG=&quot;JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;
 $ make test TEST=&quot;jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java&quot;
+$ make test TEST=&quot;micro:java.lang.reflect&quot; MICRO=&quot;FORK=1;WARMUP_ITER=2&quot;
 $ make exploded-test TEST=tier2</code></pre>
 <h3 id="configuration">Configuration</h3>
 <p>To be able to run JTReg tests, <code>configure</code> needs to know where to find the JTReg test framework. If it is not picked up automatically by configure, use the <code>--with-jtreg=&lt;path to jtreg home&gt;</code> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc. (An alternative is to set the <code>JT_HOME</code> environment variable to point to the JTReg home before running <code>configure</code>.)</p>
+<p>To be able to run microbenchmarks, <code>configure</code> needs to know where to find the JMH dependency. Use <code>--with-jmh=&lt;path to JMH jars&gt;</code> to point to a directory containing the core JMH and transitive dependencies. The recommended dependencies can be retrieved by running <code>sh make/devkit/createJMHBundle.sh</code>, after which <code>--with-jmh=build/jmh/jars</code> should work.</p>
 <h2 id="test-selection">Test selection</h2>
 <p>All functionality is available using the <code>test</code> make target. In this use case, the test or tests to be executed is controlled using the <code>TEST</code> variable. To speed up subsequent test runs with no source code changes, <code>test-only</code> can be used instead, which do not depend on the source and test image build.</p>
 <p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make test-tier1</code> is equivalent to <code>make test TEST=&quot;tier1&quot;</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>test TEST=&quot;x&quot;</code> solution needs to be used.</p>
@@ -61,6 +65,9 @@
 <p>Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just <code>gtest</code>, or as a fully qualified test descriptor <code>gtest:all</code>.</p>
 <p>If you want, you can single out an individual test or a group of tests, for instance <code>gtest:LogDecorations</code> or <code>gtest:LogDecorations.level_test_vm</code>. This can be particularly useful if you want to run a shaky test repeatedly.</p>
 <p>For Gtest, there is a separate test suite for each JVM variant. The JVM variant is defined by adding <code>/&lt;variant&gt;</code> to the test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no variant, gtest will run once for each JVM variant present (e.g. server, client). So if you only have the server JVM present, then <code>gtest:all</code> will be equivalent to <code>gtest:all/server</code>.</p>
+<h3 id="microbenchmarks">Microbenchmarks</h3>
+<p>Which microbenchmarks to run is selected using a regular expression following the <code>micro:</code> test descriptor, e.g., <code>micro:java.lang.reflect</code>. This delegates the test selection to JMH, meaning package name, class name and even benchmark method names can be used to select tests.</p>
+<p>Using special characters like <code>|</code> in the regular expression is possible, but needs to be escaped multiple times: <code>micro:ArrayCopy\\\\\|reflect</code>.</p>
 <h3 id="special-tests">Special tests</h3>
 <p>A handful of odd tests that are not covered by any other testing framework are accessible using the <code>special:</code> test descriptor. Currently, this includes <code>failure-handler</code> and <code>make</code>.</p>
 <ul>
@@ -127,5 +134,22 @@
 <h4 id="options-1">OPTIONS</h4>
 <p>Additional options to the Gtest test framework.</p>
 <p>Use <code>GTEST=&quot;OPTIONS=--help&quot;</code> to see all available Gtest options.</p>
+<h3 id="microbenchmark-keywords">Microbenchmark keywords</h3>
+<h4 id="fork">FORK</h4>
+<p>Override the number of benchmark forks to spawn. Same as specifying <code>-f &lt;num&gt;</code>.</p>
+<h4 id="iter">ITER</h4>
+<p>Number of measurement iterations per fork. Same as specifying <code>-i &lt;num&gt;</code>.</p>
+<h4 id="time">TIME</h4>
+<p>Amount of time to spend in each measurement iteration, in seconds. Same as specifying <code>-r &lt;num&gt;</code></p>
+<h4 id="warmup_iter">WARMUP_ITER</h4>
+<p>Number of warmup iterations to run before the measurement phase in each fork. Same as specifying <code>-wi &lt;num&gt;</code>.</p>
+<h4 id="warmup_time">WARMUP_TIME</h4>
+<p>Amount of time to spend in each warmup iteration. Same as specifying <code>-w &lt;num&gt;</code>.</p>
+<h4 id="results_format">RESULTS_FORMAT</h4>
+<p>Specify to have the test run save a log of the values. Accepts the same values as <code>-rff</code>, i.e., <code>text</code>, <code>csv</code>, <code>scsv</code>, <code>json</code>, or <code>latex</code>.</p>
+<h4 id="vm_options-1">VM_OPTIONS</h4>
+<p>Additional VM arguments to provide to forked off VMs. Same as <code>-jvmArgs &lt;args&gt;</code></p>
+<h4 id="options-2">OPTIONS</h4>
+<p>Additional arguments to send to JMH.</p>
 </body>
 </html>
--- a/doc/testing.md	Fri Nov 16 13:23:50 2018 -0500
+++ b/doc/testing.md	Fri Nov 16 23:39:51 2018 +0100
@@ -26,6 +26,7 @@
     $ make test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
     $ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
     $ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
+    $ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
     $ make exploded-test TEST=tier2
 
 ### Configuration
@@ -37,6 +38,12 @@
 containing `lib/jtreg.jar` etc. (An alternative is to set the `JT_HOME`
 environment variable to point to the JTReg home before running `configure`.)
 
+To be able to run microbenchmarks, `configure` needs to know where to find
+the JMH dependency. Use `--with-jmh=<path to JMH jars>` to point to a directory
+containing the core JMH and transitive dependencies. The recommended dependencies 
+can be retrieved by running `sh make/devkit/createJMHBundle.sh`, after which 
+`--with-jmh=build/jmh/jars` should work.
+
 ## Test selection
 
 All functionality is available using the `test` make target. In this use case,
@@ -104,6 +111,16 @@
 variant present (e.g. server, client). So if you only have the server JVM
 present, then `gtest:all` will be equivalent to `gtest:all/server`.
 
+### Microbenchmarks
+
+Which microbenchmarks to run is selected using a regular expression
+following the `micro:` test descriptor, e.g., `micro:java.lang.reflect`. This
+delegates the test selection to JMH, meaning package name, class name and even
+benchmark method names can be used to select tests.
+
+Using special characters like `|` in the regular expression is possible, but
+needs to be escaped multiple times: `micro:ArrayCopy\\\\\|reflect`.
+
 ### Special tests
 
 A handful of odd tests that are not covered by any other testing framework are
@@ -253,6 +270,35 @@
 
 Use `GTEST="OPTIONS=--help"` to see all available Gtest options.
 
+### Microbenchmark keywords
+
+#### FORK
+Override the number of benchmark forks to spawn. Same as specifying `-f <num>`.
+
+#### ITER
+Number of measurement iterations per fork. Same as specifying `-i <num>`.
+
+#### TIME
+Amount of time to spend in each measurement iteration, in seconds. Same as
+specifying `-r <num>`
+
+#### WARMUP_ITER
+Number of warmup iterations to run before the measurement phase in each fork.
+Same as specifying `-wi <num>`.
+
+#### WARMUP_TIME
+Amount of time to spend in each warmup iteration. Same as specifying `-w <num>`.
+
+#### RESULTS_FORMAT
+Specify to have the test run save a log of the values. Accepts the same values
+as `-rff`, i.e., `text`, `csv`, `scsv`, `json`, or `latex`.
+
+#### VM_OPTIONS
+Additional VM arguments to provide to forked off VMs. Same as `-jvmArgs <args>`
+
+#### OPTIONS
+Additional arguments to send to JMH.
+
 ---
 # Override some definitions in the global css file that are not optimal for
 # this document.
--- a/make/Help.gmk	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/Help.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -103,6 +103,7 @@
 	$(info $(_)                        # make test TEST="jdk_lang gtest:all")
 	$(info $(_) JTREG="OPT1=x;OPT2=y"  # Control the JTREG test harness)
 	$(info $(_) GTEST="OPT1=x;OPT2=y"  # Control the GTEST test harness)
+	$(info $(_) MICRO="OPT1=x;OPT2=y"  # Control the MICRO test harness)
 	$(info $(_) TEST_OPTS="OPT1=x;..." # Generic control of all test harnesses)
 	$(info $(_) TEST_VM_OPTS="ARG ..." # Same as setting TEST_OPTS to VM_OPTIONS="ARG ...")
 	$(info )
--- a/make/InitSupport.gmk	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/InitSupport.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -50,7 +50,7 @@
 
   # Make control variables, handled by Init.gmk
   INIT_CONTROL_VARIABLES += LOG CONF CONF_NAME SPEC JOBS TEST_JOBS CONF_CHECK \
-      COMPARE_BUILD JTREG GTEST TEST_OPTS TEST_VM_OPTS
+      COMPARE_BUILD JTREG GTEST MICRO TEST_OPTS TEST_VM_OPTS
 
   # All known make control variables
   MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER
--- a/make/Main.gmk	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/Main.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -493,7 +493,7 @@
 ALL_TARGETS += $(ALL_TEST_TARGETS) $(ALL_EXPLODED_TEST_TARGETS)
 
 ################################################################################
-# Build tests
+# Build tests and microbenchmarks
 #
 
 prepare-test-image:
@@ -543,11 +543,15 @@
 	     -f BuildFailureHandler.gmk images)
 endif
 
+build-microbenchmark:
+	+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f test/BuildMicrobenchmark.gmk)
+
 ALL_TARGETS += prepare-test-image build-test-hotspot-jtreg-native \
     test-image-hotspot-jtreg-native build-test-jdk-jtreg-native \
     test-image-jdk-jtreg-native build-test-lib build-test-failure-handler \
     test-failure-handler test-image-failure-handler test-image-hotspot-gtest \
-    test-image-hotspot-jtreg-graal build-test-hotspot-jtreg-graal
+    test-image-hotspot-jtreg-graal build-test-hotspot-jtreg-graal \
+    build-microbenchmark
 
 ################################################################################
 # Run tests
@@ -789,6 +793,8 @@
 
   jrtfs-jar: interim-langtools
 
+  build-microbenchmark: interim-langtools jdk.unsupported java.management
+
   ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
     ifeq ($(CREATE_BUILDJDK), true)
       # If creating a buildjdk, the interim image needs to be based on that.
@@ -1023,6 +1029,10 @@
     test-image-jdk-jtreg-native test-image-failure-handler \
     test-image-demos-jdk $(JVM_TEST_IMAGE_TARGETS)
 
+ifneq ($(JMH_CORE_JAR), )
+  test-image: build-microbenchmark
+endif
+
 ################################################################################
 
 # all-images builds all our deliverables as images.
--- a/make/RunTests.gmk	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/RunTests.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -237,13 +237,11 @@
   $(info Running tests using TEST_OPTS control variable '$(TEST_OPTS)')
 endif
 
+### Jtreg
+
 $(eval $(call SetTestOpt,VM_OPTIONS,JTREG))
 $(eval $(call SetTestOpt,JAVA_OPTIONS,JTREG))
-$(eval $(call SetTestOpt,VM_OPTIONS,GTEST))
-$(eval $(call SetTestOpt,JAVA_OPTIONS,GTEST))
-
 $(eval $(call SetTestOpt,AOT_MODULES,JTREG))
-$(eval $(call SetTestOpt,AOT_MODULES,GTEST))
 
 $(eval $(call SetTestOpt,JOBS,JTREG))
 $(eval $(call SetTestOpt,TIMEOUT_FACTOR,JTREG))
@@ -259,6 +257,12 @@
   $(info Running tests using JTREG control variable '$(JTREG)')
 endif
 
+### Gtest
+
+$(eval $(call SetTestOpt,VM_OPTIONS,GTEST))
+$(eval $(call SetTestOpt,JAVA_OPTIONS,GTEST))
+$(eval $(call SetTestOpt,AOT_MODULES,GTEST))
+
 $(eval $(call ParseKeywordVariable, GTEST, \
     SINGLE_KEYWORDS := REPEAT AOT_MODULES, \
     STRING_KEYWORDS := OPTIONS VM_OPTIONS JAVA_OPTIONS, \
@@ -269,6 +273,21 @@
   $(info Running tests using GTEST control variable '$(GTEST)')
 endif
 
+### Microbenchmarks
+
+$(eval $(call SetTestOpt,VM_OPTIONS,MICRO))
+$(eval $(call SetTestOpt,JAVA_OPTIONS,MICRO))
+
+$(eval $(call ParseKeywordVariable, MICRO, \
+    SINGLE_KEYWORDS := ITER FORK TIME WARMUP_ITER WARMUP_TIME, \
+    STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS RESULTS_FORMAT TEST_JDK BENCHMARKS_JAR, \
+))
+
+ifneq ($(MICRO), )
+  # Inform the user
+  $(info Running tests using MICRO control variable '$(MICRO)')
+endif
+
 
 ################################################################################
 # Component-specific Jtreg settings
@@ -325,6 +344,24 @@
   )
 endef
 
+# Helper function to determine if a test specification is a microbenchmark test
+#
+# It is a microbenchmark test if it is either "micro", or "micro:" followed by an optional
+# test filter string.
+define ParseMicroTestSelection
+  $(if $(filter micro%, $1), \
+    $(if $(filter micro, $1), \
+      micro:all \
+    , \
+      $(if $(filter micro:, $1), \
+        micro:all \
+      , \
+        $1 \
+      ) \
+    ) \
+  )
+endef
+
 # Helper function that removes the TOPDIR part
 CleanupJtregPath = \
   $(strip $(patsubst %/, %, $(subst $(JTREG_TOPDIR)/,, $1)))
@@ -438,6 +475,9 @@
     $(eval PARSED_TESTS += $(call ParseGtestTestSelection, $(test))) \
   ) \
   $(if $(strip $(PARSED_TESTS)), , \
+    $(eval PARSED_TESTS += $(call ParseMicroTestSelection, $(test))) \
+  ) \
+  $(if $(strip $(PARSED_TESTS)), , \
     $(eval PARSED_TESTS += $(call ParseJtregTestSelection, $(test))) \
   ) \
   $(if $(strip $(PARSED_TESTS)), , \
@@ -560,6 +600,113 @@
 
 ################################################################################
 
+### Rules for Microbenchmarks
+
+# Helper function for SetupRunMicroTest. Set a MICRO_* variable from, in order:
+# 1) Specified by user on command line
+# 2) Generic default
+#
+# Note: No spaces are allowed around the arguments.
+# Arg $1 The test ID (i.e. $1 in SetupRunMicroTest)
+# Arg $2 Base variable, e.g. MICRO_TEST_JDK
+# Arg $3 The default value (optional)
+define SetMicroValue
+  ifneq ($$($2), )
+    $1_$2 := $$($2)
+  else
+    ifneq ($3, )
+      $1_$2 := $3
+    endif
+  endif
+endef
+
+SetupRunMicroTest = $(NamedParamsMacroTemplate)
+define SetupRunMicroTestBody
+  $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
+  $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
+  $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt
+
+  $1_TEST_NAME := $$(strip $$(patsubst micro:%, %, $$($1_TEST)))
+
+  $$(eval $$(call SetMicroValue,$1,MICRO_BENCHMARKS_JAR,$$(TEST_IMAGE_DIR)/micro/benchmarks.jar))
+  $$(eval $$(call SetMicroValue,$1,MICRO_TEST_JDK,$$(JDK_IMAGE_DIR)))
+  $$(eval $$(call SetMicroValue,$1,MICRO_JAVA_OPTIONS))
+
+  # Current tests needs to open java.io
+  $1_MICRO_JAVA_OPTIONS += --add-opens=java.base/java.io=ALL-UNNAMED
+
+  # Save output as JSON or CSV file
+  ifneq ($$(MICRO_RESULTS_FORMAT), )
+    $1_MICRO_BASIC_OPTIONS += -rf $$(MICRO_RESULTS_FORMAT) -rff $$($1_TEST_RESULTS_DIR)/jmh-result.$(MICRO_RESULTS_FORMAT)
+  endif
+
+  ifneq ($$(MICRO_VM_OPTIONS)$$(MICRO_JAVA_OPTIONS), )
+    $1_MICRO_VM_OPTIONS := -jvmArgs $$(MICRO_VM_OPTIONS) $$(MICRO_JAVA_OPTIONS)
+  endif
+
+  ifneq ($$(MICRO_ITER), )
+    $1_MICRO_ITER := -i $$(MICRO_ITER)
+  endif
+  ifneq ($$(MICRO_FORK), )
+    $1_MICRO_FORK := -f $$(MICRO_FORK)
+  endif
+  ifneq ($$(MICRO_TIME), )
+    $1_MICRO_TIME := -r $$(MICRO_TIME)
+  endif
+  ifneq ($$(MICRO_WARMUP_ITER), )
+    $1_MICRO_WARMUP_ITER := -wi $$(MICRO_WARMUP_ITER)
+  endif
+  ifneq ($$(MICRO_WARMUP_TIME), )
+    $1_MICRO_WARMUP_TIME := -w $$(MICRO_WARMUP_TIME)
+  endif
+
+  run-test-$1:
+	$$(call LogWarn)
+	$$(call LogWarn, Running test '$$($1_TEST)')
+	$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
+	$$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/micro, \
+	    $$($1_MICRO_TEST_JDK)/bin/java $$($1_MICRO_JAVA_OPTIONS) -jar $$($1_MICRO_BENCHMARKS_JAR) \
+	        $$($1_MICRO_ITER) $$($1_MICRO_FORK) $$($1_MICRO_TIME) \
+	        $$($1_MICRO_WARMUP_ITER) $$($1_MICRO_WARMUP_TIME) \
+	        $$($1_MICRO_VM_OPTIONS) $$($1_MICRO_BASIC_OPTIONS) $$(MICRO_OPTIONS)  \
+	        $$($1_TEST_NAME) \
+	        > >($(TEE) $$($1_TEST_RESULTS_DIR)/micro.txt) \
+	    && $$(ECHO) $$$$? > $$($1_EXITCODE) \
+	    || $$(ECHO) $$$$? > $$($1_EXITCODE) \
+	)
+
+  $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/micro.txt
+
+  parse-test-$1: run-test-$1
+	$$(call LogWarn, Finished running test '$$($1_TEST)')
+	$$(call LogWarn, Test report is stored in $$(strip \
+	    $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
+	$$(if $$(wildcard $$($1_EXITCODE)), \
+	  $$(eval $1_EXIT_CODE := $$(shell $$(CAT) $$($1_EXITCODE))) \
+	  $$(if $$(filter 0, $$($1_EXIT_CODE)), \
+	    $$(eval $1_PASSED := 1) \
+	    $$(eval $1_ERROR := 0) \
+	  , \
+	    $$(eval $1_PASSED := 0) \
+	    $$(eval $1_ERROR := 1) \
+	  ) \
+	  $$(eval $1_FAILED := 0) \
+	  $$(eval $1_TOTAL := $$(shell \
+	      $$(EXPR) $$($1_PASSED) + $$($1_ERROR))) \
+	, \
+	  $$(eval $1_PASSED := 0) \
+	  $$(eval $1_FAILED := 0) \
+	  $$(eval $1_ERROR := 1) \
+	  $$(eval $1_TOTAL := 1) \
+	)
+
+  $1: run-test-$1 parse-test-$1
+
+  TARGETS += $1
+endef
+
+################################################################################
+
 ### Rules for Jtreg
 
 # Helper function for SetupRunJtregTest. Set a JTREG_* variable from, in order:
@@ -849,6 +996,9 @@
 UseGtestTestHandler = \
   $(if $(filter gtest:%, $1), true)
 
+UseMicroTestHandler = \
+  $(if $(filter micro:%, $1), true)
+
 UseJtregTestHandler = \
   $(if $(filter jtreg:%, $1), true)
 
@@ -870,6 +1020,11 @@
         TEST := $(test), \
     )) \
   ) \
+  $(if $(call UseMicroTestHandler, $(test)), \
+    $(eval $(call SetupRunMicroTest, $(TEST_ID), \
+        TEST := $(test), \
+    )) \
+  ) \
   $(if $(call UseJtregTestHandler, $(test)), \
     $(eval $(call SetupRunJtregTest, $(TEST_ID), \
         TEST := $(test), \
--- a/make/autoconf/configure.ac	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/autoconf/configure.ac	Fri Nov 16 23:39:51 2018 +0100
@@ -180,6 +180,9 @@
 # Setup the JTReg Regression Test Harness.
 TOOLCHAIN_SETUP_JTREG
 
+# Setup the Java Microbenchmark Harness (JMH)
+LIB_TESTS_SETUP_JMH
+
 # Setup Jib dependency tool
 TOOLCHAIN_SETUP_JIB
 
--- a/make/autoconf/lib-tests.m4	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/autoconf/lib-tests.m4	Fri Nov 16 23:39:51 2018 +0100
@@ -55,3 +55,65 @@
   AC_SUBST(GRAALUNIT_LIB)
 ])
 
+###############################################################################
+#
+# Setup and check the Java Microbenchmark Harness
+#
+AC_DEFUN_ONCE([LIB_TESTS_SETUP_JMH],
+[
+  AC_ARG_WITH(jmh, [AS_HELP_STRING([--with-jmh],
+      [Java Microbenchmark Harness for building the OpenJDK Microbenchmark Suite])])
+
+  AC_MSG_CHECKING([for jmh (Java Microbenchmark Harness)])
+  if test "x$with_jmh" = xno || test "x$with_jmh" = x; then
+    AC_MSG_RESULT([no, disabled])
+  elif test "x$with_jmh" = xyes; then
+    AC_MSG_RESULT([no, error])
+    AC_MSG_ERROR([--with-jmh requires a directory containing all jars needed by JMH])
+  else
+    # Path specified
+    JMH_HOME="$with_jmh"
+    if test ! -d [$JMH_HOME]; then
+      AC_MSG_RESULT([no, error])
+      AC_MSG_ERROR([$JMH_HOME does not exist or is not a directory])
+    fi
+    BASIC_FIXUP_PATH([JMH_HOME])
+
+    jar_names="jmh-core jmh-generator-annprocess jopt-simple commons-math3"
+    for jar in $jar_names; do
+      found_jar_files=$($ECHO $(ls $JMH_HOME/$jar-*.jar 2> /dev/null))
+
+      if test "x$found_jar_files" = x; then
+        AC_MSG_RESULT([no])
+        AC_MSG_ERROR([--with-jmh does not contain $jar-*.jar])
+      elif ! test -e "$found_jar_files"; then
+        AC_MSG_RESULT([no])
+        AC_MSG_ERROR([--with-jmh contain multiple $jar-*.jar: $found_jar_files])
+      fi
+
+      found_jar_var_name=found_${jar//-/_}
+      eval $found_jar_var_name='"'$found_jar_files'"'
+    done
+    AC_MSG_RESULT([yes])
+
+    JMH_CORE_JAR=$found_jmh_core
+    JMH_GENERATOR_JAR=$found_jmh_generator_annprocess
+    JMH_JOPT_SIMPLE_JAR=$found_jopt_simple
+    JMH_COMMONS_MATH_JAR=$found_commons_math3
+
+
+    if [ [[ "$JMH_CORE_JAR" =~ jmh-core-(.*)\.jar$ ]] ] ; then
+      JMH_VERSION=${BASH_REMATCH[[1]]}
+    else
+      JMH_VERSION=unknown
+    fi
+
+    AC_MSG_NOTICE([JMH core version: $JMH_VERSION])
+  fi
+
+  AC_SUBST(JMH_CORE_JAR)
+  AC_SUBST(JMH_GENERATOR_JAR)
+  AC_SUBST(JMH_JOPT_SIMPLE_JAR)
+  AC_SUBST(JMH_COMMONS_MATH_JAR)
+  AC_SUBST(JMH_VERSION)
+])
--- a/make/autoconf/spec.gmk.in	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/autoconf/spec.gmk.in	Fri Nov 16 23:39:51 2018 +0100
@@ -355,6 +355,12 @@
 LIBFFI_LIB_FILE:=@LIBFFI_LIB_FILE@
 GRAALUNIT_LIB := @GRAALUNIT_LIB@
 
+JMH_CORE_JAR := @JMH_CORE_JAR@
+JMH_GENERATOR_JAR := @JMH_GENERATOR_JAR@
+JMH_JOPT_SIMPLE_JAR := @JMH_JOPT_SIMPLE_JAR@
+JMH_COMMONS_MATH_JAR := @JMH_COMMONS_MATH_JAR@
+JMH_VERSION := @JMH_VERSION@
+
 # Source file for cacerts
 CACERTS_FILE=@CACERTS_FILE@
 
--- a/make/common/FindTests.gmk	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/common/FindTests.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -72,6 +72,9 @@
 # Add Gtest
 ALL_NAMED_TESTS += gtest
 
+# Add microbenchmarks
+ALL_NAMED_TESTS += micro
+
 # Find make test targets
 MAKE_TEST_TARGETS := $(shell $(MAKE) -s --no-print-directory $(MAKE_ARGS) \
     SPEC=$(SPEC) -f $(TOPDIR)/test/make/TestMake.gmk print-targets)
--- a/make/common/JarArchive.gmk	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/common/JarArchive.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -43,6 +43,7 @@
 #       For this to work, the source files must exist when the makefile is
 #       parsed.
 #   SRCS:=List of directories in where to find files to add to archive
+#   BIN:=Directory where to store build control files
 #   SUFFIXES:=File suffixes to include in jar
 #   INCLUDES:=List of directories/packages in SRCS that should be included
 #   EXCLUDES:=List of directories/packages in SRCS that should be excluded
@@ -62,10 +63,11 @@
 
   $1_JARMAIN:=$(strip $$($1_JARMAIN))
   $1_JARNAME:=$$(notdir $$($1_JAR))
-  $1_MANIFEST_FILE:=$$(dir $$($1_JAR))_the.$$($1_JARNAME)_manifest
-  $1_DELETESS_FILE:=$$(dir $$($1_JAR))_the.$$($1_JARNAME)_deletess
-  $1_DELETES_FILE:=$$(dir $$($1_JAR))_the.$$($1_JARNAME)_deletes
-  $1_BIN:=$$(dir $$($1_JAR))
+  $1_JAR_OUTPUT_DIR := $$(patsubst %/, %, $$(dir $$($1_JAR)))
+  $$(call SetIfEmpty, $1_BIN, $$($1_JAR_OUTPUT_DIR))
+  $1_MANIFEST_FILE:=$$($1_BIN)/_the.$$($1_JARNAME)_manifest
+  $1_DELETESS_FILE:=$$($1_BIN)/_the.$$($1_JARNAME)_deletess
+  $1_DELETES_FILE:=$$($1_BIN)/_the.$$($1_JARNAME)_deletes
   $$(call SetIfEmpty, $1_JAR_CMD, $$(JAR))
 
   ifeq (,$$($1_SUFFIXES))
@@ -231,11 +233,12 @@
   $1_VARDEPS := $$($1_JAR_CMD) $$($1_JAR_CREATE_OPTIONS) $$($1_MANIFEST) \
       $$($1_JARMAIN) $$($1_EXTRA_MANIFEST_ATTR) $$($1_ORIG_DEPS) $$($1_SRCS) \
       $$($1_INCLUDES) $$($1_EXCLUDES) $$($1_EXCLUDE_FILES) $$($1_EXTRA_FILES)
-  $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$(dir $$($1_JAR))_the.$$($1_JARNAME).vardeps)
+  $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_BIN)/_the.$$($1_JARNAME).vardeps)
 
   # Here is the rule that creates/updates the jar file.
   $$($1_JAR) : $$($1_DEPENDENCIES) $$($1_MANIFEST) $$($1_VARDEPS_FILE)
 	$$(call MakeTargetDir)
+	$$(call MakeDir, $$($1_BIN))
 	$$($1_GREP_INCLUDE_OUTPUT)
 	$$($1_GREP_EXCLUDE_OUTPUT)
         # If the vardeps file is part of the newer prereq list, it means that
--- a/make/conf/jib-profiles.js	Fri Nov 16 13:23:50 2018 -0500
+++ b/make/conf/jib-profiles.js	Fri Nov 16 23:39:51 2018 +0100
@@ -243,7 +243,7 @@
 
     // These are the base setttings for all the main build profiles.
     common.main_profile_base = {
-        dependencies: ["boot_jdk", "gnumake", "jtreg", "jib", "autoconf"],
+        dependencies: ["boot_jdk", "gnumake", "jtreg", "jib", "autoconf", "jmh"],
         default_make_targets: ["product-bundles", "test-bundles"],
         configure_args: concat(["--enable-jtreg-failure-handler"],
             "--with-exclude-translations=de,es,fr,it,ko,pt_BR,sv,ca,tr,cs,sk,ja_JP_A,ja_JP_HA,ja_JP_HI,ja_JP_I,zh_TW,zh_HK",
@@ -892,6 +892,12 @@
             environment_path: input.get("jtreg", "install_path") + "/jtreg/bin"
         },
 
+        jmh: {
+            organization: common.organization,
+            ext: "tar.gz",
+            revision: "1.21+1.0"
+        },
+
         gnumake: {
             organization: common.organization,
             ext: "tar.gz",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/devkit/createJMHBundle.sh	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,50 @@
+#!/bin/bash -e
+#
+# Copyright (c) 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# 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.
+#
+# Create a bundle in the build directory, containing what's needed to
+# build and run JMH microbenchmarks from the OpenJDK build.
+
+JMH_VERSION=1.21
+COMMONS_MATH3_VERSION=3.2
+JOPT_SIMPLE_VERSION=4.6
+
+BUNDLE_NAME=jmh-$JMH_VERSION.tar.gz
+
+SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
+BUILD_DIR="${SCRIPT_DIR}/../../build/jmh"
+JAR_DIR="$BUILD_DIR/jars"
+
+mkdir -p $BUILD_DIR $JAR_DIR
+cd $JAR_DIR
+rm -f *
+
+wget http://central.maven.org/maven2/org/apache/commons/commons-math3/$COMMONS_MATH3_VERSION/commons-math3-$COMMONS_MATH3_VERSION.jar
+wget http://central.maven.org/maven2/net/sf/jopt-simple/jopt-simple/$JOPT_SIMPLE_VERSION/jopt-simple-$JOPT_SIMPLE_VERSION.jar
+wget http://central.maven.org/maven2/org/openjdk/jmh/jmh-core/$JMH_VERSION/jmh-core-$JMH_VERSION.jar
+wget http://central.maven.org/maven2/org/openjdk/jmh/jmh-generator-annprocess/$JMH_VERSION/jmh-generator-annprocess-$JMH_VERSION.jar
+
+tar -cvzf ../$BUNDLE_NAME *
+
+echo "Created $BUILD_DIR/$BUNDLE_NAME"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/test/BuildMicrobenchmark.gmk	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+#
+# Copyright (c) 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# 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.
+#
+
+# This must be the first rule
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+ifeq ($(JMH_CORE_JAR), )
+  $(info Error: JMH is missing. Please use configure --with-jmh.)
+  $(error Cannot continue)
+endif
+
+#### Variables
+
+MICROBENCHMARK_SRC := $(TOPDIR)/test/micro
+MICROBENCHMARK_JAR := $(IMAGES_OUTPUTDIR)/test/micro/benchmarks.jar
+
+MICROBENCHMARK_OUTPUT := $(SUPPORT_OUTPUTDIR)/test/micro
+MICROBENCHMARK_CLASSES := $(MICROBENCHMARK_OUTPUT)/classes
+MICROBENCHMARK_JAR_BIN := $(MICROBENCHMARK_OUTPUT)/jar
+
+JMH_UNPACKED_DIR := $(MICROBENCHMARK_OUTPUT)/jmh_jars
+JMH_UNPACKED_JARS_DONE := $(JMH_UNPACKED_DIR)/_unpacked.marker
+
+# External dependencies
+JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR)
+JMH_RUNTIME_JARS := $(JMH_CORE_JAR) $(JMH_COMMONS_MATH_JAR) $(JMH_JOPT_SIMPLE_JAR)
+
+MICROBENCHMARK_CLASSPATH := $(call PathList, $(JMH_COMPILE_JARS))
+
+###
+
+# Need double \n to get new lines and no trailing spaces
+MICROBENCHMARK_MANIFEST := Build: $(FULL_VERSION)\n\
+\nJMH-Version: $(JMH_VERSION)\n\
+\nName: OpenJDK Microbenchmark Suite
+
+
+#### Compile Targets
+
+# Building microbenchmark requires the jdk.unsupported and java.management modules,
+# and to have sjavac disabled.
+$(eval $(call SetupJavaCompiler, MICROBENCHMARK_JAVA_COMPILER, \
+    JVM := $(JAVA) --add-modules jdk.unsupported --limit-modules java.management, \
+    JAVAC := $(NEW_JAVAC), \
+    DISABLE_SJAVAC := true, \
+    FLAGS := --upgrade-module-path $(JDK_OUTPUTDIR)/modules --system none $(DISABLE_WARNINGS), \
+    SERVER_DIR := $(SJAVAC_SERVER_DIR), \
+    SERVER_JVM := $(SJAVAC_SERVER_JAVA), \
+))
+
+# Build microbenchmark suite for the current JDK
+$(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
+    SETUP := MICROBENCHMARK_JAVA_COMPILER, \
+    ADD_JAVAC_FLAGS := -cp $(MICROBENCHMARK_CLASSPATH) -Xlint -Werror, \
+    SRC := $(MICROBENCHMARK_SRC), \
+    BIN := $(MICROBENCHMARK_CLASSES), \
+))
+
+$(BUILD_JDK_MICROBENCHMARK): $(JMH_COMPILE_JARS)
+
+# Unpacking dependencies for inclusion in the benchmark JARs
+$(JMH_UNPACKED_JARS_DONE): $(JMH_RUNTIME_JARS)
+	$(RM) -r $(JMH_UNPACKED_DIR)
+	$(MKDIR) -p $(JMH_UNPACKED_DIR)
+	$(foreach jar, $(JMH_RUNTIME_JARS), \
+            $$($(UNZIP) -oq $(jar) -d $(JMH_UNPACKED_DIR)))
+	$(RM) -r $(JMH_UNPACKED_DIR)/META-INF
+	$(RM) $(JMH_UNPACKED_DIR)/*.xml
+	$(TOUCH) $@
+
+# Create benchmarks JAR file with benchmarks for both the old and new JDK
+$(eval $(call SetupJarArchive, BUILD_JDK_JAR, \
+    DEPENDENCIES := $(BUILD_JDK_MICROBENCHMARK) $(JMH_UNPACKED_JARS_DONE), \
+    SRCS := $(MICROBENCHMARK_CLASSES) $(JMH_UNPACKED_DIR), \
+    BIN := $(MICROBENCHMARK_JAR_BIN), \
+    SUFFIXES := .*, \
+    EXCLUDE_FILES:= _the.BUILD_JDK_MICROBENCHMARK_batch \
+        _the.BUILD_JDK_MICROBENCHMARK.vardeps _unpacked.marker, \
+    EXTRA_MANIFEST_ATTR := $(MICROBENCHMARK_MANIFEST), \
+    JARMAIN := org.openjdk.jmh.Main, \
+    JAR := $(MICROBENCHMARK_JAR), \
+))
+
+all: $(MICROBENCHMARK_JAR)
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/BlackholedOutputStream.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BlackholedOutputStream extends OutputStream {
+
+    private final Blackhole bh;
+
+    public BlackholedOutputStream(Blackhole bh) {
+        this.bh = bh;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        bh.consume(b);
+    }
+
+    @Override
+    public void write(byte[] b) throws IOException {
+        bh.consume(b);
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        bh.consume(b);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileChannelRead.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileChannelRead {
+
+    @Param("1000000")
+    private int fileSize;
+
+    private File f;
+    private FileChannel fc;
+    private ByteBuffer bb;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        f = File.createTempFile("FileChannelReadBench", ".bin");
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            for (int i = 0; i < fileSize; i++) {
+                fos.write((byte) i);
+            }
+        }
+        bb = ByteBuffer.allocate(1);
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException {
+        f.delete();
+    }
+
+    @Setup(Level.Iteration)
+    public void beforeIteration() throws IOException {
+        fc = FileChannel.open(f.toPath(), StandardOpenOption.READ);
+    }
+
+    @TearDown(Level.Iteration)
+    public void afterIteration() throws IOException {
+        fc.close();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        int ret = fc.read(bb);
+        bb.flip();
+        if (ret == -1) {
+            // start over
+            fc.position(0);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileChannelWrite.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileChannelWrite {
+
+    @Param("1000000")
+    private int fileSize;
+
+    private File f;
+    private FileChannel fc;
+    private ByteBuffer bb;
+    private int count;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        f = File.createTempFile("FileChannelWriteBench", ".bin");
+        bb = ByteBuffer.allocate(1);
+        bb.put((byte) 47);
+        bb.flip();
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException {
+        f.delete();
+    }
+
+    @Setup(Level.Iteration)
+    public void beforeIteration() throws IOException {
+        fc = FileChannel.open(f.toPath(), StandardOpenOption.WRITE);
+        count = 0;
+    }
+
+    @TearDown(Level.Iteration)
+    public void afterIteration() throws IOException {
+        fc.close();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        fc.write(bb);
+        bb.flip();
+        count++;
+        if (count >= fileSize) {
+            // start over
+            fc.position(0);
+            count = 0;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileRead.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileRead {
+
+    @Param("1000000")
+    private int fileSize;
+
+    private File f;
+    private FileInputStream fis;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        f = File.createTempFile("FileReadBench", ".bin");
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            for (int i = 0; i < fileSize; i++) {
+                fos.write((byte) i);
+            }
+        }
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException {
+        f.delete();
+    }
+
+    @Setup(Level.Iteration)
+    public void beforeIteration() throws FileNotFoundException {
+        fis = new FileInputStream(f);
+    }
+
+    @TearDown(Level.Iteration)
+    public void afterIteration() throws IOException {
+        fis.close();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        int ret = fis.read();
+        if (ret == -1) {
+            // start over
+            fis.close();
+            fis = new FileInputStream(f);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/FileWrite.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class FileWrite {
+
+    @Param("1000000")
+    private int fileSize;
+
+    private File f;
+    private FileOutputStream fos;
+    private long count;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        f = File.createTempFile("FileWriteBench", ".bin");
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException {
+        f.delete();
+    }
+
+    @Setup(Level.Iteration)
+    public void beforeIteration() throws FileNotFoundException {
+        fos = new FileOutputStream(f);
+    }
+
+    @TearDown(Level.Iteration)
+    public void afterIteration() throws IOException {
+        fos.close();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        fos.write((byte) count);
+        count++;
+        if (count >= fileSize) {
+            // restart
+            fos.close();
+            fos = new FileOutputStream(f);
+            count = 0;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/ObjectStreamClasses.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A micro benchmark used to measure the performance impact from multi threaded access to ObjectStreamClass.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ObjectStreamClasses {
+
+    public Class<?>[] classes;
+
+    @Setup
+    public void setup() {
+        LinkedList<Class> queue = new LinkedList<Class>();
+        int i = 0;
+        while (true) {
+            // Loop until we get a ClassNotFoundException
+            // Maybe rewrite this considering the fact that there are 29
+            // inner classes available?
+            try {
+                Class clazz = Class.forName(ObjectStreamClasses.class.getName() + "$SerializableClass" + i++);
+                queue.add(clazz);
+            } catch (ClassNotFoundException e) {
+                break;
+            }
+        }
+        classes = new Class[queue.size()];
+
+        // Make ObjectStreamClass load all classes into the static map
+        i = 0;
+        while (!queue.isEmpty()) {
+            classes[i] = (Class) queue.remove();
+            i++;
+        }
+    }
+
+    /**
+     * Tests the static lookup function. Depending on JRE version the internal behavior is different but the general
+     * behavior is a synchronized call to some sort of static container.
+     */
+    @Benchmark
+    public void testLookup(Blackhole bh) {
+        for (Class<?> klass : classes) {
+            bh.consume(ObjectStreamClass.lookup(klass));
+        }
+    }
+
+    static class SerializableClass0 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass1 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass2 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass3 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass4 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass5 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass6 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass7 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass8 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass9 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass10 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass11 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass12 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass13 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass14 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass15 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass16 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass17 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass18 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass19 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass20 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass21 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass22 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass23 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass24 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass25 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass26 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass27 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass28 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    static class SerializableClass29 extends SerializableClass {
+        private static final long serialVersionUID = 1L;
+    }
+
+    @SuppressWarnings("unused")
+    private static class SerializableClass implements Serializable {
+
+        private static final long serialVersionUID = 6107539118220989250L;
+        public Object objectField00 = new Object();
+        public Object objectField01 = new Object();
+        public Object objectField02 = new Object();
+        public Object objectField03 = new Object();
+        public Object objectField04 = new Object();
+        public Object objectField05 = new Object();
+        public Object objectField06 = new Object();
+        public Object objectField07 = new Object();
+        public Object objectField08 = new Object();
+        public Object objectField09 = new Object();
+        public Object objectField10 = new Object();
+        public Object objectField11 = new Object();
+        public Object objectField12 = new Object();
+        public Object objectField13 = new Object();
+        public Object objectField14 = new Object();
+        public Object objectField15 = new Object();
+        public Object objectField16 = new Object();
+        public Object objectField17 = new Object();
+        public Object objectField18 = new Object();
+        public Object objectField19 = new Object();
+        public Object objectField20 = new Object();
+        public Object objectField21 = new Object();
+        public Object objectField22 = new Object();
+        public Object objectField23 = new Object();
+        public Object objectField24 = new Object();
+        public Object objectField25 = new Object();
+        public Object objectField26 = new Object();
+        public Object objectField27 = new Object();
+        public Object objectField28 = new Object();
+        public Object objectField29 = new Object();
+
+        SerializableClass() {
+            super();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class RandomAccessRead {
+
+    @Param("1000000")
+    private int fileSize;
+
+    private RandomAccessFile raf;
+    private long offset;
+    private int deltaIndex;
+    private int[] deltas;
+    private File f;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        f = File.createTempFile("RandomAccessBench", ".bin");
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            for (int i = 0; i < fileSize; i++) {
+                fos.write((byte) i);
+            }
+        }
+        deltas = new int[]{1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException {
+        f.delete();
+    }
+
+    @Setup(Level.Iteration)
+    public void beforeIteration() throws IOException {
+        raf = new RandomAccessFile(f, "rw");
+        offset = 0;
+        deltaIndex = 0;
+    }
+
+    @TearDown(Level.Iteration)
+    public void afterIteration() throws IOException {
+        raf.close();
+    }
+
+    @Benchmark
+    public int test() throws IOException {
+        offset = offset + deltas[deltaIndex];
+        if (offset >= fileSize) {
+            offset = 0;
+        }
+        deltaIndex++;
+        if (deltaIndex >= deltas.length) {
+            deltaIndex = 0;
+        }
+        raf.seek(offset);
+        return raf.read();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/RandomAccessWrite.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on disk subsystem performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class RandomAccessWrite {
+
+    @Param("1000000")
+    private int fileSize;
+
+    private File f;
+    private RandomAccessFile raf;
+    private long offset;
+    private int deltaIndex;
+    private int[] deltas;
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        f = File.createTempFile("RandomAccessBench", ".bin");
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            for (int i = 0; i < fileSize; i++) {
+                fos.write((byte) i);
+            }
+        }
+        deltas = new int[]{1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException {
+        f.delete();
+    }
+
+    @Setup(Level.Iteration)
+    public void beforeIteration() throws IOException {
+        raf = new RandomAccessFile(f, "rw");
+        offset = 0;
+        deltaIndex = 0;
+    }
+
+    @TearDown(Level.Iteration)
+    public void afterIteration() throws IOException {
+        raf.close();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        offset = offset + deltas[deltaIndex];
+        if (offset >= fileSize) {
+            offset = 0;
+        }
+        deltaIndex++;
+        if (deltaIndex >= deltas.length) {
+            deltaIndex = 0;
+        }
+        raf.seek(offset);
+        raf.write((byte) offset);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/SerializationWriteReplace.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.bench.java.io.BlackholedOutputStream;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SerializationWriteReplace {
+
+    private BlackholedOutputStream bos;
+    private ObjectOutputStream os;
+
+    @Setup
+    public void setupStreams(Blackhole bh) throws IOException {
+        bos = new BlackholedOutputStream(bh);
+        os = new ObjectOutputStream(bos);
+    }
+
+    @TearDown
+    public void downStreams() throws IOException {
+        os.close();
+        bos.close();
+        os = null;
+        bos = null;
+    }
+
+    @Benchmark
+    public void writeReplace() throws IOException, ClassNotFoundException {
+        os.writeObject(new Class2());
+    }
+
+    public abstract static class Base implements Serializable {
+        private static final long serialVersionUID = 1L;
+    }
+
+    public static class Class1 extends Base {
+        private static final long serialVersionUID = 2L;
+    }
+
+    public static class Class2 extends Class1 {
+        private static final long serialVersionUID = 3L;
+        Object writeReplace() throws ObjectStreamException {
+            return new Class3();
+        }
+    }
+
+    public static class Class3 extends Base {
+        private static final long serialVersionUID = 4L;
+        private String tuto = "tuto";
+        private byte b = (byte) 0xff;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/io/UTF8.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.io;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring UTF8 char operations.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class UTF8 {
+
+    private String s;
+    private BlackholedOutputStream bos;
+    private DataOutputStream dos;
+
+    @Setup
+    public void setup(Blackhole bh) {
+        bos = new BlackholedOutputStream(bh);
+        dos = new DataOutputStream(bos);
+        s = "abcdefghijklmnopqrstuvxyz0123456789";
+    }
+
+    @Benchmark
+    public void testCharConversion() throws IOException {
+        dos.writeUTF(s);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopy.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring System.arraycopy in different ways.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopy {
+
+    private static final byte[] TEST_BYTES = "HTTP/1.0".getBytes();
+    private static final char[] TEST_CHARS = new char[46];
+    private static final Object[] TEST_OBJECTS = new Object[200];  // Uses a minimum of 160 internal positions for internal copying
+
+    // a length which the compiler cannot prove is a constant
+    public static int nonConstCharLength = TEST_CHARS.length;
+    public static int nonConstByteLength = TEST_BYTES.length;
+    public static int nonConstObjectLength = TEST_OBJECTS.length;
+
+    // Use this array to copy objects in.
+    public char[] dummyCharArray = new char[TEST_CHARS.length];
+    public byte[] dummyByteArray = new byte[TEST_BYTES.length];
+    public Object[] dummyObjectArray = new Object[TEST_OBJECTS.length];
+
+    @Setup
+    public void setup() {
+        for (int i = 0; i < TEST_OBJECTS.length; i++) {
+            TEST_OBJECTS[i] = new Object();
+            dummyObjectArray[i] = new Object();
+        }
+    }
+
+    /**
+     * This test case do the same work as testArrayCopy. We should make sure
+     * testArrayCopy is equally fast or better. Compare the two and you measure
+     * the system call versus explicit copy for-loop.
+     */
+    @Benchmark
+    public void copyLoop() {
+        for (int j = 0; j < dummyByteArray.length; j++) {
+            dummyByteArray[j] = TEST_BYTES[j];
+        }
+    }
+
+    /**
+     * Test that we can optimize away the code since it should not have any side
+     * effects
+     */
+    @Benchmark
+    public void copyLoopLocalArray() {
+        byte[] localDummyByteArray = new byte[TEST_BYTES.length];
+        for (int j = 0; j < localDummyByteArray.length; j++) {
+            localDummyByteArray[j] = TEST_BYTES[j];
+        }
+    }
+
+    /**
+     * This test case do the same work as testArrayCopy. We should make sure
+     * testArrayCopy is equally fast or better. Compare the two and you measure
+     * the system call versus explicit copy for-loop.
+     * <p/>
+     * Uses non-provable constant length.
+     */
+    @Benchmark
+    public void copyLoopNonConst() {
+        for (int i = 0; i < nonConstByteLength; i++) {
+            dummyByteArray[i] = TEST_BYTES[i];
+        }
+    }
+
+    /**
+     * This test case do the same work as testCopyLoop. We should make sure
+     * testArrayCopy is equally fast or better. Compare the two and you measure
+     * the system call versus explicit copy for-loop.
+     */
+    @Benchmark
+    public void arrayCopy() {
+        System.arraycopy(TEST_BYTES, 0, dummyByteArray, 0, dummyByteArray.length);
+    }
+
+    /**
+     * Test that we can optimize away the code since it should not have any side
+     * effects
+     */
+    @Benchmark
+    public void arrayCopyLocalArray() {
+        byte[] localDummyByteArray = new byte[TEST_BYTES.length];
+        System.arraycopy(TEST_BYTES, 0, localDummyByteArray, 0, localDummyByteArray.length);
+    }
+
+    /**
+     * This test case do the same work as testCopyLoop. We should make sure
+     * testArrayCopy is equally fast or better. Compare the two and you measure
+     * the system call versus explicit copy for-loop.
+     * <p/>
+     * Uses non-provable constant length.
+     */
+    @Benchmark
+    public void arrayCopyNonConst() {
+        System.arraycopy(TEST_BYTES, 0, dummyByteArray, 0, nonConstByteLength);
+    }
+
+    @Benchmark
+    public void arrayCopyChar() {
+        System.arraycopy(TEST_CHARS, 0, dummyCharArray, 0, dummyCharArray.length);
+    }
+
+    @Benchmark
+    public void arrayCopyCharNonConst() {
+        System.arraycopy(TEST_CHARS, 0, dummyCharArray, 0, nonConstCharLength);
+    }
+
+    @Benchmark
+    public void arrayCopyObject() {
+        System.arraycopy(TEST_OBJECTS, 0, dummyObjectArray, 0, dummyObjectArray.length);
+    }
+
+    @Benchmark
+    public void arrayCopyObjectNonConst() {
+        System.arraycopy(TEST_OBJECTS, 0, dummyObjectArray, 0, nonConstObjectLength);
+    }
+
+    /**
+     * This test copies inside a object array, that is same source array as dest
+     * array. Copies backwards in the array.
+     */
+    @Benchmark
+    @OperationsPerInvocation(40)
+    public void arrayCopyObjectSameArraysBackward() {
+        for (int i = 0; i < 40; i++) {
+            System.arraycopy(dummyObjectArray, i, dummyObjectArray, i + 40, 80);
+        }
+    }
+
+    /**
+     * This test copies inside a object array, that is same source array as dest
+     * array. Copies forward in the array. There is a special version for this
+     * in JRockit.
+     */
+    @Benchmark
+    @OperationsPerInvocation(40)
+    public void arrayCopyObjectSameArraysForward() {
+        for (int i = 0; i < 40; i++) {
+            System.arraycopy(dummyObjectArray, i + 40, dummyObjectArray, i, 80);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyAligned.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring aligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyAligned {
+
+    @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+    int length;
+
+    int fromPos, toPos;
+    byte[] fromByteArr, toByteArr;
+    char[] fromCharArr, toCharArr;
+    int[] fromIntArr, toIntArr;
+    long[] fromLongArr, toLongArr;
+
+    @Setup
+    public void setup() {
+        // Both positions aligned
+        fromPos = 8;
+        toPos = 8;
+
+        fromByteArr = new byte[1210];
+        toByteArr = new byte[1210];
+        fromCharArr = new char[1210];
+        toCharArr = new char[1210];
+        fromIntArr = new int[1210];
+        toIntArr = new int[1210];
+        fromLongArr = new long[1210];
+        toLongArr = new long[1210];
+    }
+
+    @Benchmark
+    public void testByte() {
+        System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testChar() {
+        System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testInt() {
+        System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testLong() {
+        System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedBoth.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring Unaligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyUnalignedBoth {
+
+    @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+    int length;
+
+    int fromPos, toPos;
+    byte[] fromByteArr, toByteArr;
+    char[] fromCharArr, toCharArr;
+    int[] fromIntArr, toIntArr;
+    long[] fromLongArr, toLongArr;
+
+    @Setup
+    public void setup() {
+        // Both positions Unaligned
+        fromPos = 9;
+        toPos = 10;
+
+        fromByteArr = new byte[1210];
+        toByteArr = new byte[1210];
+        fromCharArr = new char[1210];
+        toCharArr = new char[1210];
+        fromIntArr = new int[1210];
+        toIntArr = new int[1210];
+        fromLongArr = new long[1210];
+        toLongArr = new long[1210];
+    }
+
+    @Benchmark
+    public void testByte() {
+        System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testChar() {
+        System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testInt() {
+        System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testLong() {
+        System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedDst.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring Unaligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyUnalignedDst {
+
+    @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+    int length;
+
+    int fromPos, toPos;
+    byte[] fromByteArr, toByteArr;
+    char[] fromCharArr, toCharArr;
+    int[] fromIntArr, toIntArr;
+    long[] fromLongArr, toLongArr;
+
+    @Setup
+    public void setup() {
+        // Dst position Unaligned
+        fromPos = 8;
+        toPos = 9;
+
+        fromByteArr = new byte[1210];
+        toByteArr = new byte[1210];
+        fromCharArr = new char[1210];
+        toCharArr = new char[1210];
+        fromIntArr = new int[1210];
+        toIntArr = new int[1210];
+        fromLongArr = new long[1210];
+        toLongArr = new long[1210];
+    }
+
+    @Benchmark
+    public void testByte() {
+        System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testChar() {
+        System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testInt() {
+        System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testLong() {
+        System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ArrayCopyUnalignedSrc.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring Unaligned System.arraycopy.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayCopyUnalignedSrc {
+
+    @Param({"1", "3", "5", "10", "20", "70", "150", "300", "600", "1200"})
+    int length;
+
+    int fromPos, toPos;
+    byte[] fromByteArr, toByteArr;
+    char[] fromCharArr, toCharArr;
+    int[] fromIntArr, toIntArr;
+    long[] fromLongArr, toLongArr;
+
+    @Setup
+    public void setup() {
+        // Dst position Unaligned
+        fromPos = 5;
+        toPos = 8;
+
+        fromByteArr = new byte[1210];
+        toByteArr = new byte[1210];
+        fromCharArr = new char[1210];
+        toCharArr = new char[1210];
+        fromIntArr = new int[1210];
+        toIntArr = new int[1210];
+        fromLongArr = new long[1210];
+        toLongArr = new long[1210];
+    }
+
+    @Benchmark
+    public void testByte() {
+        System.arraycopy(fromByteArr, fromPos, toByteArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testChar() {
+        System.arraycopy(fromCharArr, fromPos, toCharArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testInt() {
+        System.arraycopy(fromIntArr, fromPos, toIntArr, toPos, length);
+    }
+
+    @Benchmark
+    public void testLong() {
+        System.arraycopy(fromLongArr, fromPos, toLongArr, toPos, length);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ClassForName.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.lang.Class.forName() with various inputs.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ClassForName {
+
+    private String aName, bName, cName;
+
+    @Setup
+    public void setup() {
+        aName = A.class.getName();
+        bName = B.class.getName();
+        cName = C.class.getName();
+    }
+
+    /** Calls Class.forName with the same name over and over again. The class asked for exists. */
+    @Benchmark
+    public void test1(Blackhole bh) throws ClassNotFoundException {
+        bh.consume(Class.forName(aName));
+    }
+
+    /** Calls Class.forName with the three different names over and over again. All classes asked for exist. */
+    @Benchmark
+    public void test3(Blackhole bh) throws ClassNotFoundException {
+        bh.consume(Class.forName(aName));
+        bh.consume(Class.forName(bName));
+        bh.consume(Class.forName(cName));
+    }
+
+    static class A {}
+    static class B {}
+    static class C {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Clone.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.BitSet;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Clone {
+
+    private BitSet testObj1;
+    private Date testObj2;
+    private char[] testObj3;
+
+    @Setup
+    public void setup() {
+        testObj1 = new BitSet(10);
+        testObj2 = new Date();
+        testObj3 = new char[5];
+    }
+
+    /** Calls clone on three different types. The types are java.util.BitSet, java.util.Date and char[]. */
+    @Benchmark
+    public void cloneThreeDifferent(Blackhole bh) {
+        bh.consume(testObj1.clone());
+        bh.consume(testObj2.clone());
+        bh.consume(testObj3.clone());
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/FloatingDecimal.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for sun.misc.FloatingDecimal. Performs floating point number to String conversions.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class FloatingDecimal {
+
+    private double[] randomArray, twoDecimalsArray, integerArray;
+    private static final int TESTSIZE = 1000;
+
+    @Setup
+    public void setup() {
+        Random r = new Random(1123);
+        randomArray = new double[TESTSIZE];
+        twoDecimalsArray = new double[TESTSIZE];
+        integerArray = new double[TESTSIZE];
+        for (int i = 0; i < TESTSIZE; i++) {
+            randomArray[i] = r.nextDouble() * 10000.0D;
+            twoDecimalsArray[i] = ((double) (10000 - r.nextInt(20000))) / 100;
+            integerArray[i] = (double) (100 - r.nextInt(200));
+        }
+    }
+
+    /** Tests Double.toString on double values generated from Random.nextDouble() */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void randomDoubleToString(Blackhole bh) {
+        for (double d : randomArray) {
+            bh.consume(Double.toString(d));
+        }
+    }
+
+    /** Tests Double.toString on double values that are integers between -100 and 100. */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void integerDoubleToString(Blackhole bh) {
+        for (double d : integerArray) {
+            bh.consume(Double.toString(d));
+        }
+    }
+
+    /** Tests Double.toString on double values that are between -100 and 100 and have two decimal digits. */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void twoDecimalsDoubleToString(Blackhole bh) {
+        for (double d : twoDecimalsArray) {
+            bh.consume(Double.toString(d));
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/GetStackTrace.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests Thread.getStackTrace()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class GetStackTrace {
+
+    @Benchmark
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public StackTraceElement[] depth0() {
+        return Thread.currentThread().getStackTrace();
+    }
+
+    @Benchmark
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public StackTraceElement[] depth1() {
+        return depth0();
+    }
+
+    @Benchmark
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public StackTraceElement[] depth2() {
+        return depth1();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Integers.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.lang.Integer
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class Integers {
+
+    @Param("500")
+    private int size;
+
+    private String[] strings;
+
+    @Setup
+    public void setup() {
+        Random r = new Random(0);
+        strings = new String[size];
+        for (int i = 0; i < size; i++) {
+            strings[i] = "" + (r.nextInt(10000) - 5000);
+        }
+    }
+
+    @Benchmark
+    public void parseInt(Blackhole bh) {
+        for (String s : strings) {
+            bh.consume(Integer.parseInt(s));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Longs.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class Longs {
+
+    @Param("500")
+    private int size;
+
+    private long[] longArraySmall;
+    private long[] longArrayBig;
+
+    @Setup
+    public void setup() {
+        longArraySmall = new long[size];
+        longArrayBig = new long[size];
+        for (int i = 0; i < size; i++) {
+            longArraySmall[i] = 100L * i + i + 103L;
+            longArrayBig[i] = ((100L * i + i) << 32) + 4543 + i * 4;
+        }
+    }
+
+    /** Performs toString on a bunch of java.lang.Long:s, all with small values, just a couple of digits. */
+    @Benchmark
+    @Threads(Threads.MAX)
+    public void toStringSmall(Blackhole bh) {
+        for (long value : longArraySmall) {
+            bh.consume(Long.toString(value));
+        }
+    }
+
+    /** Performs toString on a bunch of java.lang.Long:s, all with large values, around 10 digits. */
+    @Benchmark
+    @Threads(Threads.MAX)
+    public void toStringBig(Blackhole bh) {
+        for (long value : longArrayBig) {
+            bh.consume(Long.toString(value));
+        }
+    }
+
+    /*
+     * Have them public to avoid total unrolling
+     */
+    public int innerLoops = 1500;
+
+    @Benchmark
+    @Threads(Threads.MAX)
+    public long repetitiveSubtraction() {
+        long x = 127, dx = 0;
+
+        for (int i = 0; i < innerLoops; i++) {
+            x -= dx;
+            dx = (dx - x);
+        }
+        return x;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/NewInstance.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring java.lang.Class.newInstance speed.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class NewInstance {
+
+    public Class<?>[] samePublicClasses;
+    public Class<?>[] differentPublicClasses;
+    public Class<?>[] differentPublicClassesConstant;
+    public Class<?>[] sameProtectedClasses;
+    public Class<?>[] differentProtectedClasses;
+
+    @Setup
+    public void setup() {
+        samePublicClasses = new Class<?>[]{Apub.class, Apub.class, Apub.class};
+        differentPublicClasses = new Class<?>[]{Apub.class, Bpub.class, Cpub.class};
+        differentPublicClassesConstant = new Class<?>[]{Apub.class, Bpub.class, Cpub.class};
+        sameProtectedClasses = new Class<?>[]{Apro.class, Apro.class, Apro.class};
+        differentProtectedClasses = new Class<?>[]{Apro.class, Bpro.class, Cpro.class};
+    }
+
+    /**
+     * Performs Class.newInstance on the same class over and over again. That it is the same class is not provable at
+     * compile time. The class is protected.
+     */
+    @Benchmark
+    public void threeSameProtected(Blackhole bh) throws IllegalAccessException, InstantiationException {
+        for (Class<?> cl : sameProtectedClasses) {
+            bh.consume(cl.newInstance());
+        }
+    }
+
+    /**
+     * Performs Class.newInstance on three different classes, just allocating one instance of one class at a time. The
+     * classes are all protected.
+     */
+    @Benchmark
+    public void threeDifferentProtected(Blackhole bh) throws IllegalAccessException, InstantiationException {
+        for (Class<?> cl : differentProtectedClasses) {
+            bh.consume(cl.newInstance());
+        }
+    }
+
+    /**
+     * Performs Class.newInstance on the same class over and over again. That it is the same class is not provable at
+     * compile time. The class is public.
+     */
+    @Benchmark
+    public void threeSamePublic(Blackhole bh) throws IllegalAccessException, InstantiationException {
+        for (Class<?> cl : samePublicClasses) {
+            bh.consume(cl.newInstance());
+        }
+    }
+
+    /**
+     * Performs Class.newInstance on three different classes, just allocating one instance of one class at a time. The
+     * classes are all public.
+     */
+    @Benchmark
+    public void threeDifferentPublic(Blackhole bh) throws IllegalAccessException, InstantiationException {
+        for (Class<?> cl : differentPublicClasses) {
+            bh.consume(cl.newInstance());
+        }
+    }
+
+    /**
+     * Performs Class.newInstance on three different classes, just allocating one instance of one class at a time. The
+     * classes are all public.
+     */
+    @Benchmark
+    public void threeDifferentPublicConstant(Blackhole bh) throws IllegalAccessException, InstantiationException {
+        bh.consume(Apub.class.newInstance());
+        bh.consume(Bpub.class.newInstance());
+        bh.consume(Cpub.class.newInstance());
+    }
+
+    @Benchmark
+    public void threeDifferentPublicFinal(Blackhole bh) throws IllegalAccessException, InstantiationException {
+        for (Class<?> cl : differentPublicClassesConstant) {
+            bh.consume(cl.newInstance());
+        }
+    }
+
+    /* Protected test classes */
+    static class Apro {}
+    static class Bpro {}
+    static class Cpro {}
+
+    /* Public test classes */
+    public static class Apub {}
+    public static class Bpub {}
+    public static class Cpub {}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ObjectHashCode.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark assesses different hashCode strategies in HotSpot
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ObjectHashCode {
+
+    @Benchmark
+    @Fork
+    public int mode_default() {
+        return System.identityHashCode(new Object());
+    }
+
+    @Benchmark
+    @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=0"})
+    public int mode_0() {
+        return System.identityHashCode(new Object());
+    }
+
+    @Benchmark
+    @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=1"})
+    public int mode_1() {
+        return System.identityHashCode(new Object());
+    }
+
+    @Benchmark
+    @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=2"})
+    public int mode_2() {
+        return System.identityHashCode(new Object());
+    }
+
+    @Benchmark
+    @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=3"})
+    public int mode_3() {
+        return System.identityHashCode(new Object());
+    }
+
+    @Benchmark
+    @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=4"})
+    public int mode_4() {
+        return System.identityHashCode(new Object());
+    }
+
+    @Benchmark
+    @Fork(jvmArgsPrepend = {"-XX:+UnlockExperimentalVMOptions", "-XX:hashCode=5"})
+    public int mode_5() {
+        return System.identityHashCode(new Object());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringBuffers.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringBuffers {
+
+    private String name;
+    private String blaha;
+    private Sigurd sig;
+
+    @Setup
+    public void setup() {
+        name = "joe";
+        blaha = "sniglogigloienlitenapasomarengrodasjukadjavelhej";
+        sig = new Sigurd();
+    }
+
+    @Benchmark
+    public String appendAndToString() {
+        return "MyStringBuffer named:" + ((name == null) ? "unknown" : name) + ".";
+    }
+
+    @Benchmark
+    public String toStringComplex() {
+        return sig.toString();
+    }
+
+    static class Sigurd {
+        int x;
+        byte y;
+        String z = "yahoo";
+
+        @Override
+        public String toString() {
+            return Integer.toString(x) + "_" + Integer.toString((int) y) + "_" + z + "_";
+        }
+    }
+
+    @Benchmark
+    public String substring() {
+        return blaha.substring(30, 35);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringBuilders.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringBuilders {
+
+    private String[] strings;
+    private String[] str3p4p2;
+    private String[] str16p8p7;
+    private String[] str3p9p8;
+    private String[] str22p40p31;
+
+    @Setup
+    public void setup() {
+        strings = new String[]{"As", "your", "attorney,", "I",
+                "advise", "you", "to", "drive", "at", "top", "speed", "it'll",
+                "be", "a", "god", "damn", "miracle", "if", "we", "can", "get",
+                "there", "before", "you", "turn", "into", "a", "wild", "animal."};
+        str3p4p2 = new String[]{"123", "1234", "12"};
+        str16p8p7 = new String[]{"1234567890123456", "12345678", "1234567"};
+        str3p9p8 = new String[]{"123", "123456789", "12345678"};
+        str22p40p31 = new String[]{"1234567890123456789012", "1234567890123456789012345678901234567890", "1234567890123456789012345678901"};
+    }
+
+    /** StringBuilder wins over StringMaker. */
+    @Benchmark
+    public String concat3p4p2() throws Exception {
+        return new StringBuilder(String.valueOf(str3p4p2[0])).append(str3p4p2[1]).append(str3p4p2[2]).toString();
+    }
+
+    /** StringBuilder wins over StringMaker. */
+    @Benchmark
+    public String concat16p8p7() throws Exception {
+        return new StringBuilder(String.valueOf(str16p8p7[0])).append(str16p8p7[1]).append(str16p8p7[2]).toString();
+    }
+
+    /** StringMaker wins over StringBuilder since the two last strings causes StringBuilder to do expand. */
+    @Benchmark
+    public String concat3p9p8() throws Exception {
+        return new StringBuilder(String.valueOf(str3p9p8[0])).append(str3p9p8[1]).append(str3p9p8[2]).toString();
+    }
+
+    /** StringMaker wins over StringBuilder. */
+    @Benchmark
+    public String concat22p40p31() throws Exception {
+        return new StringBuilder(String.valueOf(str22p40p31[0])).append(str22p40p31[1]).append(str22p40p31[2]).toString();
+    }
+
+    @Benchmark
+    public StringBuilder appendLoop8() {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 8; i++) {
+            sb.append(strings[i]);
+        }
+        return sb;
+    }
+
+    @Benchmark
+    public StringBuilder appendLoop16() {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 16; i++) {
+            sb.append(strings[i]);
+        }
+        return sb;
+    }
+
+    @Benchmark
+    public String toStringCharWithChar1() {
+        StringBuilder result = new StringBuilder();
+        result.append('a');
+        return result.toString();
+    }
+
+    @Benchmark
+    public String toStringCharWithChar2() {
+        StringBuilder result = new StringBuilder();
+        result.append('a');
+        result.append('p');
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithChar4() {
+        StringBuilder result = new StringBuilder();
+        result.append('a');
+        result.append('p');
+        result.append('a');
+        result.append(' ');
+        return result.toString();
+    }
+
+    @Benchmark
+    public String toStringCharWithChar8() {
+        StringBuilder result = new StringBuilder();
+        result.append('a');
+        result.append('p');
+        result.append('a');
+        result.append(' ');
+        result.append('a');
+        result.append('p');
+        result.append('a');
+        result.append(' ');
+        return result.toString();
+    }
+
+    @Benchmark
+    public String toStringCharWithChar16() {
+        StringBuilder result = new StringBuilder();
+        result.append('a');
+        result.append('b');
+        result.append('c');
+        result.append('d');
+        result.append('e');
+        result.append('f');
+        result.append('g');
+        result.append('h');
+        result.append('i');
+        result.append('j');
+        result.append('k');
+        result.append('l');
+        result.append('m');
+        result.append('n');
+        result.append('o');
+        result.append('p');
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithString8() {
+        StringBuilder result = new StringBuilder();
+        result.append("a");
+        result.append("b");
+        result.append("c");
+        result.append("d");
+        result.append("e");
+        result.append("f");
+        result.append("g");
+        result.append("h");
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithString16() {
+        StringBuilder result = new StringBuilder();
+        result.append("a");
+        result.append("b");
+        result.append("c");
+        result.append("d");
+        result.append("e");
+        result.append("f");
+        result.append("g");
+        result.append("h");
+        result.append("i");
+        result.append("j");
+        result.append("k");
+        result.append("l");
+        result.append("m");
+        result.append("n");
+        result.append("o");
+        result.append("p");
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithInt8() {
+        StringBuilder result = new StringBuilder();
+        result.append(2048);
+        result.append(31337);
+        result.append(0xbeefcace);
+        result.append(9000);
+        result.append(4711);
+        result.append(1337);
+        result.append(2100);
+        result.append(2600);
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithBool8() {
+        StringBuilder result = new StringBuilder();
+        result.append(true);
+        result.append(false);
+        result.append(true);
+        result.append(true);
+        result.append(false);
+        result.append(true);
+        result.append(false);
+        result.append(false);
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithFloat8() {
+        StringBuilder result = new StringBuilder();
+        result.append(113.110F);
+        result.append(156456.36435637F);
+        result.append(65436434.64632F);
+        result.append(42654634.64540F);
+        result.append(63464351.64537F);
+        result.append(634564.645711F);
+        result.append(64547.64311F);
+        result.append(4763456341.64531F);
+        return result.toString();
+    }
+
+
+    @Benchmark
+    public String toStringCharWithMixed8() {
+        StringBuilder result = new StringBuilder();
+        result.append('a');
+        result.append("stringelinglinglinglong");
+        result.append('a');
+        result.append("stringelinglinglinglong");
+        result.append('a');
+        result.append("stringelinglinglinglong");
+        result.append('p');
+        result.append("stringelinglinglinglong");
+        return result.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringConcat.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Trivial String concatenation benchmark.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringConcat {
+
+    public int intValue = 4711;
+
+    public String stringValue = String.valueOf(intValue);
+
+    public Object objectValue = Long.valueOf(intValue);
+
+    public boolean boolValue = true;
+
+    public byte byteValue = (byte)-128;
+
+    @Benchmark
+    public String concatConstInt() {
+        return "string" + intValue;
+    }
+
+    @Benchmark
+    public String concatConstString() {
+        return "string" + stringValue;
+    }
+
+    @Benchmark
+    public String concatConstIntConstInt() {
+        return "string" + intValue + "string" + intValue;
+    }
+
+    @Benchmark
+    public String concatConstStringConstInt() {
+        return "string" + stringValue + "string" + intValue;
+    }
+
+    @Benchmark
+    public String concatConst4String() {
+        return "string" + stringValue + stringValue + stringValue + stringValue;
+    }
+
+    @Benchmark
+    public String concatConst2String() {
+        return "string" + stringValue + stringValue;
+    }
+
+    @Benchmark
+    public String concatConstBoolByte() {
+        return "string" + boolValue + byteValue;
+    }
+
+    @Benchmark
+    public String concatConst6String() {
+        return "string" + stringValue + stringValue + stringValue + stringValue + stringValue + stringValue;
+    }
+
+    @Benchmark
+    public String concatConst6Object() {
+        return "string" + objectValue + objectValue + objectValue + objectValue + objectValue + objectValue;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringHashCode.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Performance test of String.hashCode() function
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringHashCode {
+
+    private String hashcode;
+    private String hashcode0;
+
+    @Setup
+    public void setup() {
+        hashcode = "abcdefghijkl";
+        hashcode0 = new String(new char[]{72, 90, 100, 89, 105, 2, 72, 90, 100, 89, 105, 2});
+    }
+
+    /**
+     * Benchmark testing String.hashCode() with a regular 12 char string with
+     * the result possibly cached in String
+     */
+    @Benchmark
+    public int cached() {
+        return hashcode.hashCode();
+    }
+
+    /**
+     * Benchmark testing String.hashCode() with a 12 char string with the
+     * hashcode = 0 forcing the value to always be recalculated.
+     */
+    @Benchmark
+    public int notCached() {
+        return hashcode0.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringHttp.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringHttp {
+
+    private byte[] httpRequest;
+    private String[] httpResponse;
+    private byte[] buf;
+
+    @Setup
+    public void setup() {
+        buf = new byte[4080];
+        httpRequest = "GET /foo/bar/baz HTTP/1.1\nHost: foo.com\n".getBytes();
+        httpResponse = new String[]{"Date: 4/20/2003 10:21:31", "Last-Modified: 4/15/2003 10:21:31",
+                "Content-Length: 1234", "", "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+                "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+                "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+                "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz",
+                "foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz"};
+    }
+
+    @Benchmark
+    public void parseRequest(Blackhole bh) {
+        bh.consume(new String(httpRequest, 0, 3));
+        bh.consume(new String(httpRequest, 5, 11));
+        bh.consume(new String(httpRequest, 17, 8));
+        bh.consume(new String(httpRequest, 32, 7));
+    }
+
+    @Benchmark
+    public int bufferResponse() {
+        int pos = 0;
+        int n = httpResponse.length;
+
+        for (String s : httpResponse) {
+            byte[] b = s.getBytes();
+            int len = b.length;
+
+            System.arraycopy(b, 0, buf, pos, len);
+            pos += len;
+            buf[pos++] = '\n';
+        }
+        return n;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringIndexOf {
+
+    private String dataString;
+    private String searchString;
+    private String dataStringBig;
+    private String searchStringBig;
+    private String data;
+    private String sub;
+    private String shortSub1;
+    private String data2;
+    private String shortSub2;
+
+    @Setup
+    public void setup() {
+        dataString = "ngdfilsoscargfdgf";
+        searchString = "oscar";
+        dataStringBig = "2937489745890797905764956790452976742965790437698498409583479067ngdcapaapapapasdkajdlkajskldjaslkjdlkasjdsalkjas";
+        searchStringBig = "capaapapapasdkajdlkajskldjaslkjdlkasjdsalk";
+        data = "0000100101010010110101010010101110101001110110101010010101010010000010111010101010101010100010010101110111010101101010100010010100001010111111100001010101001010100001010101001010101010111010010101010101010101010101010";
+        sub = "10101010";
+        shortSub1 = "1";
+        data2 = "00001001010100a10110101010010101110101001110110101010010101010010000010111010101010101010a100010010101110111010101101010100010010a100a0010101111111000010101010010101000010101010010101010101110a10010101010101010101010101010";
+        shortSub2 = "a";
+    }
+
+    /** IndexOf Micros Strings */
+
+    /**
+     * Benchmarks String.indexOf with a rather small String to search and a rather small String to search for. The
+     * searched string contains the string that is searched for.
+     */
+    @Benchmark
+    public int success() {
+        return dataString.indexOf(searchString, 2);
+    }
+
+    /**
+     * Benchmarks String.indexOf with a rather big String to search and a rather big String to search for. The searched
+     * string contains the string that is searched for.
+     */
+    @Benchmark
+    public int successBig() {
+        return dataStringBig.indexOf(searchStringBig, 2);
+    }
+
+    /**
+     * Benchmarks String.indexOf with a rather big String. Search repeatedly for a matched that is 8 chars and most
+     * oftenly will require a inner lopp match in String.indexOf with sse42.
+     */
+    @Benchmark
+    public int advancedWithMediumSub() {
+        int index = 0;
+        int dummy = 0;
+        while ((index = data.indexOf(sub, index)) > -1) {
+            index++;
+            dummy += index;
+        }
+        return dummy;
+    }
+
+
+    /**
+     * Benchmarks String.indexOf with a rather big String. Search repeatedly for a matched that is 1 chars will find a
+     * huge amount of matches
+     */
+    @Benchmark
+    public int advancedWithShortSub1() {
+        int dummy = 0;
+        int index = 0;
+        while ((index = data.indexOf(shortSub1, index)) > -1) {
+            index++;
+            dummy += index;
+        }
+        return dummy;
+    }
+
+
+    /**
+     * Benchmarks String.indexOf with a rather big String. Search repeatedly for a matched that is 1 chars but only with
+     * a few matches.
+     */
+    @Benchmark
+    public int advancedWithShortSub2() {
+        int dummy = 0;
+        int index = 0;
+        while ((index = data2.indexOf(shortSub2, index)) > -1) {
+            index++;
+            dummy += index;
+        }
+        return dummy;
+    }
+
+    @Benchmark
+    public void constantPattern() {
+        String tmp = "simple-hash:SHA-1/UTF-8";
+        if (!tmp.contains("SHA-1")) {
+            throw new RuntimeException("indexOf failed");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringOther.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringOther {
+
+    private String testString;
+    private Random rnd;
+
+    private String str1, str2, str3, str4;
+
+    @Setup
+    public void setup() {
+        testString = "Idealism is what precedes experience; cynicism is what follows.";
+        str1 = "vm-guld vm-guld vm-guld";
+        str2 = "vm-guld vm-guld vm-guldx";
+        str3 = "vm-guld vm-guld vm-guldx";
+        str4 = "adadaskasdjierudks";
+        rnd = new Random();
+    }
+
+    @Benchmark
+    public void charAt(Blackhole bh) {
+        for (int i = 0; i < testString.length(); i++) {
+            bh.consume(testString.charAt(i));
+        }
+    }
+
+    @Benchmark
+    public int compareTo() {
+        int total = 0;
+        total += str1.compareTo(str2);
+        total += str2.compareTo(str3);
+        total += str3.compareTo(str4);
+        return total;
+    }
+
+    /**
+     * Creates (hopefully) unique Strings and internizes them, creating a zillion forgettable strings in the JVMs string
+     * pool.
+     * <p/>
+     * This will test 1.) The data structure/whatever for getting and adding Strings to intern table. 2.) The
+     * intern-caches (java) behaviour on negative lookup (the string is new) 3.) GC's handling of weak handles. Since
+     * every gc we must process and pretty much kill a zillion interned strings that are now not referenced anymore, the
+     * majority of GC time will be spent in handle processing. So we get a picture of how well the pathological case of
+     * this goes.
+     */
+    @Benchmark
+    public String internUnique() {
+        return String.valueOf(rnd.nextInt()).intern();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringUpperLower.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StringUpperLower {
+
+    private String strLowerCase;
+    private String strMixedCase;
+    private String strUpperCase;
+
+    @Setup
+    public void setup() {
+        strLowerCase = "this is a simple string with different cases";
+        strMixedCase = "This IS a SImpLE strING wITh DiFfErEnT CASeS";
+        strUpperCase = "THIS IS A SIMPLE STRING WITH DIFFERENT CASES";
+    }
+
+    @Benchmark
+    public String lowerToLower() {
+        return strLowerCase.toLowerCase();
+    }
+
+    @Benchmark
+    public String mixedToLower() {
+        return strMixedCase.toLowerCase();
+    }
+
+    @Benchmark
+    public String upperToLower() {
+        return strUpperCase.toLowerCase();
+    }
+
+    @Benchmark
+    public String lowerToUpper() {
+        return strLowerCase.toUpperCase();
+    }
+
+    @Benchmark
+    public String mixedToUpper() {
+        return strMixedCase.toUpperCase();
+    }
+
+    @Benchmark
+    public String upperToUpper() {
+        return strUpperCase.toUpperCase();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/Systems.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Systems {
+
+    @Benchmark
+    public long currentTimeMillis() {
+        return System.currentTimeMillis();
+    }
+
+    @Benchmark
+    public long nanoTime() {
+        return System.nanoTime();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/ThreadStartJoin.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test to launch and gather threads. Measure time for different parts.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Benchmark)
+public class ThreadStartJoin {
+
+    private static final int THREADS = Runtime.getRuntime().availableProcessors();
+
+    private Thread[] ts;
+
+    @Benchmark
+    public void test() throws InterruptedException {
+        ts = new TestThread[THREADS];
+
+        for (int i = 0; i < THREADS; i++) {
+            ts[i] = new TestThread();
+        }
+
+        for (int i = 0; i < THREADS; i++) {
+            ts[i].start();
+        }
+
+        for (Thread mythread : ts) {
+            mythread.join();
+
+            if (mythread.isAlive()) {
+                throw new IllegalStateException("Couldn't join in time in LPHhello.");
+            }
+        }
+    }
+
+    @TearDown
+    public final void cleanup() {
+        if (ts != null) {
+            for (Thread t : ts) {
+                if (t != null) {
+                    t.interrupt();
+                }
+            }
+            ts = null;
+        }
+    }
+
+    static final class TestThread extends Thread {
+        private static int num = 0;
+
+        public TestThread() {
+            super(TestThread.name());
+        }
+
+        private synchronized static String name() {
+            return "TestThread-" + num++;
+        }
+
+        public void run() {
+            // do nothing
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/CallSiteSetTarget.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This benchmark evaluates INDY performance under dynamic target updates.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CallSiteSetTarget {
+
+    /*
+     * Implementation notes:
+     *   - This test makes sense for mutable and volatile call sites only
+     *   - Multiple threads are calling the same callsite, and invalidator thread tries to swap target on the fly.
+     *   - Additional baseline includes "raw" test, calling callsite's MH directly
+     */
+
+    private static volatile CallSite cs;
+
+    private static MethodHandle doCall1;
+    private static MethodHandle doCall2;
+
+    static {
+        try {
+            doCall1 = MethodHandles.lookup().findVirtual(CallSiteSetTarget.class, "call1", MethodType.methodType(int.class));
+            doCall2 = MethodHandles.lookup().findVirtual(CallSiteSetTarget.class, "call2", MethodType.methodType(int.class));
+            cs = new MutableCallSite(doCall1);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private int i1;
+    private int i2;
+
+    public int call1() {
+        return i1++;
+    }
+
+    public int call2() {
+        return i2++;
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return (int) cs.getTarget().invokeExact(this);
+    }
+
+    @Benchmark
+    public int testMutable() throws Throwable {
+        return (int) INDY_Mutable().invokeExact(this);
+    }
+
+    @Benchmark
+    public int testVolatile() throws Throwable {
+        return (int) INDY_Volatile().invokeExact(this);
+    }
+
+    /* =========================== INDY TRAMPOLINES ============================== */
+
+    private static MethodType MT_bsm() {
+        shouldNotCallThis();
+        return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+    }
+
+    private static MethodHandle MH_bsm_Mutable() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Mutable", MT_bsm());
+    }
+
+    private static MethodHandle MH_bsm_Volatile() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Volatile", MT_bsm());
+    }
+
+    private static MethodHandle INDY_Mutable() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm_Mutable().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTarget.class))).dynamicInvoker();
+    }
+
+    private static MethodHandle INDY_Volatile() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm_Volatile().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTarget.class))).dynamicInvoker();
+    }
+
+    public static CallSite bsm_Mutable(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteSetTarget.class) {
+            if (cs == null)
+                cs = new MutableCallSite(doCall1);
+            return cs;
+        }
+    }
+
+    public static CallSite bsm_Volatile(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteSetTarget.class) {
+            if (cs == null)
+                cs = new VolatileCallSite(doCall1);
+            return cs;
+        }
+    }
+
+    private static void shouldNotCallThis() {
+        // if this gets called, the transformation has not taken place
+        throw new AssertionError("this code should be statically transformed away by Indify");
+    }
+
+    /* =========================== INVALIDATE LOGIC ============================== */
+
+    private final static Invalidator invalidator = new Invalidator();
+
+    @Setup
+    public void setup() {
+        invalidator.start();
+    }
+
+    @TearDown
+    public void tearDown() throws InterruptedException {
+        invalidator.stop();
+    }
+
+    public static class Invalidator implements Runnable {
+
+        private final long period = Integer.getInteger("period", 1000);
+
+        private final AtomicBoolean started = new AtomicBoolean();
+        private volatile Thread thread;
+
+        @Override
+        public void run() {
+            try {
+                while(!Thread.interrupted()) {
+                    if (cs != null) {
+                        cs.setTarget(doCall1);
+                    }
+                    TimeUnit.MICROSECONDS.sleep(period);
+
+                    if (cs != null) {
+                        cs.setTarget(doCall2);
+                    }
+                    TimeUnit.MICROSECONDS.sleep(period);
+                }
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+
+        public void start() {
+            if (started.compareAndSet(false, true)) {
+                thread = new Thread(this);
+                thread.setPriority(Thread.MAX_PRIORITY);
+                thread.start();
+            }
+        }
+
+        public void stop() {
+            if (thread != null) {
+                thread.interrupt();
+                try {
+                    thread.join();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+                started.set(false);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/CallSiteSetTargetSelf.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark evaluates INDY performance under dynamic target updates.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CallSiteSetTargetSelf {
+
+    /*
+     * Implementation notes:
+     *   - This test makes sense for mutable and volatile call sites only
+     *   - Multiple threads are calling the same callsite, and each call is swapping the target.
+     *   - Additional baseline includes "raw" test, calling callsite's MH directly
+     *
+     *   - NOTE: invalidating shared target callsite is very bad with multiple threads.
+     *     I.e. this test is inherently non-scalable.
+     */
+
+    private static CallSite cs;
+
+    private static MethodHandle doCall1;
+    private static MethodHandle doCall2;
+
+    static {
+        try {
+            doCall1 = MethodHandles.lookup().findVirtual(CallSiteSetTargetSelf.class, "call1", MethodType.methodType(int.class));
+            doCall2 = MethodHandles.lookup().findVirtual(CallSiteSetTargetSelf.class, "call2", MethodType.methodType(int.class));
+            cs = new MutableCallSite(doCall1);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private int i1;
+    private int i2;
+
+    public int call1() {
+        cs.setTarget(doCall2);
+        return i1++;
+    }
+
+    public int call2() {
+        cs.setTarget(doCall1);
+        return i2++;
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return (int) cs.getTarget().invokeExact(this);
+    }
+
+    @Benchmark
+    public int testMutable() throws Throwable {
+        return (int) INDY_Mutable().invokeExact(this);
+    }
+
+    @Benchmark
+    public int testVolatile() throws Throwable {
+        return (int) INDY_Volatile().invokeExact(this);
+    }
+
+    /* =========================== INDY TRAMPOLINES ============================== */
+
+    private static MethodType MT_bsm() {
+        shouldNotCallThis();
+        return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+    }
+
+    private static MethodHandle MH_bsm_Mutable() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Mutable", MT_bsm());
+    }
+
+    private static MethodHandle MH_bsm_Volatile() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Volatile", MT_bsm());
+    }
+
+    private static MethodHandle INDY_Mutable() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm_Mutable().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTargetSelf.class))).dynamicInvoker();
+    }
+
+    private static MethodHandle INDY_Volatile() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm_Volatile().invoke(MethodHandles.lookup(), "doCall1", MethodType.methodType(int.class, CallSiteSetTargetSelf.class))).dynamicInvoker();
+    }
+
+    public static CallSite bsm_Mutable(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteSetTarget.class) {
+            if (cs == null)
+                cs = new MutableCallSite(doCall1);
+            return cs;
+        }
+    }
+
+    public static CallSite bsm_Volatile(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteSetTarget.class) {
+            if (cs == null)
+                cs = new VolatileCallSite(doCall1);
+            return cs;
+        }
+    }
+
+    private static void shouldNotCallThis() {
+        // if this gets called, the transformation has not taken place
+        throw new AssertionError("this code should be statically transformed away by Indify");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/CallSiteStable.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.VolatileCallSite;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark evaluates INDY performance when call sites are not changed.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CallSiteStable {
+
+    /*
+     * Implementation notes:
+     *   - Test is calling simple method via INDY
+     *   - Additional baseline includes "raw" test, calling target method directly in virtual and static modes
+     */
+
+    private static java.lang.invoke.CallSite cs;
+
+    private static MethodHandle doCallMH;
+
+    static {
+        try {
+            doCallMH = MethodHandles.lookup().findVirtual(CallSiteStable.class, "doCall", MethodType.methodType(int.class, int.class));
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private int i;
+
+    public int doCall(int value) {
+        return value + 1;
+    }
+
+    public static int doCallStatic(int value) {
+        return value + 1;
+    }
+
+    @Benchmark
+    public void baselineVirtual() {
+        i = doCall(i);
+    }
+
+    @Benchmark
+    public void baselineStatic() {
+        i = doCallStatic(i);
+    }
+
+    @Benchmark
+    public void testConstant() throws Throwable {
+        i = (int) INDY_Constant().invokeExact(this, i);
+    }
+
+    @Benchmark
+    public void testMutable() throws Throwable {
+        i = (int) INDY_Mutable().invokeExact(this, i);
+    }
+
+    @Benchmark
+    public void testVolatile() throws Throwable {
+        i = (int) INDY_Volatile().invokeExact(this, i);
+    }
+
+    /* =========================== INDY TRAMPOLINES ============================== */
+
+    private static MethodType MT_bsm() {
+        shouldNotCallThis();
+        return MethodType.methodType(java.lang.invoke.CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+    }
+
+    private static MethodHandle MH_bsm_Constant() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Constant", MT_bsm());
+    }
+
+    private static MethodHandle MH_bsm_Mutable() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Mutable", MT_bsm());
+    }
+
+    private static MethodHandle MH_bsm_Volatile() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return MethodHandles.lookup().findStatic(MethodHandles.lookup().lookupClass(), "bsm_Volatile", MT_bsm());
+    }
+
+    private static MethodHandle INDY_Constant() throws Throwable {
+        shouldNotCallThis();
+        return ((java.lang.invoke.CallSite) MH_bsm_Constant().invoke(MethodHandles.lookup(), "doCall", MethodType.methodType(int.class, CallSiteStable.class, int.class))).dynamicInvoker();
+    }
+    private static MethodHandle INDY_Mutable() throws Throwable {
+        shouldNotCallThis();
+        return ((java.lang.invoke.CallSite) MH_bsm_Mutable().invoke(MethodHandles.lookup(), "doCall", MethodType.methodType(int.class, CallSiteStable.class, int.class))).dynamicInvoker();
+    }
+    private static MethodHandle INDY_Volatile() throws Throwable {
+        shouldNotCallThis();
+        return ((java.lang.invoke.CallSite) MH_bsm_Volatile().invoke(MethodHandles.lookup(), "doCall", MethodType.methodType(int.class, CallSiteStable.class, int.class))).dynamicInvoker();
+    }
+
+    public static java.lang.invoke.CallSite bsm_Constant(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteStable.class) {
+            if (cs == null)
+                cs = new ConstantCallSite(doCallMH);
+            return cs;
+        }
+    }
+
+    public static java.lang.invoke.CallSite bsm_Mutable(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteStable.class) {
+            if (cs == null)
+                cs = new MutableCallSite(doCallMH);
+            return cs;
+        }
+    }
+
+    public static java.lang.invoke.CallSite bsm_Volatile(MethodHandles.Lookup lookup, String name, MethodType type) {
+        synchronized (CallSiteStable.class) {
+            if (cs == null)
+                cs = new VolatileCallSite(doCallMH);
+            return cs;
+        }
+    }
+
+    private static void shouldNotCallThis() {
+        // if this gets called, the transformation has not taken place
+        throw new AssertionError("this code should be statically transformed away by Indify");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupAcquire.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.lookup/publicLookup() acquiring performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LookupAcquire {
+
+    /*
+        Implementation notes:
+            - this test assesses acquiring lookup object only
+            - baseline includes returning cached lookup object, i.e. measures infra overheads
+            - additional baseline includes allocating object to understand Lookup instantiation costs
+            - cached instance is static, because that provides (unbeatably) best performance
+     */
+
+    public static MethodHandles.Lookup cached;
+
+    @Setup
+    public void setup() {
+        cached = MethodHandles.lookup();
+    }
+
+    @Benchmark
+    public MethodHandles.Lookup baselineCached() throws Exception {
+        return cached;
+    }
+
+    @Benchmark
+    public MyLookup baselineNew() throws Exception {
+        return new MyLookup(Object.class, 1);
+    }
+
+    @Benchmark
+    public MethodHandles.Lookup testPublicLookup() throws Exception {
+        return MethodHandles.publicLookup();
+    }
+
+    @Benchmark
+    public MethodHandles.Lookup testLookup() throws Exception {
+        return MethodHandles.lookup();
+    }
+
+    /**
+     * Dummy Lookup-looking class.
+     * Lookup is final, and all constructors are private.
+     * This class mocks the hotpath.
+     */
+    private static class MyLookup {
+        private final Class<?> klass;
+        private final int mode;
+
+        public MyLookup(Class<?> klass, int i) {
+            this.klass = klass;
+            this.mode = i;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupDefaultFind.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandle.lookup() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LookupDefaultFind {
+
+    /*
+        Implementation notes:
+            - does not test findSpecial, since the privileges of this Bench is not enough to access private members
+     */
+
+    @Benchmark
+    public MethodHandle testConstructor() throws Exception {
+        return MethodHandles.lookup().findConstructor(Victim.class, MethodType.methodType(void.class));
+    }
+
+    @Benchmark
+    public MethodHandle testGetter() throws Exception {
+        return MethodHandles.lookup().findGetter(Victim.class, "field", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testSetter() throws Exception {
+        return MethodHandles.lookup().findSetter(Victim.class, "field", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testStatic() throws Exception {
+        return MethodHandles.lookup().findStatic(Victim.class, "staticWork", MethodType.methodType(int.class));
+    }
+
+    @Benchmark
+    public MethodHandle testStaticGetter() throws Exception {
+        return MethodHandles.lookup().findStaticGetter(Victim.class, "staticField", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testStaticSetter() throws Exception {
+        return MethodHandles.lookup().findStaticSetter(Victim.class, "staticField", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testVirtual() throws Exception {
+        return MethodHandles.lookup().findVirtual(Victim.class, "virtualWork", MethodType.methodType(int.class));
+    }
+
+    public static class Victim {
+
+        public static int staticField;
+        public int field;
+
+        public Victim() {
+            // do nothing
+        }
+
+        public int virtualWork() {
+            return 1;
+        }
+
+        public static int staticWork() {
+            return 1;
+        }
+
+        private int specialWork() {
+            return 1;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupPublicFind.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandle.publicLookup() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LookupPublicFind {
+
+    /*
+        Implementation notes:
+            - findSpecial is not tested, unable to do this with public lookup object
+     */
+
+    @Benchmark
+    public MethodHandle testConstructor() throws Exception {
+        return MethodHandles.publicLookup().findConstructor(Victim.class, MethodType.methodType(void.class));
+    }
+
+    @Benchmark
+    public MethodHandle testGetter() throws Exception {
+        return MethodHandles.publicLookup().findGetter(Victim.class, "field", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testSetter() throws Exception {
+        return MethodHandles.publicLookup().findSetter(Victim.class, "field", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testStatic() throws Exception {
+        return MethodHandles.publicLookup().findStatic(Victim.class, "staticWork", MethodType.methodType(int.class));
+    }
+
+    @Benchmark
+    public MethodHandle testStaticGetter() throws Exception {
+        return MethodHandles.publicLookup().findStaticGetter(Victim.class, "staticField", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testStaticSetter() throws Exception {
+        return MethodHandles.publicLookup().findStaticSetter(Victim.class, "staticField", int.class);
+    }
+
+    @Benchmark
+    public MethodHandle testVirtual() throws Exception {
+        return MethodHandles.publicLookup().findVirtual(Victim.class, "virtualWork", MethodType.methodType(int.class));
+    }
+
+    public static class Victim {
+
+        public static int staticField;
+        public int field;
+
+        public Victim() {
+            // do nothing
+        }
+
+        public int virtualWork() {
+            return 1;
+        }
+
+        public static int staticWork() {
+            return 1;
+        }
+
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsCollector.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Microbenchmark assesses MethodHandle.asCollector() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleAsCollector {
+
+    /*
+    * Implementation notes:
+    *   - simple array-parameter method is being called
+    *   - baselineRaw calls method directly with dynamically instantiating the array
+    *   - baselineCached calls method directly with pre-cached array
+    *   - additional testCreate() test harnesses the collector acquisition performance
+    *   - testCollector() can be faster than both baselines: it can wrapping array at all
+    */
+
+    public int i;
+    private static MethodHandle mh;
+    private static MethodHandle collectorMH;
+    private static int[] cachedArgs;
+
+    @Setup
+    public void setup() throws IllegalAccessException, NoSuchMethodException {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleAsCollector.class, "doWork", MethodType.methodType(void.class, int[].class));
+        collectorMH = mh.asCollector(int[].class, 5);
+        cachedArgs = new int[]{1, 2, 3, 4, 5};
+    }
+
+    @Benchmark
+    public void baselineMH() throws Throwable {
+        mh.invokeExact(this, new int[] { 1, 2, 3, 4, 5 });
+    }
+
+    @Benchmark
+    public void baselineMHCached() throws Throwable {
+        mh.invokeExact(this, cachedArgs);
+    }
+
+    @Benchmark
+    public void baselineRaw() throws Throwable {
+        doWork(new int[] { 1, 2, 3, 4, 5});
+    }
+
+    @Benchmark
+    public void baselineRawCached() throws Throwable {
+        doWork(cachedArgs);
+    }
+
+    @Benchmark
+    public MethodHandle testCreate() {
+        return mh.asCollector(int[].class, 5);
+    }
+
+    @Benchmark
+    public void testCollector() throws Throwable {
+        collectorMH.invokeExact(this, 1, 2, 3, 4, 5);
+    }
+
+    public void doWork(int[] args) {
+        for (int a : args) {
+            i += a;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsSpreader.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Microbenchmark assesses MethodHandle.asSpreader() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleAsSpreader {
+
+    /*
+    * Implementation notes:
+    *   - simple array-parameter method is being called
+    *   - baselineRaw calls method directly with dynamically instantiating the array
+    *   - baselineCached calls method directly with pre-cached array
+    *   - additional testCreate() test harnesses the collector acquisition performance
+    *   - testCollector() can be faster than both baselines: it can wrapping array at all
+    */
+
+    public int i;
+    private static MethodHandle mh;
+    private static MethodHandle spreaderMH;
+    private static int[] cachedArgs;
+
+    @Setup
+    public void setup() throws IllegalAccessException, NoSuchMethodException {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleAsSpreader.class, "doWork", MethodType.methodType(void.class, int.class, int.class, int.class, int.class, int.class));
+        spreaderMH = mh.asSpreader(int[].class, 5);
+        cachedArgs = new int[]{1, 2, 3, 4, 5};
+    }
+
+    @Benchmark
+    public void baselineMH() throws Throwable {
+        mh.invokeExact(this, 1, 2, 3, 4, 5);
+    }
+
+    @Benchmark
+    public void baselineRaw() throws Throwable {
+        doWork(1, 2, 3, 4, 5);
+    }
+
+    @Benchmark
+    public MethodHandle testCreate() {
+        return mh.asSpreader(int[].class, 5);
+    }
+
+    @Benchmark
+    public void testSpreader() throws Throwable {
+        spreaderMH.invokeExact(this, new int[] { 1, 2, 3, 4, 5 });
+    }
+
+    @Benchmark
+    public void testSpreaderCached() throws Throwable {
+        spreaderMH.invokeExact(this, cachedArgs);
+    }
+
+    public void doWork(int arg1, int arg2, int arg3, int arg4, int arg5) {
+        i += (arg1 + arg2 + arg3 + arg4 + arg5);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleAsVarargsCollector.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Microbenchmark assesses MethodHandle.asVarargCollector() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleAsVarargsCollector {
+
+    /*
+    * Implementation notes:
+    *   - simple array-parameter method is being called
+    *   - baselineRaw calls method directly with dynamically instantiating the array
+    *   - baselineCached calls method directly with pre-cached array
+    *   - additional testCreate() test harnesses the collector acquisition performance
+    *   - testCollector() can be faster than both baselines: it can wrapping array at all
+    */
+
+    public int i;
+    private static MethodHandle mh;
+    private static MethodHandle collectorMH;
+    private static int[] cachedArgs;
+
+    @Setup
+    public void setup() throws IllegalAccessException, NoSuchMethodException {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleAsVarargsCollector.class, "doWork", MethodType.methodType(void.class, int[].class));
+        collectorMH = mh.asVarargsCollector(int[].class);
+        cachedArgs = new int[]{1, 2, 3, 4, 5};
+    }
+
+    @Benchmark
+    public void baselineMH() throws Throwable {
+        mh.invoke(this, new int[] { 1, 2, 3, 4, 5 });
+    }
+
+    @Benchmark
+    public void baselineMHCached() throws Throwable {
+        mh.invoke(this, cachedArgs);
+    }
+
+    @Benchmark
+    public void baselineRaw() throws Throwable {
+        doWork(1, 2, 3, 4, 5);
+    }
+
+    @Benchmark
+    public void baselineRawCached() throws Throwable {
+        doWork(cachedArgs);
+    }
+
+    @Benchmark
+    public MethodHandle testCreate() {
+        return mh.asVarargsCollector(int[].class);
+    }
+
+    @Benchmark
+    public void testCollector() throws Throwable {
+        collectorMH.invoke(this, 1, 2, 3, 4, 5);
+    }
+
+    public void doWork(int... args) {
+        for (int a : args) {
+            i += a;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBasicInvoke.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark to assess basic MethodHandle performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleBasicInvoke {
+
+    /*
+     * Implementation notes:
+     *   - this is a very basic test, does not do any parameter conversion (in fact, no parameters at all)
+     *   - baselines include calling method directly, and doing the same via reflection
+     *   - baselineRaw is known to be super-fast with good inlining
+     */
+
+    private int i;
+    private static MethodHandle mh;
+    private static Method ref;
+    private static MethodHandle mhUnreflect;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleBasicInvoke.class, "doWork", MethodType.methodType(int.class));
+
+        ref = MethodHandleBasicInvoke.class.getMethod("doWork");
+        ref.setAccessible(true);
+
+        mhUnreflect = MethodHandles.lookup().unreflect(ref);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork();
+    }
+
+    @Benchmark
+    public int baselineReflect() throws Throwable {
+        return (int) ref.invoke(this);
+    }
+
+    @Benchmark
+    public int testMH_Plain_Invoke() throws Throwable {
+        return (int) mh.invoke(this);
+    }
+
+    @Benchmark
+    public int testMH_Plain_Exact() throws Throwable {
+        return (int) mh.invokeExact(this);
+    }
+
+    @Benchmark
+    public int testMH_Unreflect_Invoke() throws Throwable {
+        return (int) mhUnreflect.invoke(this);
+    }
+
+    @Benchmark
+    public int testMH_Unreflect_Exact() throws Throwable {
+        return (int) mhUnreflect.invokeExact(this);
+    }
+
+    public int doWork() {
+        return i++;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBindToBinding.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandle.bindTo() binding performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleBindToBinding {
+
+    /*
+       Implementation notes:
+          - calls static method to avoid binding "this"
+          - tests binding costs with multiple depth (C1, C2, C3)
+          - baseline includes naive side effect store
+          - lowering the binding cost will minimise both the spread between C1/C2/C3 and difference towards baseline
+          - this test performance will never reach the baseline
+     */
+
+    private MethodHandle mhOrig;
+
+    @Setup
+    public void setup() throws Throwable {
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandleBindToBinding.class, "doWork",
+                MethodType.methodType(Integer.class, Integer.class, Integer.class, Integer.class));
+    }
+
+    @Benchmark
+    public Object baselineRaw() {
+        return mhOrig;
+    }
+
+    @Benchmark
+    public Object testBind_C1() throws Throwable {
+        MethodHandle mhCurry1 = mhOrig.bindTo(1);
+        return mhCurry1;
+    }
+
+    @Benchmark
+    public Object testBind_C2() throws Throwable {
+        MethodHandle mhCurry1 = mhOrig.bindTo(1);
+        MethodHandle mhCurry2 = mhCurry1.bindTo(2);
+        return mhCurry2;
+    }
+
+    @Benchmark
+    public Object testBind_C3() throws Throwable {
+        MethodHandle mhCurry1 = mhOrig.bindTo(1);
+        MethodHandle mhCurry2 = mhCurry1.bindTo(2);
+        MethodHandle mhCurry3 = mhCurry2.bindTo(3);
+        return mhCurry3;
+    }
+
+    public static Integer doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleBindToCurry.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses currying with MethodHandle.bindTo() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleBindToCurry {
+
+    /*
+       Implementation notes:
+          - calls static method to avoid binding "this"
+          - tests the performance of gradually curried methods, hoping for compiler to optimize
+          - arguments are volatile, to break optimistic CSE happening before the actual call
+          - using invokeExact and Integers to skip argument conversions
+          - baseline includes calling the method directly, and this is known to be super-fast due to inlining
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mhCurry1;
+    private MethodHandle mhCurry2;
+    private MethodHandle mhCurry3;
+
+    private volatile Integer arg1 = 1;
+    private volatile Integer arg2 = 2;
+    private volatile Integer arg3 = 3;
+
+    @Setup
+    public void setup() throws Throwable {
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandleBindToCurry.class, "doWork",
+                MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+        mhCurry1 = mhOrig.bindTo(arg1);
+        mhCurry2 = mhCurry1.bindTo(arg2);
+        mhCurry3 = mhCurry2.bindTo(arg3);
+    }
+
+    @Benchmark
+    public int baselineRaw() {
+        return doWork(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoke_C0() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoke_C1() throws Throwable {
+        return (int) mhCurry1.invokeExact(arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoke_C2() throws Throwable {
+        return (int) mhCurry2.invokeExact(arg3);
+    }
+
+    @Benchmark
+    public int testInvoke_C3() throws Throwable {
+        return (int) mhCurry3.invokeExact();
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertBoxing.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks autoboxing conversion.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertBoxing {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling static method as to minimize virtual dispatch overheads.
+     */
+
+    private Integer valueBoxed;
+    private int valueUnboxed;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findStatic(MethodHandleConvertBoxing.class, "target", MethodType.methodType(int.class, int.class));
+        newType = MethodType.methodType(int.class, Integer.class);
+        valueBoxed = 42;
+        valueUnboxed = 42;
+    }
+
+    @Benchmark
+    public int baselineExact() throws Throwable {
+        return (int) mh.invokeExact(valueUnboxed);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(int.class, Integer.class));
+    }
+
+    @Benchmark
+    public int test_3_Call() throws Throwable {
+        return (int) mh.invoke(valueBoxed);
+    }
+
+    public static int target(int value) {
+        return value + 1;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertCast.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the casts are applied.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertCast {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling static method as to minimize virtual dispatch overheads.
+     */
+
+    private A instanceA;
+    private B instanceB;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findStatic(MethodHandleConvertCast.class, "target", MethodType.methodType(A.class, A.class));
+        newType = MethodType.methodType(A.class, B.class);
+        instanceA = new A();
+        instanceB = new B();
+    }
+
+    @Benchmark
+    public A baselineExact() throws Throwable {
+        return (A) mh.invokeExact(instanceA);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(A.class, B.class));
+    }
+
+    @Benchmark
+    public A test_3_Call() throws Throwable {
+        return (A) mh.invoke(instanceB);
+    }
+
+    public static A target(A value) {
+        return value;
+    }
+
+    public static class A {}
+    public static class B extends A { }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnPrimitive.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the return type conversion: void -> int.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertReturnPrimitive {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling virtual method to guarantee side-effects on value, without trading off scalability.
+     * This test should be executed in non-shared mode.
+     */
+
+    public int value;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleConvertReturnPrimitive.class, "target", MethodType.methodType(void.class));
+        newType = MethodType.methodType(int.class, MethodHandleConvertReturnPrimitive.class);
+    }
+
+    @Benchmark
+    public void baselineExact() throws Throwable {
+        mh.invokeExact(this);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(int.class, MethodHandleConvertReturnPrimitive.class));
+    }
+
+    @Benchmark
+    public int test_3_Call() throws Throwable {
+        return (int) mh.invoke(this);
+    }
+
+    public void target() {
+        value++;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnReference.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the return type conversion: void -> Integer.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertReturnReference {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling virtual method to guarantee side-effects on value, without trading off scalability.
+     * This test should be executed in non-shared mode.
+     */
+
+    public int value;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleConvertReturnReference.class, "target", MethodType.methodType(void.class));
+        newType = MethodType.methodType(Integer.class, MethodHandleConvertReturnReference.class);
+    }
+
+    @Benchmark
+    public void baselineExact() throws Throwable {
+        mh.invokeExact(this);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(Integer.class, MethodHandleConvertReturnReference.class));
+    }
+
+    @Benchmark
+    public Object test_3_Call() throws Throwable {
+        return mh.invoke(this);
+    }
+
+    public void target() {
+        value++;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertReturnVoid.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the return type conversion: int -> void.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertReturnVoid {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling virtual method to guarantee side-effects on value, without trading off scalability.
+     * This test should be executed in non-shared mode.
+     */
+
+    public int value;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleConvertReturnVoid.class, "target", MethodType.methodType(int.class));
+        newType = MethodType.methodType(void.class, MethodHandleConvertReturnVoid.class);
+    }
+
+    @Benchmark
+    public int baselineExact() throws Throwable {
+        return (int) mh.invokeExact(this);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(void.class, MethodHandleConvertReturnVoid.class));
+    }
+
+    @Benchmark
+    public void test_3_Call() throws Throwable {
+        mh.invoke(this);
+    }
+
+    public int target() {
+        return value++;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertUnboxing.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the unboxing conversion.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertUnboxing {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling static method as to minimize virtual dispatch overheads.
+     */
+
+    private Integer valueBoxed;
+    private int valueUnboxed;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findStatic(MethodHandleConvertUnboxing.class, "target", MethodType.methodType(int.class, Integer.class));
+        newType = MethodType.methodType(int.class, int.class);
+        valueBoxed = 42;
+        valueUnboxed = 42;
+    }
+
+    @Benchmark
+    public int baselineExact() throws Throwable {
+        return (int) mh.invokeExact(valueBoxed);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(int.class, int.class));
+    }
+
+    @Benchmark
+    public int test_3_Call() throws Throwable {
+        return (int) mh.invoke(valueUnboxed);
+    }
+
+    public static int target(Integer value) {
+        return value + 1;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleConvertWidening.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses runtime argument conversion performance for MethodHandles.
+ * This particular test checks the widening conversion.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleConvertWidening {
+
+    /*
+     * Implementation notes:
+     *
+     * Baseline is invokeExact call, which presumably measures the performance without argument conversion.
+     *
+     * The test is subdivided into three subtests, gradually doing more work:
+     *   - 1_Convert: calls MH.asType to do actual conversion
+     *   - 2_MTConvert: instantiates MT, and then calls MH.asType to do actual conversion
+     *   - 3_Call: calls MH.invoke, requesting argument conversion
+     *
+     * Calling static method as to minimize virtual dispatch overheads.
+     */
+
+    private long valueLong;
+    private int valueInt;
+
+    private MethodHandle mh;
+    private MethodType newType;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findStatic(MethodHandleConvertWidening.class, "target", MethodType.methodType(long.class, long.class));
+        newType = MethodType.methodType(long.class, int.class);
+        valueInt = 42;
+        valueLong = 42L;
+    }
+
+    @Benchmark
+    public long baselineExact() throws Throwable {
+        return (long) mh.invokeExact(valueLong);
+    }
+
+    @Benchmark
+    public MethodHandle test_1_Convert() throws Throwable {
+        return mh.asType(newType);
+    }
+
+    @Benchmark
+    public MethodHandle test_2_MTConvert() throws Throwable {
+        return mh.asType(MethodType.methodType(long.class, int.class));
+    }
+
+    @Benchmark
+    public long test_3_Call() throws Throwable {
+        return (long) mh.invoke(valueInt);
+    }
+
+    public static long target(long value) {
+        return value + 1;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleInvokeWithArgs.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark to assess basic MethodHandle performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleInvokeWithArgs {
+
+    /*
+     * Implementation notes:
+     *   - this is a very basic test, does not do any parameter conversion (in fact, no parameters at all)
+     *   - baselines include calling method directly, and doing the same via reflection
+     *   - baselineRaw is known to be super-fast with good inlining
+     */
+
+    private int i;
+    private static MethodHandle mh;
+
+    private Integer a = 42;
+
+    @Setup
+    public void setup() throws Throwable {
+        mh = MethodHandles.lookup().findVirtual(MethodHandleInvokeWithArgs.class, "doWork", MethodType.methodType(int.class, Integer.class));
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork(a);
+    }
+
+    @Benchmark
+    public int baselineInvoke() throws Throwable {
+        return (int) mh.invoke(this, a);
+    }
+
+    @Benchmark
+    public int baselineInvokeExact() throws Throwable {
+        return (int) mh.invokeExact(this, a);
+    }
+
+    @Benchmark
+    public int testInvoke_WithArguments() throws Throwable {
+        return (int) mh.invokeWithArguments(this, a);
+    }
+
+    public int doWork(Integer a) {
+        return i += a;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleProxiesAsIFInstance.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleProxies;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark evaluates the performance of MethodHandleProxies.*
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleProxiesAsIFInstance {
+
+    /**
+     * Implementation notes:
+     *   - asInterfaceInstance() can only target static MethodHandle (adapters needed to call instance method?)
+     *   - baselineCompute will quickly degrade to GC test, if escape analysis is unable to spare the allocation
+     *   - testCreate* will always be slower if allocation is not eliminated; baselineAllocCompute makes sure allocation is present
+     */
+
+    public int i;
+
+    private MethodHandle target;
+    private Doable precreated;
+
+    @Setup
+    public void setup() throws Throwable {
+        target = MethodHandles.lookup().findStatic(MethodHandleProxiesAsIFInstance.class, "doWork", MethodType.methodType(int.class, int.class));
+        precreated = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+    }
+
+    @Benchmark
+    public Doable testCreate() {
+        Doable doable = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+        return doable;              // make sure allocation happens
+    }
+
+    @Benchmark
+    public Doable testCreateCall() {
+        Doable doable = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+        i = doable.doWork(i);       // make sure computation happens
+        return null;                // let allocation be eliminated
+    }
+
+    @Benchmark
+    public Doable testCall() {
+        i = precreated.doWork(i);   // make sure computation happens
+        return precreated;
+    }
+
+    @Benchmark
+    public Doable baselineCompute() {
+        Doable doable = new Doable() {
+            @Override
+            public int doWork(int i) {
+                return MethodHandleProxiesAsIFInstance.doWork(i);
+            }
+        };
+
+        i = doable.doWork(i);       // make sure computation happens
+        return null;                // let allocation be eliminated
+    }
+
+    @Benchmark
+    public Doable baselineAllocCompute() {
+        Doable doable = new Doable() {
+            @Override
+            public int doWork(int i) {
+                return MethodHandleProxiesAsIFInstance.doWork(i);
+            }
+        };
+
+        i = doable.doWork(i);       // make sure computation happens
+        return doable;              // make sure allocation happens
+    }
+
+    public static int doWork(int i) {
+        return i + 1;
+    }
+
+    public interface Doable {
+        int doWork(int i);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandleProxiesSuppl.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleProxies;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark evaluates the performance of MethodHandleProxies.* supplementary methods.
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandleProxiesSuppl {
+
+    /*
+     * Implementation notes:
+     *   - This is a very naive test, evaluates the performance of service methods.
+     */
+
+    private Doable instance;
+
+    @Setup
+    public void setup() throws Throwable {
+        MethodHandle target = MethodHandles.lookup().findStatic(MethodHandleProxiesSuppl.class, "doWork", MethodType.methodType(int.class, int.class));
+        instance = MethodHandleProxies.asInterfaceInstance(Doable.class, target);
+    }
+
+    @Benchmark
+    public Object baselineReturn() {
+        return instance;
+    }
+
+    @Benchmark
+    public boolean testIsWrapperInstance() {
+        return MethodHandleProxies.isWrapperInstance(instance);
+    }
+
+    @Benchmark
+    public Class<?> testInstanceType() {
+        return MethodHandleProxies.wrapperInstanceType(instance);
+    }
+
+    @Benchmark
+    public MethodHandle testInstanceTarget() {
+        return MethodHandleProxies.wrapperInstanceTarget(instance);
+    }
+
+    public static int doWork(int i) {
+        throw new IllegalStateException("Can't touch this");
+    }
+
+    public interface Doable {
+        int doWork(int i);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesArrayElementGetter.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the performance of MethodHandles.arrayElementGetter
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesArrayElementGetter {
+
+    /**
+     * Implementation notes:
+     *   - creating simple array, and accessing the middle element
+     *   - might have done iteration over array, but that will measure pipelining effects instead
+     *   - volatile modifier on array breaks the DCE, which would otherwise eliminate the array load
+     *   - the rationale for array size and access pattern is coherent to SetterBench
+     */
+
+    private static final int SIZE = 1024;
+    private static final int POS = SIZE/2;
+
+    private static MethodHandle mh;
+    private volatile int[] array;
+
+    @Setup
+    public void setup() throws Throwable {
+        array = new int[SIZE];
+        for (int i = 0; i < SIZE; i++) {
+            array[i] = i;
+        }
+        mh = MethodHandles.arrayElementGetter(int[].class);
+    }
+
+    @Benchmark
+    public MethodHandle testCreate() {
+        return MethodHandles.arrayElementGetter(int[].class);
+    }
+
+    @Benchmark
+    public int baselineRaw() {
+        return access(array, POS);
+    }
+
+    @Benchmark
+    public int testGetter() throws Throwable {
+        return (int) mh.invoke(array, POS);
+    }
+
+    public int access(int[] array, int pos) {
+        return array[pos];
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesArrayElementSetter.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the performance of MethodHandles.arrayElementSetter
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesArrayElementSetter {
+
+    /**
+     * Implementation notes:
+     *   - creating simple array, and accessing the middle element
+     *   - might have done iteration over array, but that will measure pipelining effects instead
+     *   - volatile modifier on array breaks the DCE, which would otherwise eliminate the array store
+     *   - the array is not shared to prevent true sharing
+     *   - the array is large enough to prevent false sharing
+     */
+
+    private static final int SIZE = 1024;
+    private static final int POS = SIZE/2;
+
+    private static MethodHandle mh;
+    private volatile int[] array;
+
+    @Setup
+    public void setup() throws Throwable {
+        array = new int[SIZE];
+        for (int i = 0; i < SIZE; i++) {
+            array[i] = i;
+        }
+        mh = MethodHandles.arrayElementSetter(int[].class);
+    }
+
+    @Benchmark
+    public MethodHandle testCreate() {
+        return MethodHandles.arrayElementSetter(int[].class);
+    }
+
+    @Benchmark
+    public void baselineRaw() {
+        access(array, POS, 1);
+    }
+
+    @Benchmark
+    public void testSetter() throws Throwable {
+        mh.invoke(array, POS, 1);
+    }
+
+    public void access(int[] array, int pos, int v) {
+        array[pos] = v;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesCatchException.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.catchException() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesCatchException {
+
+    /**
+     * Implementation notes:
+     *   - emulating instance method handles because of current issue with instance methods
+     *   - exception is cached to harness the MH code, not exception instantiation
+     *   - measuring two modes:
+     *     a) always going through normal code path;
+     *     b) always going through exceptional one
+     *   - baselines do the same thing in pure Java
+     */
+
+    private static final MyException MY_EXCEPTION = new MyException();
+
+    private int i1;
+    private int i2;
+
+    private static MethodHandle methNormal;
+    private static MethodHandle methExceptional;
+
+    @Setup
+    public void setup() throws Throwable {
+        MethodHandle bodyNormal = MethodHandles.lookup()
+            .findStatic(MethodHandlesCatchException.class, "doWorkNormal",
+                MethodType.methodType(void.class, MethodHandlesCatchException.class));
+        MethodHandle bodyExceptional = MethodHandles.lookup()
+            .findStatic(MethodHandlesCatchException.class, "doWorkExceptional",
+                MethodType.methodType(void.class, MethodHandlesCatchException.class));
+        MethodHandle fallback = MethodHandles.lookup()
+            .findStatic(MethodHandlesCatchException.class, "fallback",
+                MethodType.methodType(void.class, MyException.class, MethodHandlesCatchException.class));
+
+        methNormal = MethodHandles.catchException(bodyNormal, MyException.class, fallback);
+        methExceptional = MethodHandles.catchException(bodyExceptional, MyException.class, fallback);
+    }
+
+    @Benchmark
+    public void baselineNormal() {
+        try {
+            doWorkNormal(this);
+        } catch (MyException e) {
+            fallback(e, this);
+        }
+    }
+
+    @Benchmark
+    public void baselineExceptional() {
+        try {
+            doWorkExceptional(this);
+        } catch (MyException e) {
+            fallback(e, this);
+        }
+    }
+
+    @Benchmark
+    public void testNormal() throws Throwable {
+        methNormal.invokeExact(this);
+    }
+
+    @Benchmark
+    public void testExceptional() throws Throwable {
+        methExceptional.invokeExact(this);
+    }
+
+
+    public static void doWorkNormal(MethodHandlesCatchException inst) throws MyException {
+        inst.i1++;
+    }
+
+    public static void doWorkExceptional(MethodHandlesCatchException inst) throws MyException {
+        inst.i1++;
+        throw MY_EXCEPTION;
+    }
+
+    public static void fallback(MyException ex, MethodHandlesCatchException inst) {
+        inst.i2++;
+    }
+
+    public static class MyException extends Exception {
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesConstant.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.constant() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesConstant {
+
+    private MethodHandle mh;
+    private Integer cachedInt;
+
+    @Setup
+    public void setup() {
+        cachedInt = 42;
+        mh = MethodHandles.constant(Integer.class, 42);
+    }
+
+    @Benchmark
+    public Integer baselineReturn() {
+        return cachedInt;
+    }
+
+    @Benchmark
+    public MethodHandle interCreate() throws Throwable {
+        return MethodHandles.constant(Integer.class, 42);
+    }
+
+    @Benchmark
+    public MethodHandle interCreateCached() throws Throwable {
+        return MethodHandles.constant(Integer.class, cachedInt);
+    }
+
+    @Benchmark
+    public Integer testInvoke() throws Throwable {
+        return (Integer) mh.invoke();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesDropArguments.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.dropArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesDropArguments {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     */
+
+    private MethodHandle orig;
+    private MethodHandle modified;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        orig = MethodHandles.lookup().findStatic(MethodHandlesDropArguments.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+        modified = MethodHandles.dropArguments(orig, 0, int.class);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int baselineMH() throws Throwable {
+        return (int) orig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoke() throws Throwable {
+        return (int) modified.invokeExact(0, arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public MethodHandle interCreate() throws Throwable {
+        return MethodHandles.dropArguments(orig, 0, int.class);
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesExactInvoker.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.exactInvoker() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesExactInvoker {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     *   - tested method should perform no worse than the baseline
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mnInvoke;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", mt);
+        mnInvoke = MethodHandles.exactInvoker(mt);
+    }
+
+    @Benchmark
+    public int baselineOrig() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoker() throws Throwable {
+        return (int) mnInvoke.invokeExact(mhOrig, arg1, arg2, arg3);
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFilterArgs.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.filterArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesFilterArgs {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     *   - the filter is empty to measure infra costs, not the filter itself
+     *   - baselines should be comparable for each method if optimized enough
+     */
+
+    private MethodHandle orig;
+    private MethodHandle modified1;
+    private MethodHandle modified2;
+    private MethodHandle modified3;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        orig = MethodHandles.lookup().findStatic(MethodHandlesFilterArgs.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+        MethodHandle filter = MethodHandles.lookup().findStatic(MethodHandlesFilterArgs.class, "filter", MethodType.methodType(Integer.class, Integer.class));
+        modified1 = MethodHandles.filterArguments(orig, 0, filter);
+        modified2 = MethodHandles.filterArguments(orig, 0, filter, filter);
+        modified3 = MethodHandles.filterArguments(orig, 0, filter, filter, filter);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int baselineRawConvert() throws Throwable {
+        return doWork(filter(arg1), filter(arg2), filter(arg3));
+    }
+
+    @Benchmark
+    public int baselineMH() throws Throwable {
+        return (int) orig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int baselineMHConvert() throws Throwable {
+        return (int) orig.invokeExact(filter(arg1), filter(arg2), filter(arg3));
+    }
+
+    @Benchmark
+    public int testInvoke_M1() throws Throwable {
+        return (int) modified1.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoke_M2() throws Throwable {
+        return (int) modified2.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoke_M3() throws Throwable {
+        return (int) modified3.invokeExact(arg1, arg2, arg3);
+    }
+
+    public static Integer filter(Integer a) {
+        return a;
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFilterReturn.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.filterReturnValue() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesFilterReturn {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     */
+
+    private MethodHandle orig;
+    private MethodHandle filter;
+    private MethodHandle modified;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        orig = MethodHandles.lookup().findStatic(MethodHandlesFilterReturn.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+        filter = MethodHandles.lookup().findStatic(MethodHandlesFilterReturn.class, "filter", MethodType.methodType(int.class, int.class));
+        modified = MethodHandles.filterReturnValue(orig, filter);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return filter(doWork(arg1, arg2, arg3));
+    }
+
+    @Benchmark
+    public int baselineMH() throws Throwable {
+        return filter((int) orig.invokeExact(arg1, arg2, arg3));
+    }
+
+    @Benchmark
+    public int testInvoke() throws Throwable {
+        return (int) modified.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public MethodHandle interCreate() throws Throwable {
+        return MethodHandles.filterReturnValue(orig, filter);
+    }
+
+    public static int filter(int a) {
+        return a * 2;
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesFoldArguments.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.foldArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesFoldArguments {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mhFolded;
+    private MethodHandle mhTarget;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandlesFoldArguments.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+        mhFolded = MethodHandles.lookup().findStatic(MethodHandlesFoldArguments.class, "doWork", MethodType.methodType(int.class, int.class, Integer.class, Integer.class, Integer.class));
+        mhTarget = MethodHandles.foldArguments(mhFolded, mhOrig);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_Raw() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_Folded() throws Throwable {
+        return (int) mhFolded.invokeExact(0, arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_Target() throws Throwable {
+        return (int) mhTarget.invokeExact(arg1, arg2, arg3);
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+    public static int doWork(int r, Integer a, Integer b, Integer c) {
+        return r;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesGuardWithTest.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.guardWithTest() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodHandlesGuardWithTest {
+
+    /**
+     * Implementation notes:
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     *   - tested method should perform no worse than the baseline
+     */
+
+    private MethodHandle mhWork1;
+    private MethodHandle mhWork2;
+    private MethodHandle guard;
+    private boolean choice;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+        mhWork1 = MethodHandles.lookup().findVirtual(MethodHandlesGuardWithTest.class, "doWork1", mt);
+        mhWork2 = MethodHandles.lookup().findVirtual(MethodHandlesGuardWithTest.class, "doWork2", mt);
+
+        MethodHandle chooser = MethodHandles.lookup().findVirtual(MethodHandlesGuardWithTest.class, "chooser", MethodType.methodType(boolean.class));
+        guard = MethodHandles.guardWithTest(chooser, mhWork1, mhWork2);
+    }
+
+    @Benchmark
+    public int baselineManual() throws Throwable {
+        if (choice) {
+            return (int) mhWork1.invokeExact(this, arg1, arg2, arg3);
+        } else {
+            return (int) mhWork2.invokeExact(this, arg1, arg2, arg3);
+        }
+    }
+
+    @Benchmark
+    public int testInvoke() throws Throwable {
+        return (int) guard.invoke(this, arg1, arg2, arg3);
+    }
+
+    public boolean chooser() {
+        choice = !choice;
+        return choice;
+    }
+
+    public int doWork1(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+    public int doWork2(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*c + b) + a);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesIdentity.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.identity() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesIdentity {
+
+    private MethodHandle mh;
+    private Object cachedArg;
+
+    @Setup
+    public void setup() {
+        cachedArg = new Object();
+        mh = MethodHandles.identity(Object.class);
+    }
+
+    @Benchmark
+    public Object baselineRaw() throws Throwable {
+        return new Object();
+    }
+
+    @Benchmark
+    public Object baselineRawCached() throws Throwable {
+        return cachedArg;
+    }
+
+    @Benchmark
+    public Object testInvoke() throws Throwable {
+        return mh.invoke(new Object());
+    }
+
+    @Benchmark
+    public Object testInvokeCached() throws Throwable {
+        return mh.invoke(cachedArg);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesInsertArguments.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.insertArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesInsertArguments {
+
+    /**
+     * Implementation notes:
+     *   - this test is similar to MethodHandleBindToCurryBench
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mhCurry1;
+    private MethodHandle mhCurry2;
+    private MethodHandle mhCurry3;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class));
+        mhCurry1 = MethodHandles.insertArguments(mhOrig, 0, arg1);
+        mhCurry2 = MethodHandles.insertArguments(mhOrig, 0, arg1, arg2);
+        mhCurry3 = MethodHandles.insertArguments(mhOrig, 0, arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_C0() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_C1() throws Throwable {
+        return (int) mhCurry1.invokeExact(arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_C2() throws Throwable {
+        return (int) mhCurry2.invokeExact(arg3);
+    }
+
+    @Benchmark
+    public int invoke_C3() throws Throwable {
+        return (int) mhCurry3.invokeExact();
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesInvoker.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.invoker() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesInvoker {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     *   - tested method should perform no worse than the baseline
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mnInvoke;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", mt);
+        mnInvoke = MethodHandles.invoker(mt);
+    }
+
+    @Benchmark
+    public int baselineOrig() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoker() throws Throwable {
+        return (int) mnInvoke.invokeExact(mhOrig, arg1, arg2, arg3);
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesPermuteArguments.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.permuteArguments() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesPermuteArguments {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mhNoReorder;
+    private MethodHandle mhReverse;
+    private MethodHandle mhShift;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+
+    @Setup
+    public void setup() throws Throwable {
+        MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandlesPermuteArguments.class, "doWork", mt);
+        mhNoReorder = MethodHandles.permuteArguments(mhOrig, mt, 0, 1, 2);
+        mhReverse = MethodHandles.permuteArguments(mhOrig, mt, 2, 1, 0);
+        mhShift = MethodHandles.permuteArguments(mhOrig, mt, 2, 0, 1);
+    }
+
+    @Benchmark
+    public int baselineRaw() throws Throwable {
+        return doWork(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_Raw() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_NoReorder() throws Throwable {
+        return (int) mhNoReorder.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_Reverse() throws Throwable {
+        return (int) mhReverse.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int invoke_Shift() throws Throwable {
+        return (int) mhShift.invokeExact(arg1, arg2, arg3);
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesSpreadInvoker.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.spreadInvoker() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesSpreadInvoker {
+
+    /**
+     * Implementation notes:
+     *   - calling static method to have consistent arg list without receiver type
+     *   - using volatile ints as arguments to prevent opportunistic optimizations
+     *   - using Integers to limit argument conversion costs
+     *   - tested method should perform no worse than the baseline
+     */
+
+    private MethodHandle mhOrig;
+    private MethodHandle mnInvoke;
+
+    private volatile Integer arg1 = 42;
+    private volatile Integer arg2 = 43;
+    private volatile Integer arg3 = 44;
+    private Object[] cachedArgs;
+
+    @Setup
+    public void setup() throws Throwable {
+        cachedArgs = new Integer[]{arg1, arg2, arg3};
+
+        MethodType mt = MethodType.methodType(int.class, Integer.class, Integer.class, Integer.class);
+        mhOrig = MethodHandles.lookup().findStatic(MethodHandlesInsertArguments.class, "doWork", mt);
+        mnInvoke = MethodHandles.spreadInvoker(mt, 0);
+    }
+
+    @Benchmark
+    public int baselineOrig() throws Throwable {
+        return (int) mhOrig.invokeExact(arg1, arg2, arg3);
+    }
+
+    @Benchmark
+    public int testInvoker() throws Throwable {
+        return (int) mnInvoke.invokeExact(mhOrig, new Object[] { arg1, arg2, arg3 });
+    }
+
+    @Benchmark
+    public int testInvokerCached() throws Throwable {
+        return (int) mnInvoke.invokeExact(mhOrig, cachedArgs);
+    }
+
+    public static int doWork(Integer a, Integer b, Integer c) {
+        return 31*(31*(31*a + b) + c);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodHandlesThrowException.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses MethodHandles.throwException() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodHandlesThrowException {
+
+    /**
+     * Implementation notes:
+     *   - exceptions have a thorough call back to benchmark instance to prevent elimination (against dumb JITs)
+     *   - testing in plain and cached modes
+     *   - baselines do the same thing, but in pure Java
+     */
+
+    public int flag;
+    private MethodHandle mh;
+    private MyException cachedException;
+
+    @Setup
+    public void setup() {
+        flag = 42;
+        cachedException = new MyException();
+        mh = MethodHandles.throwException(void.class, MyException.class);
+    }
+
+    @Benchmark
+    public int baselineRaw() {
+        try {
+            throw new MyException();
+        } catch (MyException my) {
+            return my.getFlag();
+        }
+    }
+
+    @Benchmark
+    public int baselineRawCached() {
+        try {
+            throw cachedException;
+        } catch (MyException my) {
+            return my.getFlag();
+        }
+    }
+
+    @Benchmark
+    public int testInvoke() throws Throwable {
+        try {
+            mh.invoke(new MyException());
+            throw new IllegalStateException("Should throw exception");
+        } catch (MyException my) {
+            return my.getFlag();
+        }
+    }
+
+    @Benchmark
+    public int testInvokeCached() throws Throwable {
+        try {
+            mh.invoke(cachedException);
+            throw new IllegalStateException("Should throw exception");
+        } catch (MyException my) {
+            return my.getFlag();
+        }
+    }
+
+    @Benchmark
+    public MethodHandle interCreate() {
+        return MethodHandles.throwException(void.class, MyException.class);
+    }
+
+    public class MyException extends Exception {
+
+        public int getFlag() {
+            return flag;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAcquire.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Assesses general MethodType performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeAcquire {
+
+    private MethodType pTypes;
+
+    @Setup
+    public void setup() {
+        pTypes = MethodType.methodType(A.class, B.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return pTypes;
+    }
+
+    @Benchmark
+    public MethodType testReturnVoid() {
+        return MethodType.methodType(void.class);
+    }
+
+    @Benchmark
+    public MethodType testReturnInt() {
+        return MethodType.methodType(int.class);
+    }
+
+    @Benchmark
+    public MethodType testReturnObject() {
+        return MethodType.methodType(Object.class);
+    }
+
+    @Benchmark
+    public MethodType testSinglePType() {
+        return MethodType.methodType(void.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType testMultiPType() {
+        return MethodType.methodType(void.class, A.class, B.class);
+    }
+
+    @Benchmark
+    public MethodType testMultiPType_Arg() {
+        return MethodType.methodType(void.class, pTypes);
+    }
+
+    public static class A {}
+    public static class B {}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAppendParams.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.appendParameterTypes()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeAppendParams {
+
+    /**
+     * Implementation notes:
+     *   - tests multiple cases, gradually appending more arguments
+     *   - baselines include just returning the same method type, and calling with empty argument list
+     */
+
+    private MethodType mt;
+
+    @Setup
+    public void setup() {
+        mt = MethodType.methodType(void.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return mt;
+    }
+
+    @Benchmark
+    public MethodType baselineNop() {
+        return mt.appendParameterTypes();
+    }
+
+    @Benchmark
+    public MethodType test_A1() {
+        return mt.appendParameterTypes(int.class);
+    }
+
+    @Benchmark
+    public MethodType test_A2() {
+        return mt.appendParameterTypes(int.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType test_A3() {
+        return mt.appendParameterTypes(int.class, int.class, int.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeChangeParam.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.changeParameterType()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeChangeParam {
+
+    private MethodType mt;
+
+    @Setup
+    public void setup() {
+        mt = MethodType.methodType(void.class, int.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return mt;
+    }
+
+    @Benchmark
+    public MethodType baselineSame() {
+        return mt.changeParameterType(1, int.class);
+    }
+
+    @Benchmark
+    public MethodType testChangeType() {
+        return mt.changeParameterType(1, Integer.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeChangeReturn.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.changeReturnType()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeChangeReturn {
+
+    private MethodType mt;
+
+    @Setup
+    public void setup() {
+        mt = MethodType.methodType(void.class, int.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return mt;
+    }
+
+    @Benchmark
+    public MethodType baselineSame() {
+        return mt.changeReturnType(void.class);
+    }
+
+    @Benchmark
+    public MethodType testChange() {
+        return mt.changeReturnType(Integer.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeDropParams.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.dropParameterTypes()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeDropParams {
+
+    private MethodType mt;
+
+    @Setup
+    public void setup() {
+        mt = MethodType.methodType(void.class, int.class, int.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return mt;
+    }
+
+    @Benchmark
+    public MethodType baselineSame() {
+        return mt.dropParameterTypes(0, 0);
+    }
+
+    @Benchmark
+    public MethodType testDrop_A1() {
+        return mt.dropParameterTypes(0, 1);
+    }
+
+    @Benchmark
+    public MethodType testDrop_A2() {
+        return mt.dropParameterTypes(0, 2);
+    }
+
+    @Benchmark
+    public MethodType testDrop_A3() {
+        return mt.dropParameterTypes(0, 3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeGenerify.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.erase() performance
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeGenerify {
+
+    private MethodType mt;
+
+    @Setup
+    public void setup() {
+        mt = MethodType.methodType(void.class, int.class, Integer.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return mt;
+    }
+
+    @Benchmark
+    public MethodType testGeneric() {
+        return mt.generic();
+    }
+
+    @Benchmark
+    public MethodType testWrapErase() {
+        return mt.wrap().erase();
+    }
+
+    @Benchmark
+    public MethodType testErase() {
+        return mt.erase();
+    }
+
+    @Benchmark
+    public MethodType testWrap() {
+        return mt.wrap();
+    }
+
+    @Benchmark
+    public MethodType testUnwrap() {
+        return mt.unwrap();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeInsertParams.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.MethodType;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses the MethodType.insertParameterTypes()
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class MethodTypeInsertParams {
+
+    private MethodType mt;
+
+    @Setup
+    public void setup() {
+        mt = MethodType.methodType(void.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType baselineRaw() {
+        return mt;
+    }
+
+    @Benchmark
+    public MethodType baselineSame() {
+        return mt.insertParameterTypes(0);
+    }
+
+    @Benchmark
+    public MethodType testInsert_A1() {
+        return mt.insertParameterTypes(0, int.class);
+    }
+
+    @Benchmark
+    public MethodType testInsert_A2() {
+        return mt.insertParameterTypes(0, int.class, int.class);
+    }
+
+    @Benchmark
+    public MethodType testInsert_A3() {
+        return mt.insertParameterTypes(0, int.class, int.class, int.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/SwitchPointAdhoc.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MutableCallSite;
+import java.lang.invoke.SwitchPoint;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assessing SwitchPoint performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SwitchPointAdhoc {
+
+    /*
+     * Implementation notes:
+     *   - this test asserts SwitchPoint performance in both valid and invalid cases
+     *   - this test does not assert invalidation performance (hard to do with irreversible SwitchPoint)
+     *   - raw baseline gives the idea for MethodHandle invocation cost
+     *   - CS baseline gives the idea for additional dereference cost
+     */
+
+    private MethodHandle body1, body2;
+    private int i;
+    private java.lang.invoke.SwitchPoint sw1, sw2;
+    private CallSite cs;
+
+    @Setup
+    public void setup() throws NoSuchMethodException, IllegalAccessException {
+        sw1 = new java.lang.invoke.SwitchPoint();
+        sw2 = new java.lang.invoke.SwitchPoint();
+        SwitchPoint.invalidateAll(new SwitchPoint[]{sw2});
+        body1 = MethodHandles.lookup().findVirtual(SwitchPointAdhoc.class, "body1", MethodType.methodType(int.class, int.class));
+        body2 = MethodHandles.lookup().findVirtual(SwitchPointAdhoc.class, "body2", MethodType.methodType(int.class, int.class));
+        cs = new MutableCallSite(body1);
+    }
+
+    @Benchmark
+    public void baselineRaw() throws Throwable {
+        i = (int) body1.invoke(this, i);
+    }
+
+    @Benchmark
+    public void baselineCS() throws Throwable {
+        i = (int) cs.getTarget().invoke(this, i);
+    }
+
+    @Benchmark
+    public void testValid() throws Throwable {
+        MethodHandle handle = sw1.guardWithTest(body1, body2);
+        i = (int) handle.invoke(this, i);
+    }
+
+    @Benchmark
+    public void testInvalid() throws Throwable {
+        MethodHandle handle = sw2.guardWithTest(body1, body2);
+        i = (int) handle.invoke(this, i);
+    }
+
+    public int body1(int i) {
+        return i + 1;
+    }
+
+    public int body2(int i) {
+        return i + 1;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/SwitchPointGuard.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.invoke.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assessing SwitchPoint performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SwitchPointGuard {
+
+    /*
+     * Implementation notes:
+     *   - this test asserts SwitchPoint performance in both valid and invalid cases
+     *   - this test does not assert invalidation performance (hard to do with irreversible SwitchPoint)
+     *   - raw baseline gives the idea for MethodHandle invocation cost
+     *   - CS baseline gives the idea for additional dereference cost
+     */
+
+    private MethodHandle body1, body2;
+    private int i;
+    private SwitchPoint sw1, sw2;
+    private CallSite cs;
+    private MethodHandle guard1, guard2;
+
+    @Setup
+    public void setup() throws NoSuchMethodException, IllegalAccessException {
+        sw1 = new SwitchPoint();
+        sw2 = new SwitchPoint();
+        SwitchPoint.invalidateAll(new SwitchPoint[]{sw2});
+        body1 = MethodHandles.lookup().findVirtual(SwitchPointGuard.class, "body1", MethodType.methodType(int.class, int.class));
+        body2 = MethodHandles.lookup().findVirtual(SwitchPointGuard.class, "body2", MethodType.methodType(int.class, int.class));
+        guard1 = sw1.guardWithTest(body1, body2);
+        guard2 = sw2.guardWithTest(body1, body2);
+        cs = new MutableCallSite(body1);
+    }
+
+    @Benchmark
+    public void baselineRaw() throws Throwable {
+        i = (int) body1.invoke(this, i);
+    }
+
+    @Benchmark
+    public void baselineCS() throws Throwable {
+        i = (int) cs.getTarget().invoke(this, i);
+    }
+
+    @Benchmark
+    public void testValid() throws Throwable {
+        i = (int) guard1.invoke(this, i);
+    }
+
+    @Benchmark
+    public void testInvalid() throws Throwable {
+        i = (int) guard2.invoke(this, i);
+    }
+
+    public int body1(int i) {
+        return i + 1;
+    }
+
+    public int body2(int i) {
+        return i + 1;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Clazz {
+
+    /**
+     * Get constructor for this class through reflection
+     *
+     * @return
+     * @throws NoSuchMethodException
+     */
+    @Benchmark
+    public Constructor getConstructor() throws NoSuchMethodException {
+        return Clazz.class.getConstructor();
+    }
+
+    /**
+     * Get constructor for the String class through reflection, forcing full
+     * security check
+     *
+     * @return
+     * @throws NoSuchMethodException
+     */
+    @Benchmark
+    public Constructor getConstructorDifferentClassLoader() throws NoSuchMethodException {
+        return String.class.getConstructor();
+    }
+
+    /**
+     * Get the toString method through reflection on Clazz
+     *
+     * @return
+     */
+    @Benchmark
+    public Method getMethod() throws NoSuchMethodException {
+        return Clazz.class.getMethod("toString");
+    }
+
+    /**
+     * Get the toString method through reflection on String, forcing full
+     * security check
+     *
+     * @return
+     * @throws NoSuchMethodException
+     */
+    @Benchmark
+    public Method getMethodDifferentClassLoader() throws NoSuchMethodException {
+        return String.class.getMethod("toString");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/ClazzWithSecurityManager.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.reflect;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Policy;
+import java.security.URIParameter;
+
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+/**
+ * Reflection benchmark
+ *
+ * @author sfriberg
+ */
+@State(Scope.Benchmark)
+public class ClazzWithSecurityManager extends Clazz {
+
+    @Setup
+    public void setup() throws IOException, NoSuchAlgorithmException, URISyntaxException {
+        URI policyFile = ClazzWithSecurityManager.class.getResource("/jmh-security.policy").toURI();
+        Policy.setPolicy(Policy.getInstance("JavaPolicy", new URIParameter(policyFile)));
+        System.setSecurityManager(new SecurityManager());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/MethodInvoke.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.lang.reflect;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring java.lang.reflect.Method.invoke speed.
+ * <p/>
+ * TODO: Add tests for virtual and interface methods.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MethodInvoke {
+
+    private Method staticMeth_0;
+    private Method staticMeth_6ref;
+    private Method staticMeth_6prim;
+
+    private Object[] args_0;
+    private Object[] args_6ref;
+    private Object[] args_6prim;
+
+    @Setup
+    public void setup() {
+        args_0 = new Object[]{};
+        args_6ref = new Object[]{ new Object(), new Object(),
+                new Object(), new Object(), new Object(), new Object()};
+        args_6prim = new Object[]{
+                new Integer(1), new Long(5L),
+                new Double(5.6d), new Float(23.11f),
+                Boolean.TRUE, new Character('d')
+        };
+
+        staticMeth_0 = getMethodWithName("staticMethodWithoutParams");
+        staticMeth_6ref = getMethodWithName("staticMethodWithSixObjectParams");
+        staticMeth_6prim = getMethodWithName("staticMethodWithSixPrimitiveParams");
+    }
+
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public static void staticMethodWithoutParams() {
+        // intentionally left blank
+    }
+
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public static void staticMethodWithSixObjectParams(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) {
+        // intentionally left blank
+    }
+
+    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+    public static void staticMethodWithSixPrimitiveParams(int i, long j, double d, float f, boolean z, char c) {
+        // intentionally left blank
+    }
+
+    /* inner method to get the method to invoke. */
+
+    private static Method getMethodWithName(String methodName) {
+        Method[] methodArray = MethodInvoke.class.getMethods();
+        for (Method m : methodArray) {
+            if (m.getName().equals(methodName)) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    @Benchmark
+    public void invokeWithoutParams() throws InvocationTargetException, IllegalAccessException {
+        staticMeth_0.invoke(null, args_0);
+    }
+
+    @Benchmark
+    public void invokeWithSixObjectParams() throws Exception {
+        staticMeth_6ref.invoke(null, args_6ref);
+    }
+
+    @Benchmark
+    public void invokeWithSixPrimitiveParams() throws Exception {
+        staticMeth_6prim.invoke(null, args_6prim);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/math/BigDecimals.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.math;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.math.BigDecimal;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class BigDecimals {
+
+    /** Make sure TEST_SIZE is used to size the arrays. We need this constant to parametrize the operations count. */
+    private static final int TEST_SIZE = 100;
+
+    /* dummy variables for intermediate results */
+    public Object[] dummyArr;
+    public String[] dummyStringArray;
+    public int dummy;
+
+    /* array to hold the created objects. */
+    private BigDecimal[] bigDecimals;
+    private String[] stringInputs;
+    private double[] doubleInputs;
+    private BigDecimal[] hugeArray, largeArray, smallArray;
+
+    @Setup
+    public void setup() {
+        Random r = new Random(1123);
+        dummyArr = new Object[TEST_SIZE];
+        bigDecimals = new BigDecimal[TEST_SIZE];
+        stringInputs = new String[TEST_SIZE];
+        doubleInputs = new double[TEST_SIZE];
+        for (int i = 0; i < TEST_SIZE; i++) {
+            double value = (double) (i + 1);
+            switch (i % 4) {
+                case 0:
+                    value = -value * 54345.0d;
+                    break;
+                case 1:
+                    value = value * 5434543453454355e100;
+                    break;
+                case 2:
+                    value = -value / 5434543453454355e100;
+                    break;
+                case 3:
+                    break;
+            }
+
+            bigDecimals[i] = new BigDecimal(value);
+            stringInputs[i] = "" + value;
+            doubleInputs[i] = value;
+        }
+
+        /*
+         * Huge numbers larger than MAX_LONG
+         */
+        hugeArray = new BigDecimal[TEST_SIZE];
+
+        /*
+        * Large numbers less than MAX_LONG but larger than MAX_INT
+        */
+        largeArray = new BigDecimal[TEST_SIZE];
+
+        /*
+        * Small number less than MAX_INT
+        */
+        smallArray = new BigDecimal[TEST_SIZE];
+
+        dummyStringArray = new String[TEST_SIZE];
+        for (int i = 0; i < TEST_SIZE; i++) {
+            int value = Math.abs(r.nextInt());
+            hugeArray[i] = new BigDecimal("" + ((long) value + (long) Integer.MAX_VALUE)
+                    + ((long) value + (long) Integer.MAX_VALUE) + ".55");
+            largeArray[i] = new BigDecimal("" + ((long) value + (long) Integer.MAX_VALUE) + ".55");
+            smallArray[i] = new BigDecimal("" + ((long) value / 1000) + ".55");
+        }
+    }
+
+    /** Invokes the (String)-constructor of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testConstructorWithString(Blackhole bh) {
+        for (String s : stringInputs) {
+            bh.consume(new BigDecimal(s));
+        }
+    }
+
+    /** Invokes the (double)-constructor of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testConstructorWithDouble(Blackhole bh) {
+        for (double s : doubleInputs) {
+            bh.consume(new BigDecimal(s));
+        }
+    }
+
+    /** Invokes the toString method of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testToString(Blackhole bh) {
+        for (BigDecimal s : bigDecimals) {
+            bh.consume(s.toString());
+        }
+    }
+
+    /**
+     * Invokes the setScale method of BigDecimal with various different values.
+     */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testSetScale(Blackhole bh) {
+        for (BigDecimal s : bigDecimals) {
+            bh.consume(s.setScale(2, BigDecimal.ROUND_HALF_UP));
+        }
+    }
+
+    /** Invokes the setScale method of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(50 * TEST_SIZE)
+    public void testSetScaleVarious(Blackhole bh) {
+        for (int scale = 0; scale < 50; scale++) {
+            for (BigDecimal s : bigDecimals) {
+                bh.consume(s.setScale(scale, BigDecimal.ROUND_HALF_UP));
+            }
+        }
+    }
+
+    /** Invokes the add method of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testAdd(Blackhole bh) {
+        BigDecimal tmp = null;
+        for (BigDecimal s : bigDecimals) {
+            if (tmp == null) {
+                tmp = s;
+                continue;
+            }
+            tmp = tmp.add(s);
+        }
+        bh.consume(tmp);
+    }
+
+    /** Invokes the multiply method of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testMultiply(Blackhole bh) {
+        BigDecimal tmp = null;
+        for (BigDecimal s : bigDecimals) {
+            if (tmp == null) {
+                tmp = s;
+                continue;
+            }
+            tmp = tmp.multiply(s);
+        }
+        bh.consume(tmp);
+    }
+
+    /** Invokes the compareTo method of BigDecimal with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE - 1)
+    public void testCompareTo(Blackhole bh) {
+        BigDecimal c = bigDecimals[0];
+        for (BigDecimal s : bigDecimals) {
+            bh.consume(c.compareTo(s));
+        }
+    }
+
+    /** Test BigDecimal.toString() with huge numbers larger than MAX_LONG */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testHugeToString(Blackhole bh) {
+        for (BigDecimal s : hugeArray) {
+            bh.consume(s.toString());
+        }
+    }
+
+    /** Test BigDecimal.toString() with large numbers less than MAX_LONG but larger than MAX_INT */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testLargeToString(Blackhole bh) {
+        for (BigDecimal s : largeArray) {
+            bh.consume(s.toString());
+        }
+    }
+
+    /** Test BigDecimal.toString() with small numbers less than MAX_INT */
+    @Benchmark
+    @OperationsPerInvocation(TEST_SIZE)
+    public void testSmallToString(Blackhole bh) {
+        for (BigDecimal s : smallArray) {
+            bh.consume(s.toString());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/math/BigIntegers.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.openjdk.bench.java.math;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.math.BigInteger;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class BigIntegers {
+
+    private BigInteger[] hugeArray, largeArray, smallArray;
+    public String[] dummyStringArray;
+    public Object[] dummyArr;
+    private static final int TESTSIZE = 1000;
+
+    @Setup
+    public void setup() {
+        Random r = new Random(1123);
+
+        hugeArray = new BigInteger[TESTSIZE]; /*
+         * Huge numbers larger than
+         * MAX_LONG
+         */
+        largeArray = new BigInteger[TESTSIZE]; /*
+         * Large numbers less than
+         * MAX_LONG but larger than
+         * MAX_INT
+         */
+        smallArray = new BigInteger[TESTSIZE]; /*
+         * Small number less than
+         * MAX_INT
+         */
+
+        dummyStringArray = new String[TESTSIZE];
+        dummyArr = new Object[TESTSIZE];
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            int value = Math.abs(r.nextInt());
+
+            hugeArray[i] = new BigInteger("" + ((long) value + (long) Integer.MAX_VALUE)
+                    + ((long) value + (long) Integer.MAX_VALUE));
+            largeArray[i] = new BigInteger("" + ((long) value + (long) Integer.MAX_VALUE));
+            smallArray[i] = new BigInteger("" + ((long) value / 1000));
+        }
+    }
+
+    /** Test BigInteger.toString() with huge numbers larger than MAX_LONG */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void testHugeToString(Blackhole bh) {
+        for (BigInteger s : hugeArray) {
+            bh.consume(s.toString());
+        }
+    }
+
+    /** Test BigInteger.toString() with large numbers less than MAX_LONG but larger than MAX_INT */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void testLargeToString(Blackhole bh) {
+        for (BigInteger s : largeArray) {
+            bh.consume(s.toString());
+        }
+    }
+
+    /** Test BigInteger.toString() with small numbers less than MAX_INT */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void testSmallToString(Blackhole bh) {
+        for (BigInteger s : smallArray) {
+            bh.consume(s.toString());
+        }
+    }
+
+    /** Invokes the multiply method of BigInteger with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void testMultiply(Blackhole bh) {
+        BigInteger tmp = null;
+        for (BigInteger s : hugeArray) {
+            if (tmp == null) {
+                tmp = s;
+                continue;
+            }
+            tmp = tmp.multiply(s);
+        }
+        bh.consume(tmp);
+    }
+
+    /** Invokes the multiply method of BigInteger with various different values. */
+    @Benchmark
+    @OperationsPerInvocation(TESTSIZE)
+    public void testAdd(Blackhole bh) {
+        BigInteger tmp = null;
+        for (BigInteger s : hugeArray) {
+            if (tmp == null) {
+                tmp = s;
+                continue;
+            }
+            tmp = tmp.add(s);
+        }
+        bh.consume(tmp);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/DatagramSocketTest.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * DatagramSocket micros designed to stress UDP performance.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class DatagramSocketTest {
+
+    @Param({"1024", "2048", "4096", "8192", "16384", "32768"})
+    int size;
+
+    private DatagramSocket socket;
+    private DatagramPacket packet;
+
+    @Setup
+    public void prepare() throws SocketException, UnknownHostException {
+        socket = new DatagramSocket();
+
+        byte[] buf = new byte[size];
+        packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("localhost"), 9877);
+    }
+
+    @TearDown
+    public void cleanup() {
+        socket.close();
+    }
+
+    @Benchmark
+    public void testSend() throws IOException {
+        socket.send(packet);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/SocketChannelReadWrite.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.*;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on network conditions and paltform.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class SocketChannelReadWrite {
+
+    private ServerSocketChannel ssc;
+    private SocketChannel s1, s2;
+    private ReadThread rt;
+    private ByteBuffer bb = ByteBuffer.allocate(1);
+
+    @Setup(Level.Trial)
+    public void beforeRun() throws IOException {
+        InetAddress iaddr = InetAddress.getLocalHost();
+
+        ssc = ServerSocketChannel.open().bind(null);
+        s1 = SocketChannel.open(new InetSocketAddress(iaddr, ssc.socket().getLocalPort()));
+        s2 = ssc.accept();
+
+        rt = new ReadThread(s2);
+        rt.start();
+
+        bb.put((byte) 47);
+        bb.flip();
+    }
+
+    @TearDown(Level.Trial)
+    public void afterRun() throws IOException, InterruptedException {
+        s1.close();
+        s2.close();
+        ssc.close();
+        rt.join();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        s1.write(bb);
+        bb.flip();
+    }
+
+    static class ReadThread extends Thread {
+        private SocketChannel sc;
+
+        public ReadThread(SocketChannel s2) {
+            this.sc = s2;
+        }
+
+        public void run() {
+            try {
+                ByteBuffer bb = ByteBuffer.allocate(1);
+                while (sc.read(bb) > 0) {
+                    bb.flip();
+                }
+            } catch (ClosedChannelException ex) {
+                // shutdown time
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/SocketReadWrite.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+/**
+ * Tests the overheads of I/O API.
+ * This test is known to depend heavily on network conditions and paltform.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class SocketReadWrite {
+
+    private OutputStream os;
+    private InputStream is;
+    private ServerSocket ss;
+    private Socket s1, s2;
+    private ReadThread rt;
+
+    @Setup
+    public void beforeRun() throws IOException {
+        InetAddress iaddr = InetAddress.getLocalHost();
+
+        ss = new ServerSocket(0);
+        s1 = new Socket(iaddr, ss.getLocalPort());
+        s2 = ss.accept();
+
+        os = s1.getOutputStream();
+        is = s2.getInputStream();
+
+        rt = new ReadThread(is);
+        rt.start();
+    }
+
+    @TearDown
+    public void afterRun() throws IOException, InterruptedException {
+        os.write(0);
+        os.close();
+        is.close();
+        s1.close();
+        s2.close();
+        ss.close();
+        rt.join();
+    }
+
+    @Benchmark
+    public void test() throws IOException {
+        os.write((byte) 4711);
+    }
+
+    static class ReadThread extends Thread {
+        private InputStream is;
+
+        public ReadThread(InputStream is) {
+            this.is = is;
+        }
+
+        public void run() {
+            try {
+                while (is.read() > 0);
+            } catch (SocketException ex) {
+                // ignore - most likely "socket closed", which means shutdown
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/SocketStreaming.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Micro benchmark for streaming data over a Socket.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class SocketStreaming {
+
+    /** The bytes to write/read. */
+    public static final int dataLength = 16383;
+    /** setTcpNoDelay(noNagle) */
+    public static final boolean noNagle = false;
+
+    private WriterThread writerThread;
+    private Socket readSocket;
+    private byte[] bytes;
+
+    @Setup
+    public void prepare() throws Exception {
+        bytes = new byte[dataLength];
+
+        // Setup the writer thread
+        writerThread = new WriterThread(dataLength, noNagle);
+        writerThread.start();
+
+        // Wait for a read socket
+        readSocket = writerThread.waitForReadSocket();
+    }
+
+    @TearDown
+    public void cleanup() throws IOException {
+        // Take down the writer thread and the reader socket
+        writerThread.finish();
+        while (!readSocket.isClosed()) {
+            readSocket.close();
+        }
+        readSocket = null;
+    }
+
+    @Benchmark
+    public void testSocketInputStreamRead() throws InterruptedException, IOException {
+        InputStream in = readSocket.getInputStream();
+
+        // Notify the writer thread to add elements to stream
+        writerThread.requestSendBytes();
+
+        // Read these from the stream
+        int bytesRead = 0;
+        while (bytesRead < dataLength) {
+            int lastRead = in.read(bytes);
+            if (lastRead < 0) {
+                throw new InternalError("Unexpectedly got " + lastRead + " bytes from the socket");
+            }
+            bytesRead += lastRead;
+        }
+    }
+
+    /**
+     * Thread used to write bytes to a socket.
+     */
+    private class WriterThread extends Thread {
+
+        /** The number of bytes to write. */
+        private int dataLength;
+        /** setTcpNoDelay(noNagle) */
+        private boolean noNagle;
+        /** Lock needed to send sendBytes requests. */
+        private final Object sendBytesLock = new Object();
+        /** Indicates that a sendBytes has been requested. */
+        private boolean sendBytesRequested;
+        /** Indicates that no more sendBytes will be requested. Time to shutdown. */
+        private boolean sendBytesDone;
+        /** Lock needed to protect the connectPort variable. */
+        private final Object connectLock = new Object();
+        /** The port the read socket should connect to. */
+        private int connectPort = -1;
+
+        /**
+         * Constructor.
+         *
+         * @param dataLength The number of bytes to write
+         * @param noNagle    setTcpNoDelay(noNagle)
+         */
+        public WriterThread(int dataLength, boolean noNagle) {
+            super("Load producer");
+            this.dataLength = dataLength;
+            this.noNagle = noNagle;
+        }
+
+        /** Entry point for data sending helper thread. */
+        @Override
+        public void run() {
+            try {
+                Socket writeSocket;
+                ServerSocket serverSocket = new ServerSocket(0);
+
+                /* Tell the other thread that we now know the port number.
+                 * The other thread will now start to connect until the following accept() call succeeds.
+                 */
+                synchronized (connectLock) {
+                    connectPort = serverSocket.getLocalPort();
+                    connectLock.notify();
+                }
+
+                // Wait for the other thread to connect
+                writeSocket = serverSocket.accept();
+                writeSocket.setTcpNoDelay(noNagle);
+
+                // No more connects so this can be closed
+                serverSocket.close();
+                serverSocket = null;
+
+                OutputStream out = writeSocket.getOutputStream();
+
+                // Iterate as long as sendBytes are issued
+                while (waitForSendBytesRequest()) {
+                    sendBytes(out);
+                }
+
+                // Time to shutdown
+                while (!writeSocket.isClosed()) {
+                    writeSocket.close();
+                }
+                writeSocket = null;
+            } catch (Exception e) {
+                System.exit(1);
+            }
+        }
+
+        /**
+         * Sends bytes to the output stream
+         *
+         * @param out The output stream
+         * @throws IOException
+         */
+        private void sendBytes(OutputStream out) throws IOException {
+            byte outBytes[] = new byte[dataLength];
+
+            int bytesToSend = dataLength;
+            int bytesSent = 0;
+            while (bytesSent < bytesToSend) {
+                out.write(outBytes);
+                bytesSent += outBytes.length;
+            }
+        }
+
+        /**
+         * Waits for the readSocket and returns it when it is ready.
+         *
+         * @return The socket to read from
+         * @throws InterruptedException
+         */
+        @SuppressWarnings("SleepWhileHoldingLock")
+        public Socket waitForReadSocket() throws InterruptedException {
+            int theConnectPort = waitForConnectPort();
+
+            while (true) {
+                try {
+                    return new Socket(InetAddress.getByName(null), theConnectPort);
+                } catch (IOException e) {
+                    // Wait some more for the server thread to get going
+                    Thread.sleep(1000);
+                }
+            }
+
+        }
+
+        /**
+         * Waits for next sendBytes request
+         *
+         * @return <code>true</code> if it is time to sendBytes, <code>false</code> if it is time to shutdown
+         * @throws InterruptedException
+         */
+        public boolean waitForSendBytesRequest() throws InterruptedException {
+            synchronized (sendBytesLock) {
+                while (!sendBytesRequested && !sendBytesDone) {
+                    sendBytesLock.wait();
+                }
+
+                // Clear the flag
+                sendBytesRequested = false;
+
+                return !sendBytesDone;
+            }
+        }
+
+        /** Requests a sendBytes. */
+        public void requestSendBytes() {
+            synchronized (sendBytesLock) {
+                sendBytesRequested = true;
+                sendBytesLock.notify();
+            }
+        }
+
+        /** Tells the writerThread that it is time to shutdown. */
+        public void finish() {
+            synchronized (sendBytesLock) {
+                sendBytesDone = true;
+                sendBytesLock.notify();
+            }
+        }
+
+        private int waitForConnectPort() throws InterruptedException {
+            synchronized (connectLock) {
+                while (connectPort == -1) {
+                    connectLock.wait();
+                }
+                return connectPort;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/net/URLEncodeDecode.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.net;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.net.URLEncoder.encode and Decoder.decode.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class URLEncodeDecode {
+
+    @Param("1024")
+    public int count;
+
+    @Param("1024")
+    public int maxLength;
+
+    @Param("3")
+    public long mySeed;
+
+    public String[] testStringsEncode;
+    public String[] testStringsDecode;
+    public String[] toStrings;
+
+    @Setup
+    public void setupStrings() {
+        char[] tokens = new char[((int) 'Z' - (int) 'A' + 1) + ((int) 'z' - (int) 'a' + 1) + ((int) '9' - (int) '1' + 1) + 5];
+        int n = 0;
+        tokens[n++] = '0';
+        for (int i = (int) '1'; i <= (int) '9'; i++) {
+            tokens[n++] = (char) i;
+        }
+        for (int i = (int) 'A'; i <= (int) 'Z'; i++) {
+            tokens[n++] = (char) i;
+        }
+        for (int i = (int) 'a'; i <= (int) '<'; i++) {
+            tokens[n++] = (char) i;
+        }
+        tokens[n++] = '-';
+        tokens[n++] = '_';
+        tokens[n++] = '.';
+        tokens[n++] = '*';
+
+        Random r = new Random(mySeed);
+        testStringsEncode = new String[count];
+        testStringsDecode = new String[count];
+        toStrings = new String[count];
+        for (int i = 0; i < count; i++) {
+            int l = r.nextInt(maxLength);
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < l; j++) {
+                int c = r.nextInt(tokens.length);
+                sb.append(tokens[c]);
+            }
+            testStringsEncode[i] = sb.toString();
+        }
+
+        for (int i = 0; i < count; i++) {
+            int l = r.nextInt(maxLength);
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < l; j++) {
+                int c = r.nextInt(tokens.length + 5);
+                if (c >= tokens.length) {
+                    sb.append("%").append(tokens[r.nextInt(16)]).append(tokens[r.nextInt(16)]);
+                } else {
+                    sb.append(tokens[c]);
+                }
+            }
+            testStringsDecode[i] = sb.toString();
+        }
+    }
+
+    @Benchmark
+    public void testEncodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
+        for (String s : testStringsEncode) {
+            bh.consume(java.net.URLEncoder.encode(s, "UTF-8"));
+        }
+    }
+
+    @Benchmark
+    public void testDecodeUTF8(Blackhole bh) throws UnsupportedEncodingException {
+        for (String s : testStringsDecode) {
+            bh.consume(URLDecoder.decode(s, "UTF-8"));
+        }
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/nio/ByteBuffers.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.nio;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark operations on java.nio.Buffer.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ByteBuffers {
+
+    @Param({"10", "1000", "100000"})
+    private int size;
+
+    public byte dummyByte;
+    public char dummyChar;
+    public short dummyShort;
+    public int dummyInt;
+    public long dummyLong;
+    public float dummyFloat;
+    public double dummyDouble;
+
+    // ---------------- BULK GET TESTS
+
+    @Benchmark
+    public byte[] testBulkGet() {
+        return innerBufferBulkGet(ByteBuffer.allocate(size));
+    }
+
+    @Benchmark
+    public byte[] testDirectBulkGet() {
+        return innerBufferBulkGet(ByteBuffer.allocateDirect(size));
+    }
+
+    // ---------------- BULK PUT TESTS
+
+    @Benchmark
+    public byte[] testBulkPut() {
+        return innerBufferBulkPut(ByteBuffer.allocate(size));
+    }
+
+    @Benchmark
+    public byte[] testDirectBulkPut() {
+        return innerBufferBulkPut(ByteBuffer.allocateDirect(size));
+    }
+
+    // ---------------- SINGLE GET TESTS
+
+    @Benchmark
+    public int testSingleGetByte() {
+        return innerSingleGetByte(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public int testSingleGetChar() {
+        return innerSingleGetChar(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public int testSingleGetShort() {
+        return innerSingleGetShort(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public int testSingleGetInt() {
+        return innerSingleGetInt(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public long testSingleGetLong() {
+        return innerSingleGetLong(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public float testSingleGetFloat() {
+        return innerSingleGetFloat(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public double testSingleGetDouble() {
+        return innerSingleGetDouble(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public int testDirectSingleGetByte() {
+        return innerSingleGetByte(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public int testDirectSingleGetChar() {
+        return innerSingleGetChar(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public int testDirectSingleGetShort() {
+        return innerSingleGetShort(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public int testDirectSingleGetInt() {
+        return innerSingleGetInt(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public long testDirectSingleGetLong() {
+        return innerSingleGetLong(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public float testDirectSingleGetFloat() {
+        return innerSingleGetFloat(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public double testDirectSingleGetDouble() {
+        return innerSingleGetDouble(ByteBuffer.allocateDirect(1000));
+    }
+
+    // ---------------- SINGLE PUT TESTS
+
+    @Benchmark
+    public void testSinglePutByte() {
+        innerSinglePutByte(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testSinglePutChar() {
+        innerSinglePutChar(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testSinglePutShort() {
+        innerSinglePutShort(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testSinglePutInt() {
+        innerSinglePutInt(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testSinglePutLong() {
+        innerSinglePutLong(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testSinglePutFloat() {
+        innerSinglePutFloat(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testSinglePutDouble() {
+        innerSinglePutDouble(ByteBuffer.allocate(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutByte() {
+        innerSinglePutByte(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutChar() {
+        innerSinglePutChar(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutShort() {
+        innerSinglePutShort(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutInt() {
+        innerSinglePutInt(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutLong() {
+        innerSinglePutLong(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutFloat() {
+        innerSinglePutFloat(ByteBuffer.allocateDirect(1000));
+    }
+
+    @Benchmark
+    public void testDirectSinglePutDouble() {
+        innerSinglePutDouble(ByteBuffer.allocateDirect(1000));
+    }
+
+    // ---------------- HELPER METHODS
+
+    private byte[] innerBufferBulkGet(ByteBuffer bb) {
+        byte[] dummyByteArray = new byte[bb.capacity()];
+        bb.get(dummyByteArray);
+        bb.flip();
+        return dummyByteArray;
+    }
+
+    private byte[] innerBufferBulkPut(ByteBuffer bb) {
+        byte[] dummyByteArray = new byte[bb.capacity()];
+        bb.put(dummyByteArray);
+        bb.flip();
+        return dummyByteArray;
+    }
+
+    private int innerSingleGetByte(ByteBuffer bb) {
+        int r = 0;
+        for (int i = 0; i < bb.capacity(); i++) {
+            r += bb.get(i);
+        }
+        return r;
+    }
+
+    private int innerSingleGetChar(ByteBuffer bb) {
+        int r = 0;
+        for (int i = 0; i < bb.capacity(); i += 2) {
+            r += bb.getChar(i);
+        }
+        return r;
+    }
+
+    private int innerSingleGetShort(ByteBuffer bb) {
+        int r = 0;
+        for (int i = 0; i < bb.capacity(); i += 2) {
+            r += bb.getShort(i);
+        }
+        return r;
+    }
+
+    private int innerSingleGetInt(ByteBuffer bb) {
+        int r = 0;
+        for (int i = 0; i < bb.capacity(); i += 4) {
+            r += bb.getInt(i);
+        }
+        return r;
+    }
+
+    private long innerSingleGetLong(ByteBuffer bb) {
+        long r = 0;
+        for (int i = 0; i < bb.capacity(); i += 8) {
+            r += bb.getLong(i);
+        }
+        return r;
+    }
+
+    private float innerSingleGetFloat(ByteBuffer bb) {
+        float r = 0;
+        for (int i = 0; i < bb.capacity(); i += 4) {
+            r += bb.getFloat(i);
+        }
+        return r;
+    }
+
+    private double innerSingleGetDouble(ByteBuffer bb) {
+        double d = 0;
+        for (int i = 0; i < bb.capacity(); i += 8) {
+            d += bb.getDouble(i);
+        }
+        return d;
+    }
+
+    private void innerSinglePutByte(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i++) {
+            bb.put(i, dummyByte);
+        }
+    }
+
+    private void innerSinglePutChar(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i += 2) {
+            bb.putChar(i, dummyChar);
+        }
+    }
+
+    private void innerSinglePutShort(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i += 2) {
+            bb.putShort(i, dummyShort);
+        }
+    }
+
+    private void innerSinglePutInt(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i += 4) {
+            bb.putInt(i, dummyInt);
+        }
+    }
+
+    private void innerSinglePutLong(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i += 8) {
+            bb.putLong(i, dummyLong);
+        }
+    }
+
+    private void innerSinglePutFloat(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i += 4) {
+            bb.putFloat(i, dummyFloat);
+        }
+    }
+
+    private void innerSinglePutDouble(ByteBuffer bb) {
+        for (int i = 0; i < bb.capacity(); i += 8) {
+            bb.putDouble(i, dummyDouble);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/nio/CharsetEncodeDecode.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.nio;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark tests the encode/decode loops on different Charsets. It was created from an adhoc benchmark addressing
+ * a performance issue which in the end boiled down to the encode/decode loops. This is the reason for the values on the
+ * char and byte arrays.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class CharsetEncodeDecode {
+
+    private byte[] BYTES;
+    private char[] CHARS;
+
+    private CharsetEncoder encoder;
+    private CharsetDecoder decoder;
+
+    @Param({"BIG5", "ISO-8859-15", "ASCII", "UTF-16"})
+    private String type;
+
+    @Param("16384")
+    private int size;
+
+    @Setup
+    public void prepare() {
+        BYTES = new byte[size];
+        CHARS = new char[size];
+        for (int i = 0; i < size; ++i) {
+            int val = 48 + (i % 16);
+            BYTES[i] = (byte) val;
+            CHARS[i] = (char) val;
+        }
+
+        encoder = Charset.forName(type).newEncoder();
+        decoder = Charset.forName(type).newDecoder();
+    }
+
+    @Benchmark
+    public ByteBuffer encode() throws CharacterCodingException {
+        CharBuffer charBuffer = CharBuffer.wrap(CHARS);
+        return encoder.encode(charBuffer);
+    }
+
+    @Benchmark
+    public CharBuffer decode() throws CharacterCodingException {
+        ByteBuffer byteBuffer = ByteBuffer.wrap(BYTES);
+        return decoder.decode(byteBuffer);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/security/DoPrivileged.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.security;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring DoPrivileged
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class DoPrivileged {
+
+    private PrivilegedAction<Integer> privilegedAction;
+
+    @Setup
+    public void setup() {
+        privilegedAction = () -> 42;
+    }
+
+    @Benchmark
+    public int test() {
+        return AccessController.doPrivileged(privilegedAction);
+    }
+
+    @Benchmark
+    public int testInline() {
+        return AccessController.doPrivileged((PrivilegedAction<Integer>) () -> 42);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/security/MessageDigests.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.security;
+
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Tests various digester algorithms. Sets Fork parameters as these tests are
+ * rather allocation intensive. Reduced number of forks and iterations as
+ * benchmarks are stable.
+ */
+@State(Scope.Thread)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 10)
+@Fork(jvmArgsAppend = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 5)
+public class MessageDigests {
+
+    @Param({"64", "1024", "16384"})
+    private int length;
+
+    @Param({"md2", "md5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"})
+    private String digesterName;
+
+    @Param({"DEFAULT", "SUN"})
+    protected String provider;
+
+    private byte[] inputBytes;
+    private MessageDigest digester;
+
+    @Setup
+    public void setup() throws NoSuchAlgorithmException, DigestException, NoSuchProviderException {
+        inputBytes = new byte[length];
+        new Random(1234567890).nextBytes(inputBytes);
+        if ("DEFAULT".equals(provider)) {
+            digester = MessageDigest.getInstance(digesterName);
+        } else {
+            digester = MessageDigest.getInstance(digesterName, provider);
+        }
+    }
+
+    @Benchmark
+    public byte[] digest() throws DigestException {
+        return digester.digest(inputBytes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/ArraysEquals.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for Array.equals() with 80 entry arrays differing at beginning, middle, or end.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArraysEquals {
+
+    public char[] testCharArray1 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".toCharArray();
+    public char[] testCharArray2 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789b".toCharArray();
+    public char[] testCharArray3 = "123456789012345678901234567890123456789a123456789012345678901234567890123456789b".toCharArray();
+    public char[] testCharArray4 = "1234567890a2345678901234567890123456789a123456789012345678901234567890123456789b".toCharArray();
+    public char[] testCharArray5 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".toCharArray();
+    public byte[] testByteArray1 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".getBytes();
+    public byte[] testByteArray2 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789b".getBytes();
+    public byte[] testByteArray3 = "123456789012345678901234567890123456789a123456789012345678901234567890123456789b".getBytes();
+    public byte[] testByteArray4 = "1234567890a2345678901234567890123456789a123456789012345678901234567890123456789b".getBytes();
+    public byte[] testByteArray5 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789a".getBytes();
+
+    /** Char array tests */
+
+    @Benchmark
+    public boolean testCharTrue() {
+        return Arrays.equals(testCharArray1, testCharArray5);
+    }
+
+    @Benchmark
+    public boolean testCharFalseEnd() {
+        return Arrays.equals(testCharArray1, testCharArray2);
+    }
+
+    @Benchmark
+    public boolean testCharFalseMid() {
+        return Arrays.equals(testCharArray1, testCharArray3);
+    }
+
+    @Benchmark
+    public boolean testCharFalseBeginning() {
+        return Arrays.equals(testCharArray1, testCharArray4);
+    }
+
+    /** Byte arrays tests */
+    @Benchmark
+    public boolean testByteTrue() {
+        return Arrays.equals(testByteArray1, testByteArray5);
+    }
+
+    @Benchmark
+    public boolean testByteFalseEnd() {
+        return Arrays.equals(testByteArray1, testByteArray2);
+    }
+
+    @Benchmark
+    public boolean testByteFalseMid() {
+        return Arrays.equals(testByteArray1, testByteArray3);
+    }
+
+    @Benchmark
+    public boolean testByteFalseBeginning() {
+        return Arrays.equals(testByteArray1, testByteArray4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/Dates.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Dates {
+
+    int year = 75;
+    int month = 11;
+    int day = 23;
+    int hours = 16;
+    int minutes = 47;
+    int seconds = 12;
+
+    @Benchmark
+    public Date testEmptyConstructor() {
+        return new Date();
+    }
+
+    @SuppressWarnings("deprecation")
+    @Benchmark
+    public Date testIIIIIIConstructor() {
+        hours++;
+        minutes++;
+        seconds++;
+        return new Date(year, month, day, hours, minutes, seconds);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/GregorianCalendars.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class GregorianCalendars {
+
+    private Calendar calendar;
+    private long millis;
+
+    @Setup
+    public void setup() {
+        calendar = new GregorianCalendar();
+        millis = 4711L;
+    }
+
+    @Benchmark
+    public GregorianCalendar testConstructor() {
+        return new GregorianCalendar();
+    }
+
+    @Benchmark
+    public void testUpdate() {
+        calendar.setTimeInMillis(millis);
+        millis += 1L;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/RandomNext.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests java.util.Random's different flavours of next-methods.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class RandomNext {
+
+    public Random rnd;
+
+    @Setup
+    public void setup() {
+        rnd = new Random();
+    }
+
+    @Benchmark
+    public int testNextInt() {
+        return rnd.nextInt();
+    }
+
+    @Benchmark
+    public int testNextInt100() {
+        return rnd.nextInt(100);
+    }
+
+    @Benchmark
+    public int testNextInt128() {
+        return rnd.nextInt(128);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/ZipFind.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Tests ZipFile.getEntry() on the microbenchmarks.jar zip file
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ZipFind {
+
+    // Files that exist in the microbenchmarks.jar zip file
+    public static final String[] existingFiles = {"org/openjdk/bench/java/util/ZipFind.class",
+            "org/openjdk/bench/vm/lang/Throw.class",
+            "org/openjdk/bench/java/nio/ByteBuffers.class"};
+    public static String[] nonExistingFiles = {"/try/to/findme.not", "needle/in/a/HayStack.class"};
+
+    private ZipFile zip;
+
+    @Setup
+    public void prepare() throws IOException, URISyntaxException {
+        String zipFile = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
+        zip = new ZipFile(zipFile);
+
+        // Verify no typos in the filename lists above
+        assert zip.getEntry(ZipFind.nonExistingFiles[0]) == null;
+        assert zip.getEntry(ZipFind.existingFiles[0]) != null;
+        assert zip.getEntry(ZipFind.existingFiles[1]) != null;
+        assert zip.getEntry(ZipFind.existingFiles[2]) != null;
+    }
+
+    @TearDown
+    public void cleanup() throws IOException {
+        zip.close();
+    }
+
+    @Benchmark
+    public ZipEntry testOneNonExisting() throws IOException {
+         return zip.getEntry(ZipFind.nonExistingFiles[0]);
+    }
+
+    @Benchmark
+    public void testTwoNonExisting(Blackhole bh) throws IOException {
+        bh.consume(zip.getEntry(nonExistingFiles[0]));
+        bh.consume(zip.getEntry(nonExistingFiles[1]));
+    }
+
+    @Benchmark
+    public void testNonExistingAndExisting(Blackhole bh) throws IOException {
+        bh.consume(zip.getEntry(nonExistingFiles[0]));
+        bh.consume(zip.getEntry(existingFiles[0]));
+    }
+
+    @Benchmark
+    public ZipEntry testOneExisting() throws IOException {
+        return zip.getEntry(ZipFind.existingFiles[0]);
+    }
+
+    @Benchmark
+    public void testTwoExisting(Blackhole bh) throws IOException {
+        bh.consume(zip.getEntry(existingFiles[0]));
+        bh.consume(zip.getEntry(existingFiles[1]));
+    }
+
+    @Benchmark
+    public void testThreeExisting(Blackhole bh) throws IOException {
+        bh.consume(zip.getEntry(existingFiles[0]));
+        bh.consume(zip.getEntry(existingFiles[1]));
+        bh.consume(zip.getEntry(existingFiles[2]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Atomic.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Atomic {
+
+    public AtomicInteger aInteger;
+    public AtomicLong aLong;
+    public AtomicBoolean aBool;
+
+    public Object testObject1;
+    public Object testObject2;
+    public AtomicReference<Object> aReference;
+
+    /**
+     * The test variables are allocated every iteration so you can assume they are initialized to get similar behaviour
+     * across iterations
+     */
+    @Setup(Level.Iteration)
+    public void setupIteration() {
+        testObject1 = new Object();
+        testObject2 = new Object();
+        aInteger = new AtomicInteger(0);
+        aBool = new AtomicBoolean(false);
+        aReference = new AtomicReference<>(testObject1);
+        aLong = new AtomicLong(0);
+    }
+
+
+    /** Always swap in value. This test should be compiled into a CAS */
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void testAtomicIntegerAlways(Blackhole bh) {
+        bh.consume(aInteger.compareAndSet(0, 2));
+        bh.consume(aInteger.compareAndSet(2, 0));
+    }
+
+    /** Never write a value just return the old one. This test should be compiled into a CAS */
+    @Benchmark
+    public void testAtomicIntegerNever(Blackhole bh) {
+        bh.consume(aInteger.compareAndSet(1, 3));
+    }
+
+    /** Flips an atomic boolean on and off */
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void testAtomicBooleanFlip(Blackhole bh) {
+        bh.consume(aBool.getAndSet(true));
+        bh.consume(aBool.getAndSet(false));
+    }
+
+    /** Writes same value over and over */
+    @Benchmark
+    public void testAtomicBooleanSame(Blackhole bh) {
+        bh.consume(aBool.getAndSet(true));
+    }
+
+    /** Increment and get over multiple threads */
+    @Benchmark
+    public void testAtomicIntegerGetAndIncrement(Blackhole bh) {
+        bh.consume(aInteger.getAndIncrement());
+    }
+
+    /** Increment and get over multiple threads */
+    @Benchmark
+    public void testAtomicLongGetAndIncrement(Blackhole bh) {
+        bh.consume(aLong.getAndIncrement());
+    }
+
+    /** Swap a few references */
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void testAtomicReference(Blackhole bh) {
+        bh.consume(aReference.compareAndSet(testObject1, testObject2));
+        bh.consume(aReference.compareAndSet(testObject2, testObject1));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/AtomicIntegerUpdateAndGet.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * Benchmarks assesses the performance of new Atomic* API.
+ *
+ * Implementation notes:
+ *   - atomic instances are padded to eliminate false sharing
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class AtomicIntegerUpdateAndGet {
+
+    private PaddedAtomicInteger count;
+    private int value = 42;
+    private IntUnaryOperator captureOp;
+    private IntUnaryOperator noCaptureOp;
+
+    @Setup
+    public void setup() {
+        count = new PaddedAtomicInteger();
+        noCaptureOp = new IntUnaryOperator() {
+            public int applyAsInt(int v) {
+                return v + 42;
+            }
+        };
+        captureOp = new IntUnaryOperator() {
+            public int applyAsInt(int v) {
+                return v + value;
+            }
+        };
+    }
+
+    @Benchmark
+    public int testAddAndGet() {
+        return count.addAndGet(42);
+    }
+
+    @Benchmark
+    public int testInnerNoCapture() {
+        return count.updateAndGet(new IntUnaryOperator() {
+            public int applyAsInt(int v) {
+                return v + 42;
+            }
+        });
+    }
+
+    @Benchmark
+    public int testInnerCapture() {
+        return count.updateAndGet(new IntUnaryOperator() {
+            public int applyAsInt(int v) {
+                return v + value;
+            }
+        });
+    }
+
+    @Benchmark
+    public int testInnerCaptureCached() {
+        return count.updateAndGet(captureOp);
+    }
+
+    @Benchmark
+    public int testInnerNoCaptureCached() {
+        return count.updateAndGet(noCaptureOp);
+    }
+
+    @Benchmark
+    public int testLambdaNoCapture() {
+        return count.updateAndGet(x -> x + 42);
+    }
+
+    @Benchmark
+    public int testLambdaCapture() {
+        return count.updateAndGet(x -> x + value);
+    }
+
+    private static class PaddedAtomicInteger extends AtomicInteger {
+        private volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06, pad07;
+        private volatile long pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolForking.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool forking infrastructure.
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolForking {
+
+    /**
+     * Implementation notes:
+     *
+     * This test harnesses forking infrastructure within FJP.
+     * As such, no slack is given for allocating any humble number of tasks: the goal is to fork a lot.
+     * The approximate number of tasks is (SIZE / THRESHOLD).
+     *
+     * Raw baseline gives the idea for compute bound for this benchmark.
+     * FJP could be faster than baseline, because the baseline is single-threaded.
+     */
+
+    @Param("0")
+    private int workers;
+
+    @Param("10000000")
+    private int size;
+
+    @Param("10")
+    private int threshold;
+
+    private Problem problem;
+    private ForkJoinPool fjpSync;
+    private ForkJoinPool fjpAsync;
+
+    @Setup
+    public void setup() {
+        problem = new Problem(size);
+        if (workers == 0) {
+            workers = Runtime.getRuntime().availableProcessors();
+        }
+        fjpSync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false);
+        fjpAsync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
+    }
+
+    @TearDown
+    public void teardown() {
+        fjpSync.shutdownNow();
+        fjpAsync.shutdownNow();
+    }
+
+    @Benchmark
+    public long baselineRaw() {
+        return problem.solve();
+    }
+
+    @Benchmark
+    public Long testExplicit_Sync() throws ExecutionException, InterruptedException {
+        return fjpSync.invoke(new ExplicitTask(problem, 0, problem.size(), threshold));
+    }
+
+    @Benchmark
+    public Long testExplicit_Async() throws ExecutionException, InterruptedException {
+        return fjpAsync.invoke(new ExplicitTask(problem, 0, problem.size(), threshold));
+    }
+
+    @Benchmark
+    public Long testStandard_Sync() throws ExecutionException, InterruptedException {
+        return fjpSync.invoke(new StandardTask(problem, 0, problem.size(), threshold));
+    }
+
+    @Benchmark
+    public Long testStandard_Async() throws ExecutionException, InterruptedException {
+        return fjpAsync.invoke(new StandardTask(problem, 0, problem.size(), threshold));
+    }
+
+    private static class ExplicitTask extends RecursiveTask<Long> {
+        private final Problem problem;
+        private final int l;
+        private final int r;
+        private final int thresh;
+
+        public ExplicitTask(Problem p, int l, int r, int thresh) {
+            this.problem = p;
+            this.l = l;
+            this.r = r;
+            this.thresh = thresh;
+        }
+
+        @Override
+        protected Long compute() {
+            if (r - l <= thresh) {
+                return problem.solve(l, r);
+            }
+
+            int mid = (l + r) >>> 1;
+            ForkJoinTask<Long> t1 = new ExplicitTask(problem, l, mid, thresh);
+            ForkJoinTask<Long> t2 = new ExplicitTask(problem, mid, r, thresh);
+
+            t1.fork();
+            t2.fork();
+
+            long res = 0;
+            res += t2.join();
+            res += t1.join();
+            return res;
+        }
+    }
+
+    private static class StandardTask extends RecursiveTask<Long> {
+        private final Problem problem;
+        private final int l;
+        private final int r;
+        private final int thresh;
+
+        public StandardTask(Problem p, int l, int r, int thresh) {
+            this.problem = p;
+            this.l = l;
+            this.r = r;
+            this.thresh = thresh;
+        }
+
+        @Override
+        protected Long compute() {
+            if (r - l <= thresh) {
+                return problem.solve(l, r);
+            }
+
+            int mid = (l + r) >>> 1;
+            ForkJoinTask<Long> t1 = new StandardTask(problem, l, mid, thresh);
+            ForkJoinTask<Long> t2 = new StandardTask(problem, mid, r, thresh);
+
+            ForkJoinTask.invokeAll(t1, t2);
+            long res = 0;
+            res += t1.join();
+            res += t2.join();
+            return res;
+        }
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolRawCallable.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses general ForkJoinPool performance with simple tasks
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class ForkJoinPoolRawCallable {
+
+    /**
+     * Implementation notes:
+     *
+     * This test submits empty callables.
+     * Callables are submitted in batches, to prevent convoying by driver threads.
+     * One driver thread can saturate up to BATCH_SIZE threads.
+     *
+     * One baseline includes raw throughput, without submissions to executors.
+     * This is not considered as fair comparison, but left around as basic compute baseline.
+     * Executors could not possibly be faster than that.
+     *
+     * Another baseline includes ThreadPoolExecutor.
+     * Note that this baseline is inherently non-scalable with ABQ backing TPE.
+     * The size of ABQ is chosen to accommodate tons of threads, which can also suffer due to cache effects.
+     *
+     * Tasks are reading public volatile field to break opportunistic optimizations in loops.
+     * Tasks are pre-allocated to negate instantiation costs.
+     */
+
+    @Param("0")
+    private int workers;
+
+    @Param("1000")
+    private int batchSize;
+
+    private ThreadPoolExecutor tpe;
+    private ForkJoinPool fjpSync;
+    private ForkJoinPool fjpAsync;
+    private List<SampleTask> tasks;
+
+    public volatile int arg = 42;
+
+    @Setup
+    public void setup() {
+        SampleTask task = new SampleTask();
+
+        tasks = new ArrayList<>();
+        for (int c = 0; c < batchSize; c++) {
+            tasks.add(task);
+        }
+
+        if (workers == 0) {
+            workers = Runtime.getRuntime().availableProcessors();
+        }
+
+        tpe = new ThreadPoolExecutor(workers, workers, 1, TimeUnit.HOURS, new ArrayBlockingQueue<>(batchSize * batchSize));
+        fjpSync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, false);
+        fjpAsync = new ForkJoinPool(workers, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
+    }
+
+    @TearDown
+    public void teardown() {
+        tpe.shutdownNow();
+        fjpSync.shutdownNow();
+        fjpAsync.shutdownNow();
+    }
+
+    @Benchmark
+    public int baseline_raw() throws Exception {
+        int s = 0;
+        for (SampleTask t : tasks) {
+            s += t.call();
+        }
+        return s;
+    }
+
+    @Benchmark
+    public int baseline_TPE() throws Exception {
+        return doWork(tpe);
+    }
+
+    @Benchmark
+    public int testSync() throws ExecutionException, InterruptedException {
+        return doWork(fjpSync);
+    }
+
+    @Benchmark
+    public int testAsync() throws ExecutionException, InterruptedException {
+        return doWork(fjpAsync);
+    }
+
+    public int doWork(ExecutorService service) throws ExecutionException, InterruptedException {
+        List<Future<Integer>> futures = new ArrayList<>(tasks.size());
+        for (SampleTask task : tasks) {
+            futures.add(service.submit(task));
+        }
+
+        int s = 0;
+        for (Future<Integer> future : futures) {
+            s += future.get();
+        }
+        return s;
+    }
+
+    public class SampleTask implements Callable<Integer> {
+        @Override
+        public Integer call() throws Exception {
+            return arg;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoQueued.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool performance with dependence on threshold.
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolThresholdAutoQueued {
+
+    /**
+     * Implementation notes:
+     *
+     * This test solves the problem with threshold = 1, and adaptive heuristics. The optimal level is static,
+     * and lies somewhere in 1..2 interval. Note the test degrades significantly when heuristic starts to fail,
+     * and the throughput is buried under FJP overheads.
+     *
+     * Baseline includes solving problem sequentially. Hence, each test provides the speedup for parallel execution
+     * versus sequential version.
+     */
+
+    @Param("0")
+    private int workers;
+
+    @Param("10000000")
+    private int size;
+
+    @Param({"1", "2", "3", "4", "5", "6", "7", "8"})
+    private int threshold;
+
+    private ForkJoinPool fjp;
+    private Problem problem;
+
+    @Setup
+    public void setup() {
+        if (workers == 0) {
+            workers = Runtime.getRuntime().availableProcessors();
+        }
+
+        problem = new Problem(size);
+        fjp = new ForkJoinPool(workers);
+    }
+
+    @TearDown
+    public void teardown() {
+        fjp.shutdownNow();
+    }
+
+    @Benchmark
+    public long baselineRaw() {
+        return problem.solve();
+    }
+
+    @Benchmark
+    public Long test() throws ExecutionException, InterruptedException {
+        return fjp.invoke(new AutoQueuedTask(threshold, problem, 0, problem.size()));
+    }
+
+    private static class AutoQueuedTask extends RecursiveTask<Long> {
+        private final int thr;
+        private final Problem problem;
+        private final int l;
+        private final int r;
+
+        public AutoQueuedTask(int thr, Problem p, int l, int r) {
+            this.thr = thr;
+            this.problem = p;
+            this.l = l;
+            this.r = r;
+        }
+
+        @Override
+        protected Long compute() {
+            if (r - l <= 1 || getQueuedTaskCount() >= thr) {
+                return problem.solve(l, r);
+            }
+
+            int mid = (l + r) >>> 1;
+            ForkJoinTask<Long> t1 = new AutoQueuedTask(thr, problem, l, mid);
+            ForkJoinTask<Long> t2 = new AutoQueuedTask(thr, problem, mid, r);
+
+            t2.fork();
+
+            long res = 0;
+            res += t1.invoke();
+            res += t2.join();
+            return res;
+        }
+    }
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdAutoSurplus.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool performance with dependence on threshold.
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolThresholdAutoSurplus {
+
+    /**
+     * Implementation notes:
+     *
+     * This test solves the problem with threshold = 1, and adaptive heuristics. The optimal level is static,
+     * and lies somewhere in 1..2 interval. Note the test degrades significantly when heuristic starts to fail,
+     * and the throughput is buried under FJP overheads.
+     *
+     * Baseline includes solving problem sequentially. Hence, each test provides the speedup for parallel execution
+     * versus sequential version.
+     */
+
+    @Param("0")
+    private int workers;
+
+    @Param("10000000")
+    private int size;
+
+    @Param({"1", "2", "3", "4", "5", "6", "7", "8"})
+    private int threshold;
+
+    private ForkJoinPool fjp;
+    private Problem problem;
+
+    @Setup
+    public void setup() {
+        if (workers == 0) {
+            workers = Runtime.getRuntime().availableProcessors();
+        }
+
+        problem = new Problem(size);
+        fjp = new ForkJoinPool(workers);
+    }
+
+    @TearDown
+    public void teardown() {
+        fjp.shutdownNow();
+    }
+
+    @Benchmark
+    public long baselineRaw() {
+        return problem.solve();
+    }
+
+    @Benchmark
+    public Long test() throws ExecutionException, InterruptedException {
+        return fjp.invoke(new AutoQueuedTask(threshold, problem, 0, problem.size()));
+    }
+
+    private static class AutoQueuedTask extends RecursiveTask<Long> {
+        private final int thr;
+        private final Problem problem;
+        private final int l;
+        private final int r;
+
+        public AutoQueuedTask(int thr, Problem p, int l, int r) {
+            this.thr = thr;
+            this.problem = p;
+            this.l = l;
+            this.r = r;
+        }
+
+        @Override
+        protected Long compute() {
+            if (r - l <= 1 || getSurplusQueuedTaskCount() >= thr) {
+                return problem.solve(l, r);
+            }
+
+            int mid = (l + r) >>> 1;
+            ForkJoinTask<Long> t1 = new AutoQueuedTask(thr, problem, l, mid);
+            ForkJoinTask<Long> t2 = new AutoQueuedTask(thr, problem, mid, r);
+
+            t2.fork();
+
+            long res = 0;
+            res += t1.invoke();
+            res += t2.join();
+            return res;
+        }
+    }
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ForkJoinPoolThresholdStatic.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark assesses ForkJoinPool performance with dependence on threshold.
+ */
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class ForkJoinPoolThresholdStatic {
+
+    /**
+     * Implementation notes:
+     *
+     * This test solves the problem on different threshold levels.
+     * The optimal level depends on available parallelism.
+     * Lower thresholds will suffer because of ForkJoinPool infrastructure overheads.
+     * Higher thresholds will suffer because of lower available task parallelism.
+     *
+     * Baseline includes solving problem sequentially.
+     * Hence, each test provides the speedup for parallel execution
+     * versus sequential version.
+     */
+
+    @Param("0")
+    private int workers;
+
+    @Param("10000000")
+    private int size;
+
+    @Param({"1", "5", "10", "50", "100", "500", "1000", "5000", "10000", "50000", "100000", "500000", "1000000", "5000000", "10000000"})
+    private int threshold;
+
+    private ForkJoinPool fjp;
+    private Problem problem;
+
+    @Setup
+    public void setup() {
+        if (workers == 0) {
+            workers = Runtime.getRuntime().availableProcessors();
+        }
+
+        problem = new Problem(size);
+        fjp = new ForkJoinPool(workers);
+    }
+
+    @TearDown
+    public void teardown() {
+        fjp.shutdownNow();
+    }
+
+    @Benchmark
+    public long baselineRaw() {
+        return problem.solve();
+    }
+
+    @Benchmark
+    public Long test() throws ExecutionException, InterruptedException {
+        return fjp.invoke(new AdjustableThreshTask(threshold, problem, 0, problem.size()));
+    }
+
+    private static class AdjustableThreshTask extends RecursiveTask<Long> {
+        private final int thr;
+        private final Problem problem;
+        private final int l;
+        private final int r;
+
+        public AdjustableThreshTask(int thr, Problem p, int l, int r) {
+            this.thr = thr;
+            this.problem = p;
+            this.l = l;
+            this.r = r;
+        }
+
+        @Override
+        protected Long compute() {
+            if (r - l <= thr) {
+                return problem.solve(l, r);
+            }
+
+            int mid = (l + r) >>> 1;
+            ForkJoinTask<Long> t1 = new AdjustableThreshTask(thr, problem, l, mid);
+            ForkJoinTask<Long> t2 = new AdjustableThreshTask(thr, problem, mid, r);
+
+            ForkJoinTask.invokeAll(t1, t2);
+
+            long res = 0;
+            res += t1.join();
+            res += t2.join();
+            return res;
+        }
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Locks.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Locks {
+
+    private ReentrantLock reentrantLock;
+    private ReentrantLock fairReentrantLock;
+    private ReentrantReadWriteLock reentrantRWLock;
+    private ReentrantReadWriteLock fairReentrantRWLock;
+    private Semaphore semaphore;
+    private Semaphore fairSemaphore;
+    private Lock reentrantWriteLock;
+    private Mutex mutex;
+
+    @Setup
+    public void setup() {
+        reentrantLock = new ReentrantLock(false);
+        fairReentrantLock = new ReentrantLock(true);
+        reentrantRWLock = new ReentrantReadWriteLock(false);
+        fairReentrantRWLock = new ReentrantReadWriteLock(true);
+        semaphore = new Semaphore(1, false);
+        fairSemaphore = new Semaphore(1, true);
+        reentrantWriteLock = new ReentrantReadWriteLock(false).writeLock();
+        mutex = new Mutex();
+    }
+
+    @Benchmark
+    public void testSynchronizedBlock() {
+        synchronized (this) {
+            Blackhole.consumeCPU(10);
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testFairReentrantLock() {
+        fairReentrantLock.lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            fairReentrantLock.unlock();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testReentrantLock() {
+        reentrantLock.lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            reentrantLock.unlock();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testFairReentrantReadWriteLock() {
+        fairReentrantRWLock.readLock().lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            fairReentrantRWLock.readLock().unlock();
+        }
+        fairReentrantRWLock.writeLock().lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            fairReentrantRWLock.writeLock().unlock();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testReentrantReadWriteLock() {
+        reentrantRWLock.readLock().lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            reentrantRWLock.readLock().unlock();
+        }
+        reentrantRWLock.writeLock().lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            reentrantRWLock.writeLock().unlock();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testReentrantWriteLock() {
+        reentrantWriteLock.lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            reentrantWriteLock.unlock();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testFairSemaphore() throws InterruptedException {
+        fairSemaphore.acquire();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            fairSemaphore.release();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testSemaphore() throws InterruptedException {
+        semaphore.acquire();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            semaphore.release();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @Benchmark
+    public void testAbstractQueueSynchronizer() {
+        mutex.lock();
+        try {
+            Blackhole.consumeCPU(10);
+        } finally {
+            mutex.unlock();
+        }
+        Blackhole.consumeCPU(5);
+    }
+
+    @SuppressWarnings("serial")
+    private final class Mutex extends AbstractQueuedSynchronizer implements Lock, java.io.Serializable {
+
+        @Override
+        public boolean isHeldExclusively() {
+            return getState() == 1;
+        }
+
+        @Override
+        public boolean tryAcquire(int acquires) {
+            return compareAndSetState(0, 1);
+        }
+
+        @Override
+        public boolean tryRelease(int releases) {
+            setState(0);
+            return true;
+        }
+
+        @Override
+        public Condition newCondition() {
+            return new ConditionObject();
+        }
+
+        private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+            s.defaultReadObject();
+            setState(0); // reset to unlocked state
+        }
+
+        @Override
+        public void lock() {
+            acquire(1);
+        }
+
+        @Override
+        public boolean tryLock() {
+            return tryAcquire(1);
+        }
+
+        @Override
+        public void lockInterruptibly() throws InterruptedException {
+            acquireInterruptibly(1);
+        }
+
+        @Override
+        public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+            return tryAcquireNanos(1, unit.toNanos(timeout));
+        }
+
+        @Override
+        public void unlock() {
+            release(1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Maps {
+    private SimpleRandom rng;
+    private Map<Integer, Integer> map;
+    private Integer[] key;
+
+    private int removesPerMaxRandom;
+    private int insertsPerMaxRandom;
+    private int total;
+    private int position;
+
+    @Setup
+    public void initTest() {
+        int nkeys = 10000;
+        int pRemove = 10;
+        int pInsert = 90;
+        removesPerMaxRandom = (int) ((pRemove / 100.0 * 0x7FFFFFFFL));
+        insertsPerMaxRandom = (int) ((pInsert / 100.0 * 0x7FFFFFFFL));
+
+        rng = new SimpleRandom();
+        map = new ConcurrentHashMap<>();
+        total = 0;
+        key = new Integer[nkeys];
+        for (int i = 0; i < key.length; ++i) {
+            key[i] = new Integer(rng.next());
+        }
+        position = key.length / 2;
+    }
+
+    @Benchmark
+    @Threads(4)
+    public void testConcurrentHashMap() {
+        int pos = position;
+        // random-walk around key positions, bunching accesses
+        int r = rng.next();
+        pos += (r & 7) - 3;
+        while (pos >= key.length) {
+            pos -= key.length;
+        }
+        while (pos < 0) {
+            pos += key.length;
+        }
+        Integer k = key[pos];
+        Integer x = map.get(k);
+        if (x != null) {
+            if (x.intValue() != k.intValue()) {
+                throw new Error("bad mapping: " + x + " to " + k);
+            }
+
+            if (r < removesPerMaxRandom) {
+                if (map.remove(k) != null) {
+                    pos = total % key.length; // move from position
+                }
+            }
+        } else if (r < insertsPerMaxRandom) {
+            ++pos;
+            map.put(k, k);
+        }
+        total += r;
+        position = pos;
+    }
+
+    private static class SimpleRandom {
+        private final static long multiplier = 0x5DEECE66DL;
+        private final static long addend = 0xBL;
+        private final static long mask = (1L << 48) - 1;
+        private final static AtomicLong seq = new AtomicLong(1);
+        private long seed = System.nanoTime() + seq.getAndIncrement();
+
+        public int next() {
+            long nextSeed = (seed * multiplier + addend) & mask;
+            seed = nextSeed;
+            return ((int) (nextSeed >>> 17)) & 0x7FFFFFFF;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Problem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+
+/**
+ * Generic problem for concurrency tests.
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+public class Problem {
+
+    /*
+     * Implementation notes:
+     *
+     * This problem makes its bidding to confuse loop unrolling and CSE, and as such break loop optimizations.
+     * Should loop optimizations be allowed, the performance with different (l, r) could change non-linearly.
+     */
+
+    private final int[] data;
+    private final int size;
+
+    public Problem(int size) {
+        this.size = size;
+        data = new int[size];
+    }
+
+    public long solve() {
+        return solve(0, size);
+    }
+
+    public long solve(int l, int r) {
+        long sum = 0;
+        for (int c = l; c < r; c++) {
+            int v = hash(data[c]);
+            if (filter(v)) {
+                sum += v;
+            }
+        }
+        return sum;
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public static int hash(int x) {
+        x ^= (x << 21);
+        x ^= (x >>> 31);
+        x ^= (x << 4);
+        return x;
+    }
+
+    public static boolean filter(int i) {
+        return ((i & 0b101) == 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ProducerConsumer.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests the different blocking queues in the java.util.concurrent package.
+ * The tests are done with a single producer and a variable number of consumers.
+ * The tests are created from Doug Lea's concurrent test suite.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class ProducerConsumer {
+
+    @Param("100")
+    private int capacity;
+
+    @Param
+    private QueueType type;
+
+    private BlockingQueue<Integer> q;
+    private Producer prod;
+
+    @Setup
+    public void prepare() {
+        switch (type) {
+            case ABQ_F:
+                q = new ArrayBlockingQueue<>(capacity, true);
+                break;
+            case ABQ_NF:
+                q = new ArrayBlockingQueue<>(capacity, false);
+                break;
+            case LBQ:
+                q = new LinkedBlockingQueue<>(capacity);
+                break;
+            case PBQ:
+                q = new PriorityBlockingQueue<>(capacity);
+                break;
+            default:
+                throw new RuntimeException();
+        }
+
+        prod = new Producer(q);
+        prod.start();
+    }
+
+    @TearDown
+    public void teardown() {
+        prod.halt();
+    }
+
+    @Benchmark
+    public void test() {
+        try {
+            int last = -1;
+            int v = q.take();
+            if (v < last) {
+                throw new Error("Out-of-Order transfer");
+            }
+            Blackhole.consumeCPU(10);
+        } catch (Exception ie) {
+        }
+    }
+
+    public enum QueueType {
+        LBQ,
+        ABQ_NF,
+        ABQ_F,
+        PBQ,
+    }
+
+    private class Producer extends Thread {
+        private final BlockingQueue<Integer> queue;
+        private int i = 0;
+        private volatile boolean running;
+
+        public Producer(BlockingQueue<Integer> queue) {
+            this.queue = queue;
+        }
+
+        @Override
+        public void run() {
+            running = true;
+            try {
+                while (running) {
+                    queue.put(i++);
+                }
+            } catch (Exception ie) {
+            }
+        }
+
+        public void halt() {
+            running = false;
+            this.interrupt();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Queues.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class Queues {
+
+    @Param("100")
+    private int capacity;
+
+    @Param
+    private QueueType type;
+
+    public enum QueueType {
+        LBQ,
+        ABQ_NF,
+        ABQ_F,
+        PBQ,
+    }
+
+    private BlockingQueue<Integer> q;
+
+    @Setup
+    public void setup() {
+        switch (type) {
+            case ABQ_F:
+                q = new ArrayBlockingQueue<>(capacity, true);
+                break;
+            case ABQ_NF:
+                q = new ArrayBlockingQueue<>(capacity, false);
+                break;
+            case LBQ:
+                q = new LinkedBlockingQueue<>(capacity);
+                break;
+            case PBQ:
+                q = new PriorityBlockingQueue<>(capacity);
+                break;
+            default:
+                throw new RuntimeException();
+        }
+    }
+
+    @Benchmark
+    public void test() {
+        try {
+            int l = (int) System.nanoTime();
+            Integer item = q.poll();
+            if (item != null) {
+                Blackhole.consumeCPU(5);
+            } else {
+                Blackhole.consumeCPU(10);
+                while (!q.offer(l)) {
+                    Blackhole.consumeCPU(5);
+                }
+            }
+        } catch (Exception ie) {
+            throw new Error("iteration failed");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/ThreadLocalRandomNextInt.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.concurrent;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ThreadLocalRandomNextInt {
+
+    @State(Scope.Benchmark)
+    public static class Global {
+        public ThreadLocal<Random> tlr;
+        private List<ThreadLocal<Integer>> contaminators; // reachable, non-garbage-collectable
+
+        @Setup(Level.Trial)
+        public void setup() {
+            tlr = new ThreadLocal<Random>() {
+                @Override
+                protected Random initialValue() {
+                    return java.util.concurrent.ThreadLocalRandom.current();
+                }
+            };
+
+            // contaminate ThreadLocals
+            int contaminatorCount = Integer.getInteger("contaminators", 0);
+            contaminators = new ArrayList<>(contaminatorCount);
+            for (int i = 0; i < contaminatorCount; i++) {
+                final int finalI = i;
+                ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
+                    @Override
+                    protected Integer initialValue() {
+                        return finalI;
+                    }
+                };
+                contaminators.add(tl);
+                tl.get();
+            }
+        }
+    }
+
+    @State(Scope.Thread)
+    public static class Local {
+        public java.util.concurrent.ThreadLocalRandom tlr;
+
+        @Setup(Level.Trial)
+        public void setup() {
+            tlr = java.util.concurrent.ThreadLocalRandom.current();
+        }
+    }
+
+    @Benchmark
+    public int baseline(Local l) {
+        return l.tlr.nextInt();
+    }
+
+    @Benchmark
+    public int testJUC() {
+        return java.util.concurrent.ThreadLocalRandom.current().nextInt();
+    }
+
+    @Benchmark
+    public int testLang(Global g) {
+        return g.tlr.get().nextInt();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/logging/LogRecord.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.logging;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class LogRecord {
+    private Logger logger;
+
+    @Setup
+    public void setup(final Blackhole bh) {
+        try {
+            logger = Logger.getLogger("logger");
+            logger.addHandler(new Handler() {
+                @Override
+                public void publish(java.util.logging.LogRecord record) {
+                    bh.consume(record);
+                }
+
+                @Override
+                public void flush() {
+                    // do nothing
+                }
+
+                @Override
+                public void close() throws SecurityException {
+                    // do nothing
+                }
+            });
+            logger.setLevel(Level.FINE);
+            logger.setUseParentHandlers(false);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Benchmark
+    public void testFine() {
+       logger.log(Level.FINE, "test message");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/AllMatcher.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different "allMatch" schemes.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatcher {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - all operations have similar semantics
+     *   - these use the qualifier duality: all(P(x)) === !(exists(!P(x))
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongPredicate op;
+
+    @Setup
+    public void setup() {
+        op = new LongPredicate() {
+            @Override
+            public boolean test(long x) {
+                return true;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_anyMatch() {
+        return LongStream.range(0, size).allMatch(op);
+    }
+
+    @Benchmark
+    public boolean seq_filter_findFirst() {
+        return !(LongStream.range(0, size).filter(op.negate()).findFirst().isPresent());
+    }
+
+    @Benchmark
+    public boolean seq_filter_findAny() {
+        return !(LongStream.range(0, size).filter(op.negate()).findAny().isPresent());
+    }
+
+    @Benchmark
+    public boolean par_anyMatch() {
+        return LongStream.range(0, size).parallel().allMatch(op);
+    }
+
+    @Benchmark
+    public boolean par_filter_findFirst() {
+        return !(LongStream.range(0, size).parallel().filter(op.negate()).findFirst().isPresent());
+    }
+
+    @Benchmark
+    public boolean par_filter_findAny() {
+        return !(LongStream.range(0, size).parallel().filter(op.negate()).findAny().isPresent());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/AnyMatcher.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different "anyMatch" schemes.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatcher {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - all operations have similar semantics
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongPredicate op;
+
+    @Setup
+    public void setup() {
+        op = new LongPredicate() {
+            @Override
+            public boolean test(long x) {
+                return false;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_anyMatch() {
+        return LongStream.range(0, size).anyMatch(op);
+    }
+
+    @Benchmark
+    public boolean seq_filter_findFirst() {
+        return LongStream.range(0, size).filter(op).findFirst().isPresent();
+    }
+
+    @Benchmark
+    public boolean seq_filter_findAny() {
+        return LongStream.range(0, size).filter(op).findAny().isPresent();
+    }
+
+    @Benchmark
+    public boolean par_anyMatch() {
+        return LongStream.range(0, size).parallel().anyMatch(op);
+    }
+
+    @Benchmark
+    public boolean par_filter_findFirst() {
+        return LongStream.range(0, size).parallel().filter(op).findFirst().isPresent();
+    }
+
+    @Benchmark
+    public boolean par_filter_findAny() {
+        return LongStream.range(0, size).parallel().filter(op).findAny().isPresent();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/Decomposition.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark is the golden benchmark for decompositions.
+ * There are at least four parameters to juggle:
+ *   - pool parallelism (P), controlled via -Djava.util.concurrent.ForkJoinUtils.pool.parallelism
+ *   - problem size (N), controlled as benchmark param
+ *   - operation cost (Q), controlled as benchmark param
+ *   - number of clients (C), controlled via -t option in harness
+ *
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Thread)
+public class Decomposition {
+
+    @Param("1000")
+    private int N;
+
+    @Param("1000")
+    private int Q;
+
+    @State(Scope.Thread)
+    public static class Thinktime {
+        @Param("10")
+        private int S;
+
+        @Setup(Level.Invocation)
+        public void sleep() throws InterruptedException {
+            TimeUnit.MILLISECONDS.sleep(S);
+        }
+    }
+
+    @Benchmark
+    public long saturated_sequential() throws InterruptedException {
+        return LongStream.range(1, N).filter(k -> doWork(k, Q)).sum();
+    }
+
+    @Benchmark
+    public long thinktime_sequential(Thinktime t) throws InterruptedException {
+        return LongStream.range(1, N).filter(k -> doWork(k, Q)).sum();
+    }
+
+    @Benchmark
+    public long saturated_parallel() throws InterruptedException {
+        return LongStream.range(1, N).parallel().filter(k -> doWork(k, Q)).sum();
+    }
+
+    @Benchmark
+    public long thinktime_parallel(Thinktime t) throws InterruptedException {
+        return LongStream.range(1, N).parallel().filter(k -> doWork(k, Q)).sum();
+    }
+
+    /**
+     * Make some work.
+     * This method have a couple of distinguishable properties:
+     *   - the run time is linear with Q
+     *   - the computation is dependent on input, preventing common reductions
+     *   - the returned result is dependent on loop result, preventing dead code elimination
+     *   - the returned result is almost always false
+     *
+     * This code uses inlined version of ThreadLocalRandom.next() to mitigate the edge effects
+     * of acquiring TLR every single call.
+     *
+     * @param input input
+     * @return result
+     */
+    public static boolean doWork(long input, long count) {
+        long t = input;
+        for (int i = 0; i < count; i++) {
+            t += (t * 0x5DEECE66DL + 0xBL) & (0xFFFFFFFFFFFFL);
+        }
+        return (t == 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/NoneMatcher.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different "noneMatch" schemes.
+ *
+ * @author Aleksey Shipilev, aleksey.shipilev@oracle.com
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatcher {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - all operations have similar semantics
+     *   - these use the qualifier duality:
+     *         exists(P(x)) === !all(!P(x)) =>
+     *         !exists(P(x)) === all(!P(x))
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongPredicate op;
+
+    @Setup
+    public void setup() {
+        op = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_anyMatch() {
+        return LongStream.range(0, size).noneMatch(op);
+    }
+
+    @Benchmark
+    public boolean par_anyMatch() {
+        return LongStream.range(0, size).parallel().noneMatch(op);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/Reducers.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongBinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for checking different reduce schemes.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Reducers {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongBinaryOperator op;
+
+    @Setup
+    public void setup() {
+        op = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_reduce() {
+        return LongStream.range(0, size).reduce(op).getAsLong();
+    }
+
+    @Benchmark
+    public long par_reduce() {
+        return LongStream.range(0, size).parallel().reduce(op).getAsLong();
+    }
+
+    @Benchmark
+    public long seq_reduce_base() {
+        return LongStream.range(0, size).reduce(0L, op);
+    }
+
+    @Benchmark
+    public long par_reduce_base() {
+        return LongStream.range(0, size).parallel().reduce(0L, op);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/LongAccumulator.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops;
+
+public class LongAccumulator {
+
+    long acc;
+
+    public LongAccumulator() {
+        acc = 0;
+    }
+
+    public void add(long v) {
+        acc += v;
+    }
+
+    public void merge(LongAccumulator other) {
+        acc += other.acc;
+    }
+
+    public long get() {
+        return acc;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AllMatch.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatch {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the predicates are always true to avert shortcurcuiting
+     */
+
+    @Param("100000")
+    private int size;
+
+    private Predicate<Long> p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return true;
+            }
+        };
+        p2 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return true;
+            }
+        };
+        p3 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return true;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_invoke() {
+        return LongStream.range(0, size).boxed().allMatch(p1);
+    }
+
+    @Benchmark
+    public int seq_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int seq_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).boxed().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().allMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().allMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public boolean par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().allMatch(p1);
+    }
+
+    @Benchmark
+    public int par_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int par_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().boxed().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().allMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().allMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AllMatchShort.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatchShort {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - test the predicate which will become false closer to start, in the middle, and closer to the end
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Param("100")
+    private int offset;
+
+    private Predicate<Long> pMid, pStart, pEnd;
+
+    @Setup
+    public void setup() {
+        pStart = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v < offset;
+            }
+        };
+        pMid = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v < size / 2;
+            }
+        };
+        pEnd = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v < size - offset;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_start() {
+        return LongStream.range(0, size).boxed().allMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean seq_mid() {
+        return LongStream.range(0, size).boxed().allMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean seq_end() {
+        return LongStream.range(0, size).boxed().allMatch(pEnd);
+    }
+
+    @Benchmark
+    public boolean par_start() {
+        return LongStream.range(0, size).parallel().boxed().allMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean par_mid() {
+        return LongStream.range(0, size).parallel().boxed().allMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean par_end() {
+        return LongStream.range(0, size).parallel().boxed().allMatch(pEnd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AnyMatch.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatch {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the predicates are always false to avert shortcurcuiting
+     */
+
+    @Param("100000")
+    private int size;
+
+    private Predicate<Long> p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return false;
+            }
+        };
+        p2 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return false;
+            }
+        };
+        p3 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return false;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_invoke() {
+        return LongStream.range(0, size).boxed().anyMatch(p1);
+    }
+
+    @Benchmark
+    public int seq_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int seq_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).boxed().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().anyMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().anyMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public boolean par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().anyMatch(p1);
+    }
+
+    @Benchmark
+    public int par_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int par_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().boxed().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().anyMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().anyMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/AnyMatchShort.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatchShort {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - test the predicate which will become true closer to start, in the middle, and closer to the end
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Param("100")
+    private int offset;
+
+    private Predicate<Long> pMid, pStart, pEnd;
+
+    @Setup
+    public void setup() {
+        pStart = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v > offset;
+            }
+        };
+        pMid = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v > size / 2;
+            }
+        };
+        pEnd = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v > size - offset;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_start() {
+        return LongStream.range(0, size).boxed().anyMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean seq_mid() {
+        return LongStream.range(0, size).boxed().anyMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean seq_end() {
+        return LongStream.range(0, size).boxed().anyMatch(pEnd);
+    }
+
+    @Benchmark
+    public boolean par_start() {
+        return LongStream.range(0, size).parallel().boxed().anyMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean par_mid() {
+        return LongStream.range(0, size).parallel().boxed().anyMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean par_end() {
+        return LongStream.range(0, size).parallel().boxed().anyMatch(pEnd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Filter.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for filter() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Filter {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive predicates is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    private Predicate<Long> p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long l) {
+                return (l & 0b11111111) == 0;
+            }
+        };
+        p2 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long l) {
+                return (l & 0b00001111) == 0;
+            }
+        };
+        p3 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long l) {
+                return (l & 0x00000011) == 0;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .boxed()
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        return LongStream.range(0, size)
+                .boxed()
+                .filter(p1)
+                .filter(p1)
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .filter(p1)
+                .filter(p1)
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        return LongStream.range(0, size)
+                .boxed()
+                .filter(p1)
+                .filter(p2)
+                .filter(p3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .filter(p1)
+                .filter(p2)
+                .filter(p3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/FindAny.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findAny() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindAny {
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public Long seq_invoke() {
+        return LongStream.range(0, size).boxed().findAny().get();
+    }
+
+    @Benchmark
+    public Long par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().findAny().get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/FindFirst.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findFirst() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindFirst {
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public Long seq_invoke() {
+        return LongStream.range(0, size).boxed().findFirst().get();
+    }
+
+    @Benchmark
+    public Long par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().findFirst().get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/ForEach.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.Consumer;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for forEach() operations.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ForEach {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongAdder sink;
+    private Consumer<Long> b1, b2, b3;
+
+    @Setup
+    public void setup() {
+        sink = new LongAdder();
+        b1 = new Consumer<Long>() {
+            @Override
+            public void accept(Long v) {
+                sink.add(v);
+            }
+        };
+        b2 = new Consumer<Long>() {
+            @Override
+            public void accept(Long v) {
+                sink.add(v);
+            }
+        };
+        b3 = new Consumer<Long>() {
+            @Override
+            public void accept(Long v) {
+                sink.add(v);
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        LongStream.range(0, size).boxed().forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_chain111() {
+        LongStream.range(0, size).boxed().forEach(b1);
+        LongStream.range(0, size).boxed().forEach(b1);
+        LongStream.range(0, size).boxed().forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_chain123() {
+        LongStream.range(0, size).boxed().forEach(b1);
+        LongStream.range(0, size).boxed().forEach(b2);
+        LongStream.range(0, size).boxed().forEach(b3);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        LongStream.range(0, size).parallel().boxed().forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_chain111() {
+        LongStream.range(0, size).parallel().boxed().forEach(b1);
+        LongStream.range(0, size).parallel().boxed().forEach(b1);
+        LongStream.range(0, size).parallel().boxed().forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_chain123() {
+        LongStream.range(0, size).parallel().boxed().forEach(b1);
+        LongStream.range(0, size).parallel().boxed().forEach(b2);
+        LongStream.range(0, size).parallel().boxed().forEach(b3);
+        return sink.sum();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Limit.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for limit() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Limit {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the tests include:
+     *          - return nothing
+     *          - return just a single element
+     *          - return half
+     *          - return all but last element
+     *          - return all
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_baseline() {
+        return LongStream.range(0, size)
+                .boxed()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limit0() {
+        return LongStream.range(0, size)
+                .boxed()
+                .limit(0)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limit1() {
+        return LongStream.range(0, size)
+                .boxed()
+                .limit(1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limitHalf() {
+        return LongStream.range(0, size)
+                .boxed()
+                .limit(size / 2)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limitFull() {
+        return LongStream.range(0, size)
+                .boxed()
+                .limit(size - 1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limitFullest() {
+        return LongStream.range(0, size)
+                .boxed()
+                .limit(size)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_baseline() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limit0() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .limit(0)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limit1() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .limit(1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limitHalf() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .limit(size / 2)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limitFull() {
+        return LongStream.range(0, size).parallel()
+                .boxed().limit(size - 1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limitFullest() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .limit(size)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Map.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for map() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Map {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    private Function<Long, Long> m1, m2, m3;
+
+    @Setup
+    public void setup() {
+        m1 = new Function<Long, Long>() {
+            @Override
+            public Long apply(Long l) {
+                return l * 2;
+            }
+        };
+        m2 = new Function<Long, Long>() {
+            @Override
+            public Long apply(Long l) {
+                return l * 2;
+            }
+        };
+        m3 = new Function<Long, Long>() {
+            @Override
+            public Long apply(Long l) {
+                return l * 2;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .boxed()
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        return LongStream.range(0, size)
+                .boxed()
+                .map(m1)
+                .map(m1)
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .map(m1)
+                .map(m1)
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        return LongStream.range(0, size)
+                .boxed()
+                .map(m1)
+                .map(m2)
+                .map(m3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .map(m1)
+                .map(m2)
+                .map(m3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/NoneMatch.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatch {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the predicates are always false to avert shortcurcuiting
+     */
+
+    @Param("100000")
+    private int size;
+
+    private Predicate<Long> p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return false;
+            }
+        };
+        p2 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return false;
+            }
+        };
+        p3 = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return false;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_invoke() {
+        return LongStream.range(0, size).boxed().noneMatch(p1);
+    }
+
+    @Benchmark
+    public int seq_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int seq_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).boxed().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().noneMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).boxed().noneMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public boolean par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().noneMatch(p1);
+    }
+
+    @Benchmark
+    public int par_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int par_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().boxed().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().noneMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().boxed().noneMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/NoneMatchShort.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatchShort {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - test the predicate which will become true closer to start, in the middle, and closer to the end
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Param("100")
+    private int offset;
+
+    private Predicate<Long> pMid, pStart, pEnd;
+
+    @Setup
+    public void setup() {
+        pStart = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v > offset;
+            }
+        };
+        pMid = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v > size / 2;
+            }
+        };
+        pEnd = new Predicate<Long>() {
+            @Override
+            public boolean test(Long v) {
+                return v > size - offset;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_start() {
+        return LongStream.range(0, size).boxed().noneMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean seq_mid() {
+        return LongStream.range(0, size).boxed().noneMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean seq_end() {
+        return LongStream.range(0, size).boxed().noneMatch(pEnd);
+    }
+
+    @Benchmark
+    public boolean par_start() {
+        return LongStream.range(0, size).parallel().boxed().noneMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean par_mid() {
+        return LongStream.range(0, size).parallel().boxed().noneMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean par_end() {
+        return LongStream.range(0, size).parallel().boxed().noneMatch(pEnd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Reduce.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Reduce {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     */
+
+    @Param("100000")
+    private int size;
+
+    private BinaryOperator<Long> op1, op2, op3;
+
+    @Setup
+    public void setup() {
+        op1 = new BinaryOperator<Long>() {
+            @Override
+            public Long apply(Long l, Long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op2 = new BinaryOperator<Long>() {
+            @Override
+            public Long apply(Long l, Long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op3 = new BinaryOperator<Long>() {
+            @Override
+            public Long apply(Long l, Long r) {
+                return (l > r) ? l : r;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size).boxed().reduce(op1).get();
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).boxed().reduce(op1).get();
+        l += LongStream.range(0, size).boxed().reduce(op1).get();
+        l += LongStream.range(0, size).boxed().reduce(op1).get();
+        return l;
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).boxed().reduce(op1).get();
+        l += LongStream.range(0, size).boxed().reduce(op2).get();
+        l += LongStream.range(0, size).boxed().reduce(op3).get();
+        return l;
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+        l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+        l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+        return l;
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().boxed().reduce(op1).get();
+        l += LongStream.range(0, size).parallel().boxed().reduce(op2).get();
+        l += LongStream.range(0, size).parallel().boxed().reduce(op3).get();
+        return l;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/ReduceBase.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce()-base operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ReduceBase {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    private BinaryOperator<Long> op1, op2, op3;
+
+    @Setup
+    public void setup() {
+        op1 = new BinaryOperator<Long>() {
+            @Override
+            public Long apply(Long l, Long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op2 = new BinaryOperator<Long>() {
+            @Override
+            public Long apply(Long l, Long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op3 = new BinaryOperator<Long>() {
+            @Override
+            public Long apply(Long l, Long r) {
+                return (l > r) ? l : r;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size).boxed().reduce(0L, op1);
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).boxed().reduce(0L, op1);
+        l += LongStream.range(0, size).boxed().reduce(0L, op1);
+        l += LongStream.range(0, size).boxed().reduce(0L, op1);
+        return l;
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).boxed().reduce(0L, op1);
+        l += LongStream.range(0, size).boxed().reduce(0L, op2);
+        l += LongStream.range(0, size).boxed().reduce(0L, op3);
+        return l;
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+        l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+        l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+        return l;
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().boxed().reduce(0L, op1);
+        l += LongStream.range(0, size).parallel().boxed().reduce(0L, op2);
+        l += LongStream.range(0, size).parallel().boxed().reduce(0L, op3);
+        return l;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/Sorted.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Comparator;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for sorted() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Sorted {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - consecutive sorts should reuse the knowledge that stream was sorted already
+     */
+
+    @Param("100000")
+    private int size;
+
+    private Comparator<Long> cmp;
+
+    @Setup
+    public void setup() {
+        cmp = new Comparator<Long>() {
+            @Override
+            public int compare(Long x, Long y) {
+                return (x > y) ? 1 : (x < y ? -1 : 0);
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .boxed()
+                .sorted(cmp)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .sorted(cmp)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain() {
+        return LongStream.range(0, size)
+                .boxed()
+                .sorted(cmp)
+                .sorted(cmp)
+                .sorted(cmp)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .sorted(cmp)
+                .sorted(cmp)
+                .sorted(cmp)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/SortedUnique.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for both sorted() and uniq() operations.
+ * Sorts long range modulo power of two, then does unique elements.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class SortedUnique {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .boxed()
+                .mapToLong((l) -> l & 0xFFFF)
+                .sorted()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .mapToLong((l) -> l & 0xFFFF)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/UniqueElements.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.ref;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for uniqueElements() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class UniqueElements {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .boxed()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain() {
+        return LongStream.range(0, size)
+                .boxed()
+                .distinct()
+                .distinct()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain() {
+        return LongStream.range(0, size).parallel()
+                .boxed()
+                .distinct()
+                .distinct()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AllMatch.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatch {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the predicates are always true to avert shortcurcuiting
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongPredicate p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return true;
+            }
+        };
+        p2 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return true;
+            }
+        };
+        p3 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return true;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_invoke() {
+        return LongStream.range(0, size).allMatch(p1);
+    }
+
+    @Benchmark
+    public int seq_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int seq_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).allMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).allMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public boolean par_invoke() {
+        return LongStream.range(0, size).parallel().allMatch(p1);
+    }
+
+    @Benchmark
+    public int par_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int par_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().allMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().allMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().allMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AllMatchShort.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for allMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AllMatchShort {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - test the predicate which will become false closer to start, in the middle, and closer to the end
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Param("100")
+    private int offset;
+
+    private LongPredicate pMid, pStart, pEnd;
+
+    @Setup
+    public void setup() {
+        pStart = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v < offset;
+            }
+        };
+        pMid = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v < size / 2;
+            }
+        };
+        pEnd = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v < size - offset;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_start() {
+        return LongStream.range(0, size).allMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean seq_mid() {
+        return LongStream.range(0, size).allMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean seq_end() {
+        return LongStream.range(0, size).allMatch(pEnd);
+    }
+
+    @Benchmark
+    public boolean par_start() {
+        return LongStream.range(0, size).parallel().allMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean par_mid() {
+        return LongStream.range(0, size).parallel().allMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean par_end() {
+        return LongStream.range(0, size).parallel().allMatch(pEnd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AnyMatch.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatch {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the predicates are always false to avert shortcurcuiting
+     */
+    @Param("100000")
+    private int size;
+
+    private LongPredicate p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+        p2 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+        p3 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_invoke() {
+        return LongStream.range(0, size).anyMatch(p1);
+    }
+
+    @Benchmark
+    public int seq_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int seq_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).anyMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).anyMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public boolean par_invoke() {
+        return LongStream.range(0, size).parallel().anyMatch(p1);
+    }
+
+    @Benchmark
+    public int par_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int par_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().anyMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().anyMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().anyMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/AnyMatchShort.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for anyMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AnyMatchShort {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - test the predicate which will become true closer to start, in the middle, and closer to the end
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Param("100")
+    private int offset;
+
+    private LongPredicate pMid, pStart, pEnd;
+
+    @Setup
+    public void setup() {
+        pStart = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v > offset;
+            }
+        };
+        pMid = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v > size / 2;
+            }
+        };
+        pEnd = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v > size - offset;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_start() {
+        return LongStream.range(0, size).anyMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean seq_mid() {
+        return LongStream.range(0, size).anyMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean seq_end() {
+        return LongStream.range(0, size).anyMatch(pEnd);
+    }
+
+    @Benchmark
+    public boolean par_start() {
+        return LongStream.range(0, size).parallel().anyMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean par_mid() {
+        return LongStream.range(0, size).parallel().anyMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean par_end() {
+        return LongStream.range(0, size).parallel().anyMatch(pEnd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Filter.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for filter() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Filter {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive predicates is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongPredicate p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new LongPredicate() {
+            @Override
+            public boolean test(long l) {
+                return (l & 0b11111111) == 0;
+            }
+        };
+        p2 = new LongPredicate() {
+            @Override
+            public boolean test(long l) {
+                return (l & 0b00001111) == 0;
+            }
+        };
+        p3 = new LongPredicate() {
+            @Override
+            public boolean test(long l) {
+                return (l & 0x00000011) == 0;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        return LongStream.range(0, size)
+                .filter(p1)
+                .filter(p1)
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        return LongStream.range(0, size).parallel()
+                .filter(p1)
+                .filter(p1)
+                .filter(p1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        return LongStream.range(0, size)
+                .filter(p1)
+                .filter(p2)
+                .filter(p3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        return LongStream.range(0, size).parallel()
+                .filter(p1)
+                .filter(p2)
+                .filter(p3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/FindAny.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findAny() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindAny {
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size).findAny().getAsLong();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel().findAny().getAsLong();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/FindFirst.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for findFirst() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class FindFirst {
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size).findFirst().getAsLong();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel().findFirst().getAsLong();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/ForEach.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongConsumer;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for forEach() operations.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ForEach {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     */
+    @Param("100000")
+    private int size;
+
+    private LongConsumer b1, b2, b3;
+    private LongAdder sink;
+
+    @Setup
+    public void setup() {
+        sink = new LongAdder();
+        b1 = new LongConsumer() {
+            @Override
+            public void accept(long v) {
+                sink.add(v);
+            }
+        };
+        b2 = new LongConsumer() {
+            @Override
+            public void accept(long v) {
+                sink.add(v);
+            }
+        };
+        b3 = new LongConsumer() {
+            @Override
+            public void accept(long v) {
+                sink.add(v);
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        LongStream.range(0, size).forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_chain111() {
+        LongStream.range(0, size).forEach(b1);
+        LongStream.range(0, size).forEach(b1);
+        LongStream.range(0, size).forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_chain123() {
+        LongStream.range(0, size).forEach(b1);
+        LongStream.range(0, size).forEach(b2);
+        LongStream.range(0, size).forEach(b3);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        LongStream.range(0, size).parallel().forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_chain111() {
+        LongStream.range(0, size).parallel().forEach(b1);
+        LongStream.range(0, size).parallel().forEach(b1);
+        LongStream.range(0, size).parallel().forEach(b1);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_chain123() {
+        LongStream.range(0, size).parallel().forEach(b1);
+        LongStream.range(0, size).parallel().forEach(b2);
+        LongStream.range(0, size).parallel().forEach(b3);
+        return sink.sum();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Limit.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for limit() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Limit {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the tests include:
+     *          - return nothing
+     *          - return just a single element
+     *          - return half
+     *          - return all but last element
+     *          - return all
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_baseline() {
+        return LongStream.range(0, size)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limit0() {
+        return LongStream.range(0, size)
+                .limit(0)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limit1() {
+        return LongStream.range(0, size)
+                .limit(1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limitHalf() {
+        return LongStream.range(0, size)
+                .limit(size / 2)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limitFull() {
+        return LongStream.range(0, size)
+                .limit(size - 1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_limitFullest() {
+        return LongStream.range(0, size)
+                .limit(size)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_baseline() {
+        return LongStream.range(0, size).parallel()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limit0() {
+        return LongStream.range(0, size).parallel()
+                .limit(0)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limit1() {
+        return LongStream.range(0, size).parallel()
+                .limit(1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limitHalf() {
+        return LongStream.range(0, size).parallel()
+                .limit(size / 2)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limitFull() {
+        return LongStream.range(0, size).parallel()
+                .limit(size - 1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_limitFullest() {
+        return LongStream.range(0, size).parallel()
+                .limit(size)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Map.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongUnaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for map() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Map {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongUnaryOperator m1, m2, m3;
+
+    @Setup
+    public void setup() {
+        m1 = new LongUnaryOperator() {
+            @Override
+            public long applyAsLong(long l) {
+                return l * 2;
+            }
+        };
+        m2 = new LongUnaryOperator() {
+            @Override
+            public long applyAsLong(long l) {
+                return l * 2;
+            }
+        };
+        m3 = new LongUnaryOperator() {
+            @Override
+            public long applyAsLong(long l) {
+                return l * 2;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        return LongStream.range(0, size)
+                .map(m1)
+                .map(m1)
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        return LongStream.range(0, size).parallel()
+                .map(m1)
+                .map(m1)
+                .map(m1)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        return LongStream.range(0, size)
+                .map(m1)
+                .map(m2)
+                .map(m3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        return LongStream.range(0, size).parallel()
+                .map(m1)
+                .map(m2)
+                .map(m3)
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/NoneMatch.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatch {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the predicates are always false to avert shortcurcuiting
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongPredicate p1, p2, p3;
+
+    @Setup
+    public void setup() {
+        p1 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+        p2 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+        p3 = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return false;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_invoke() {
+        return LongStream.range(0, size).noneMatch(p1);
+    }
+
+    @Benchmark
+    public int seq_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int seq_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).noneMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).noneMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public boolean par_invoke() {
+        return LongStream.range(0, size).parallel().noneMatch(p1);
+    }
+
+    @Benchmark
+    public int par_chain111() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+        return s;
+    }
+
+    @Benchmark
+    public int par_chain123() {
+        int s = 0;
+        s += (LongStream.range(0, size).parallel().noneMatch(p1)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().noneMatch(p2)) ? 1 : 0;
+        s += (LongStream.range(0, size).parallel().noneMatch(p3)) ? 1 : 0;
+        return s;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/NoneMatchShort.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for noneMatch() operation.
+ * Focuses on short-circuiting behavior.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class NoneMatchShort {
+
+    /**
+     * Implementation notes:
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - test the predicate which will become true closer to start, in the middle, and closer to the end
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Param("100")
+    private int offset;
+
+    private LongPredicate pMid, pStart, pEnd;
+
+    @Setup
+    public void setup() {
+        pStart = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v > offset;
+            }
+        };
+        pMid = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v > size / 2;
+            }
+        };
+        pEnd = new LongPredicate() {
+            @Override
+            public boolean test(long v) {
+                return v > size - offset;
+            }
+        };
+    }
+
+    @Benchmark
+    public boolean seq_start() {
+        return LongStream.range(0, size).noneMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean seq_mid() {
+        return LongStream.range(0, size).noneMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean seq_end() {
+        return LongStream.range(0, size).noneMatch(pEnd);
+    }
+
+    @Benchmark
+    public boolean par_start() {
+        return LongStream.range(0, size).parallel().noneMatch(pStart);
+    }
+
+    @Benchmark
+    public boolean par_mid() {
+        return LongStream.range(0, size).parallel().noneMatch(pMid);
+    }
+
+    @Benchmark
+    public boolean par_end() {
+        return LongStream.range(0, size).parallel().noneMatch(pEnd);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Reduce.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongBinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Reduce {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     */
+    @Param("100000")
+    private int size;
+
+    private LongBinaryOperator op1, op2, op3;
+
+    @Setup
+    public void setup() {
+        op1 = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op2 = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op3 = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size).reduce(op1).getAsLong();
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).reduce(op1).getAsLong();
+        l += LongStream.range(0, size).reduce(op1).getAsLong();
+        l += LongStream.range(0, size).reduce(op1).getAsLong();
+        return l;
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).reduce(op1).getAsLong();
+        l += LongStream.range(0, size).reduce(op2).getAsLong();
+        l += LongStream.range(0, size).reduce(op3).getAsLong();
+        return l;
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+        l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+        l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+        return l;
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().reduce(op1).getAsLong();
+        l += LongStream.range(0, size).parallel().reduce(op2).getAsLong();
+        l += LongStream.range(0, size).parallel().reduce(op3).getAsLong();
+        return l;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/ReduceBase.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.LongBinaryOperator;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for reduce()-base operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class ReduceBase {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+    @Param("100000")
+    private int size;
+
+    private LongBinaryOperator op1, op2, op3;
+
+    @Setup
+    public void setup() {
+        op1 = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op2 = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+        op3 = new LongBinaryOperator() {
+            @Override
+            public long applyAsLong(long l, long r) {
+                return (l > r) ? l : r;
+            }
+        };
+    }
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size).reduce(0L, op1);
+    }
+
+    @Benchmark
+    public long seq_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).reduce(0L, op1);
+        l += LongStream.range(0, size).reduce(0L, op1);
+        l += LongStream.range(0, size).reduce(0L, op1);
+        return l;
+    }
+
+    @Benchmark
+    public long seq_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).reduce(0L, op1);
+        l += LongStream.range(0, size).reduce(0L, op2);
+        l += LongStream.range(0, size).reduce(0L, op3);
+        return l;
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel().reduce(0L, op1);
+    }
+
+    @Benchmark
+    public long par_chain_111() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().reduce(0L, op1);
+        l += LongStream.range(0, size).parallel().reduce(0L, op1);
+        l += LongStream.range(0, size).parallel().reduce(0L, op1);
+        return l;
+    }
+
+    @Benchmark
+    public long par_chain_123() {
+        long l = 0;
+        l += LongStream.range(0, size).parallel().reduce(0L, op1);
+        l += LongStream.range(0, size).parallel().reduce(0L, op2);
+        l += LongStream.range(0, size).parallel().reduce(0L, op3);
+        return l;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/Sorted.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for sorted() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Sorted {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - consecutive sorts should reuse the knowledge that stream was sorted already
+     */
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .sorted()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .sorted()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain() {
+        return LongStream.range(0, size).parallel()
+                .sorted()
+                .sorted()
+                .sorted()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain() {
+        return LongStream.range(0, size).parallel()
+                .sorted()
+                .sorted()
+                .sorted()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/SortedUnique.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for both sorted() and uniq() operations.
+ * Sorts long range modulo power of two, then does unique elements.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class SortedUnique {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     */
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(1, size)
+                .map(l -> l & 0xFFFF)
+                .sorted()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(1, size).parallel()
+                .map(l -> l & 0xFFFF)
+                .sorted()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/ops/value/UniqueElements.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.ops.value;
+
+import org.openjdk.bench.java.util.stream.ops.LongAccumulator;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for uniqueElements() operation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class UniqueElements {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     *   - the result of applying consecutive operations is the same, in order to have the same number of elements in sink
+     */
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long seq_invoke() {
+        return LongStream.range(0, size)
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_invoke() {
+        return LongStream.range(0, size).parallel()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long seq_chain() {
+        return LongStream.range(0, size)
+                .distinct()
+                .distinct()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+    @Benchmark
+    public long par_chain() {
+        return LongStream.range(0, size).parallel()
+                .distinct()
+                .distinct()
+                .distinct()
+                .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineParMultiple.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark tests the pipeline fusion abilities.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class PipelineParMultiple {
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public long bulk_into_anon() {
+        return LongStream.range(0, size).parallel()
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> false)
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+    @Benchmark
+    public long bulk_into_named() {
+        LongPredicate t = (x) -> true;
+        LongPredicate f = (x) -> false;
+        return LongStream.range(0, size).parallel()
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(f)
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+
+    @Benchmark
+    public long bulk_foreach_anon() {
+        LongAdder adder = new LongAdder();
+        LongStream.range(0, size).parallel().forEach((l) -> {
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> false).test(l))
+                adder.add(l);
+        });
+        return adder.sum();
+    }
+
+
+    @Benchmark
+    public long bulk_foreach_named() {
+        LongAdder adder = new LongAdder();
+        LongPredicate t = (x) -> true;
+        LongPredicate f = (x) -> false;
+        LongStream.range(0, size).parallel().forEach((l) -> {
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (f.test(l))
+                adder.add(l);
+        });
+        return adder.sum();
+    }
+
+    @Benchmark
+    public long bulk_ifs() {
+        LongAdder adder = new LongAdder();
+        LongStream.range(0, size).parallel().forEach((l) -> {
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (false)
+                adder.add(l);
+        });
+        return adder.sum();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineSeqMultiple.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongPredicate;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark tests the pipeline fusion abilities.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class PipelineSeqMultiple {
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public Object bulk_into_anon() {
+        return LongStream.range(0, size)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> true)
+                .filter((x) -> false)
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+    @Benchmark
+    public Object bulk_into_named() {
+        LongPredicate t = (x) -> true;
+        LongPredicate f = (x) -> false;
+        return LongStream.range(0, size)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(t)
+                .filter(f)
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+
+    @Benchmark
+    public Object bulk_foreach_anon() {
+        LongAdder adder = new LongAdder();
+        LongStream.range(0, size).forEach((l) -> {
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> true).test(l))
+            if (((LongPredicate) (x) -> false).test(l))
+                adder.add(l);
+        });
+        return adder.sum();
+    }
+
+
+    @Benchmark
+    public Object bulk_foreach_named() {
+        LongAdder adder = new LongAdder();
+        LongPredicate t = (x) -> true;
+        LongPredicate f = (x) -> false;
+        LongStream.range(0, size).forEach((l) -> {
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (t.test(l))
+            if (f.test(l))
+                adder.add(l);
+        });
+        return adder.sum();
+    }
+
+    @Benchmark
+    public Object bulk_ifs() {
+        LongAdder adder = new LongAdder();
+        LongStream.range(0, size).forEach((l) -> {
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (true)
+            if (false)
+                adder.add(l);
+        });
+        return adder.sum();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/PipelineSetup.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark tests the pipeline construction costs.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class PipelineSetup {
+
+    /**
+     * This is one of the few benchmarks where measuring running time makes sense.
+     */
+
+    @Param("100000")
+    private int size;
+
+    @Benchmark
+    public Object baseline_newObject() {
+        return new Object();
+    }
+
+    @Benchmark
+    public LongStream seq_test00() {
+        return LongStream.range(0, size);
+    }
+
+    @Benchmark
+    public LongStream seq_test01() {
+        return LongStream.range(0, size)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream seq_test02() {
+        return LongStream.range(0, size)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream seq_test04() {
+        return LongStream.range(0, size)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream seq_test08() {
+        return LongStream.range(0, size)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream seq_test16() {
+        return LongStream.range(0, size)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream par_test00() {
+        return LongStream.range(0, size).parallel();
+    }
+
+    @Benchmark
+    public LongStream par_test01() {
+        return LongStream.range(0, size).parallel()
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream par_test02() {
+        return LongStream.range(0, size).parallel()
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream par_test04() {
+        return LongStream.range(0, size).parallel()
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream par_test08() {
+        return LongStream.range(0, size).parallel()
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+    @Benchmark
+    public LongStream par_test16() {
+        return LongStream.range(0, size).parallel()
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false)
+                .filter((x) -> false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/pipeline/Terminal.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.pipeline;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.LongConsumer;
+import java.util.stream.LongStream;
+
+/**
+ * Benchmark for forEach()/iterator()/into() operations;
+ * Testing which one is faster for semantically-equvalent operations.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Terminal {
+
+    /**
+     * Implementation notes:
+     *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
+     *   - operations are explicit inner classes to untangle unwanted lambda effects
+     */
+
+    @Param("100000")
+    private int size;
+
+    private LongAdder sink;
+    private LongConsumer block;
+
+    @Setup
+    public void setup() {
+        sink = new LongAdder();
+        block = new LongConsumer() {
+            @Override
+            public void accept(long v) {
+                sink.add(v);
+            }
+        };
+    }
+
+    @Benchmark
+    public long baseline_prim_acc() {
+        long s = 0;
+        for (long l = 0L; l < size; l++) {
+            s += l;
+        }
+        sink.add(s);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long baseline_prim_sink() {
+        for (long l = 0L; l < size; l++) {
+            sink.add(l);
+        }
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long baseline_iterator_acc() {
+        long s = 0;
+        for (Iterator<Long> iterator = LongStream.range(0, size).boxed().iterator(); iterator.hasNext(); ) {
+            Long l = iterator.next();
+            s += l;
+        }
+        sink.add(s);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long baseline_iterator_sink() {
+        for (Iterator<Long> iterator = LongStream.range(0, size).boxed().iterator(); iterator.hasNext(); ) {
+            sink.add(iterator.next());
+        }
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_iterator() {
+        Iterator<Long> i = LongStream.range(0, size).boxed().iterator();
+        while (i.hasNext()) {
+            sink.add(i.next());
+        }
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_iterator() {
+        Iterator<Long> i = LongStream.range(0, size).parallel().boxed().iterator();
+        while (i.hasNext()) {
+            sink.add(i.next());
+        }
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_forEach() {
+        LongStream.range(1, size).forEach(block);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long par_forEach() {
+        LongStream.range(1, size).parallel().forEach(block);
+        return sink.sum();
+    }
+
+    @Benchmark
+    public long seq_into() {
+        return LongStream.range(1, size)
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+    @Benchmark
+    public long par_into() {
+        return LongStream.range(1, size).parallel()
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DataProviders.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) , 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.
+ */
+
+package org.openjdk.bench.java.util.stream.tasks;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.stream.Stream;
+
+public class DataProviders {
+    public static Stream<String> dictionary() throws IOException {
+        BufferedReader r = new BufferedReader(new InputStreamReader(DataProviders.class.getResourceAsStream("cmudict-0.7b.txt")));
+        // Strip out the copyright notice and special chars
+        return r.lines().filter(w -> w.charAt(0) >= 'A' && w.charAt(0) <= 'Z').map(w -> w.substring(0, w.indexOf(" "))).onClose(() -> {
+            try {
+                r.close();
+            } catch (IOException e) {
+                // swallow
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+
+
+/**
+ * Bulk scenario: searching max "wordValue" through the dictionary (array of strings).
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+    @Setup(Level.Trial)
+    public void loadData() {
+        // cause classload and problem initialization
+        DictionaryProblem.class.getName();
+    }
+
+    @Benchmark
+    public int hm_seq() {
+        int max = 0;
+        for (String s : DictionaryProblem.get()) {
+            int v = DictionaryProblem.wordValue(s);
+            if (v > max) {
+                max = v;
+            }
+        }
+        return max;
+    }
+
+    @Benchmark
+    public int hm_par() {
+        return new Task(DictionaryProblem.get(), 0, DictionaryProblem.get().length).invoke();
+    }
+
+    @Benchmark
+    public int bulk_seq_inner() {
+        return Arrays.stream(DictionaryProblem.get())
+                .map(new Function<String, Integer>() {
+                    @Override
+                    public Integer apply(String s) {
+                        return DictionaryProblem.wordValue(s);
+                    }
+                })
+                .reduce(0, new BinaryOperator<Integer>() {
+                    @Override
+                    public Integer apply(Integer l, Integer r) {
+                        return l > r ? l : r;
+                    }
+                });
+    }
+
+    @Benchmark
+    public int bulk_par_inner() {
+        return Arrays.stream(DictionaryProblem.get()).parallel()
+                .map(new Function<String, Integer>() {
+                    @Override
+                    public Integer apply(String s) {
+                        return DictionaryProblem.wordValue(s);
+                    }
+                })
+                .reduce(0, new BinaryOperator<Integer>() {
+                    @Override
+                    public Integer apply(Integer l, Integer r) {
+                        return l > r ? l : r;
+                    }
+                });
+    }
+
+
+    public static class Task extends RecursiveTask<Integer> {
+        private static final int FORK_LIMIT = 500;
+
+        private final String[] words;
+        private final int start, end;
+
+        Task(String[] w, int start, int end) {
+            this.words = w;
+            this.start = start;
+            this.end = end;
+        }
+
+        @Override
+        protected Integer compute() {
+            int size = end - start;
+            if (size > FORK_LIMIT) {
+                int mid = start + size / 2;
+                Task t1 = new Task(words, start, mid);
+                Task t2 = new Task(words, mid, end);
+                t1.fork();
+                Integer v2 = t2.invoke();
+                Integer v1 = t1.join();
+                return Math.max(v1, v2);
+            } else {
+                int max = 0;
+                for (int i = start; i < end; i++) {
+                    int v = DictionaryProblem.wordValue(words[i]);
+                    if (v > max) {
+                        max = v;
+                    }
+                }
+                return max;
+            }
+        }
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/DictionaryProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+import org.openjdk.bench.java.util.stream.tasks.DataProviders;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class DictionaryProblem {
+
+    private static final int DICTIONARY_REPEAT_RATE = 40;
+
+    private static final String[] dict;
+
+    static {
+        int size;
+        int idx = 0;
+        List<String> d = Collections.emptyList();
+        try (Stream<String> s = DataProviders.dictionary()) {
+            d = s.collect(Collectors.<String>toList());
+        } catch (Exception e) {
+            // ignore
+        }
+        size = d.size() * DICTIONARY_REPEAT_RATE;
+        dict = new String[size];
+        for (int i = 0; i < DICTIONARY_REPEAT_RATE; i++) {
+            d.sort(new IdxComparator(i));
+            for (String s : d) {
+                // copy the whole string
+                dict[idx++] = new String(s.toCharArray());
+            }
+        }
+        assert (idx == dict.length);
+    }
+
+    public static String[] get() {
+        return dict;
+    }
+
+    /**
+     * A word value is the sum of alphabet value of each characters in a word.
+     *
+     * @param word The word
+     * @return The word value
+     */
+    public static int wordValue(String word) {
+        char[] ar = word.toLowerCase().toCharArray();
+        int value = 0;
+        for (char c: ar) {
+            int v = c - 'a' + 1;
+            if (v < 1 || v > 26) {
+                // skip non-alphabet
+                continue;
+            }
+            value += (c - 'a' + 1);
+        }
+        return value;
+    }
+
+    static class IdxComparator implements Comparator<String> {
+        private final int index;
+
+        public IdxComparator(int i) {
+            index = i;
+        }
+
+        @Override
+        public int compare(String a, String b) {
+            if (a.length() > index && b.length() > index) {
+                return (a.charAt(index) - b.charAt(index));
+            } else {
+                return (a.length() - b.length());
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Lambda.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: searching max "wordValue" through the dictionary (array of strings).
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+    @Setup(Level.Trial)
+    public void loadData() {
+        // cause classload and problem initialization
+        DictionaryProblem.class.getName();
+    }
+
+    public static Integer maxInt(Integer l, Integer r) {
+        return l > r ? l : r;
+    }
+
+    @Benchmark
+    public int bulk_seq_lambda() {
+        return Arrays.stream(DictionaryProblem.get())
+                .map(s -> DictionaryProblem.wordValue(s))
+                .reduce(0, (l, r) -> l > r ? l : r);
+    }
+
+    @Benchmark
+    public int bulk_seq_mref() {
+        return Arrays.stream(DictionaryProblem.get())
+                .map(DictionaryProblem::wordValue)
+                .reduce(0, Lambda::maxInt);
+    }
+
+    @Benchmark
+    public int bulk_par_lambda() {
+        return Arrays.stream(DictionaryProblem.get()).parallel()
+                .map(s -> DictionaryProblem.wordValue(s))
+                .reduce(0, (l, r) -> l > r ? l : r);
+    }
+
+    @Benchmark
+    public int bulk_par_mref() {
+        return Arrays.stream(DictionaryProblem.get()).parallel()
+                .map(DictionaryProblem::wordValue)
+                .reduce(0, Lambda::maxInt);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/DictionaryWordValue/Xtras.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.DictionaryWordValue;
+
+/**
+ * Bulk scenario: searching max "wordValue" through the dictionary (array of strings).
+ */
+public class Xtras {
+
+    // no workloads yet
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerDuplicate;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * This benchmark assesses flatMap() performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Bulk {
+
+    /**
+     * Implementation notes:
+     *   - parallel versions need to use special sink to get the values
+     */
+
+    private IntegerDuplicateProblem problem;
+    private LongAdder adder;
+
+    @Setup
+    public void setup() {
+        problem = new IntegerDuplicateProblem();
+        adder = new LongAdder();
+    }
+
+    @Benchmark
+    public long hm_seq() {
+        for (Integer i : problem.get()) {
+            adder.add(i);
+            adder.add(i);
+        }
+        return adder.sum();
+    }
+
+    @Benchmark
+    public long hm_par() {
+        new Task(problem.get(), adder, 0, problem.get().length).invoke();
+        return adder.sum();
+    }
+
+    @Benchmark
+    public long bulk_seq_inner() {
+        return Arrays.stream(problem.get()).flatMap(new Function<Integer, Stream<Integer>>() {
+            @Override
+            public Stream<Integer> apply(Integer integer) {
+                return Collections.nCopies(2, integer).stream();
+            }
+        }).collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+    @Benchmark
+    public long bulk_par_inner() {
+        return Arrays.stream(problem.get()).parallel().flatMap(new Function<Integer, Stream<Integer>>() {
+            @Override
+            public Stream<Integer> apply(Integer integer) {
+                return Collections.nCopies(2, integer).stream();
+            }
+        }).collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+    public static class Task extends RecursiveAction {
+        private static final int FORK_LIMIT = 500;
+
+        private final Integer[] data;
+        private final LongAdder sink;
+        private final int start;
+        private final int end;
+
+        Task(Integer[] w, LongAdder sink, int start, int end) {
+            this.data = w;
+            this.sink = sink;
+            this.start = start;
+            this.end = end;
+        }
+
+        @Override
+        protected void compute() {
+            int size = end - start;
+            if (size > FORK_LIMIT) {
+                int mid = start + size / 2;
+                Task t1 = new Task(data, sink, start, mid);
+                Task t2 = new Task(data, sink, mid, end);
+                t1.fork();
+                t2.invoke();
+                t1.join();
+            } else {
+                for (int i = start; i < end; i++) {
+                    sink.add(i);
+                    sink.add(i);
+                }
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/IntegerDuplicateProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerDuplicate;
+
+import java.util.Random;
+
+public class IntegerDuplicateProblem {
+
+    private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024*1024);
+
+    private final Integer[] data = new Integer[DATA_SIZE];
+
+    public IntegerDuplicateProblem() {
+        // use fixed seed to reduce run-to-run variance
+        Random rand = new Random(0x30052012);
+
+        for (int i = 0; i < data.length; i++) {
+            data[i] = new Integer(rand.nextInt());
+        }
+    }
+
+    public Integer[] get() {
+        return data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerDuplicate/Lambda.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerDuplicate;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+
+/**
+ * This benchmark assesses flatMap() performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class Lambda {
+
+    /**
+     * Implementation notes:
+     *   - parallel versions need to use special sink to get the values
+     */
+
+    private IntegerDuplicateProblem problem;
+
+    @Setup
+    public void setup() {
+        problem = new IntegerDuplicateProblem();
+    }
+
+    @Benchmark
+    public long lambda_seq_inner() {
+        return Arrays.stream(problem.get()).flatMap(k -> Collections.nCopies(2, k).stream())
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+    @Benchmark
+    public long lambda_par_inner() {
+        return Arrays.stream(problem.get()).parallel().flatMap(k -> Collections.nCopies(2, k).stream())
+                .collect(LongAdder::new, LongAdder::add, (la1, la2) -> la1.add(la2.sum())).sum();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+
+/**
+ * Bulk scenario: search for max value in array.
+ *
+ * This test covers bulk infrastructure only. Refer to other tests for lambda-specific cases.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+    private IntegerMaxProblem problem;
+
+    @Setup(Level.Trial)
+    public void populateData(){
+        problem = new IntegerMaxProblem();
+    }
+
+    @Benchmark
+    public int hm_seq() {
+        int max = Integer.MIN_VALUE;
+        for (int v: problem.get()) {
+            if (v > max) {
+                max = v;
+            }
+        }
+        return max;
+    }
+
+    @Benchmark
+    public int hm_par() {
+        return new MaxIntTask(problem.get(), 0, problem.get().length).invoke();
+    }
+
+    @Benchmark
+    public int bulk_seq_inner() {
+        return Arrays.stream(problem.get()).reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+            @Override
+            public Integer apply(Integer l, Integer r) {
+                return l > r ? l : r;
+            }
+        });
+    }
+
+    @Benchmark
+    public int bulk_par_inner() {
+        return Arrays.stream(problem.get()).parallel().reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+            @Override
+            public Integer apply(Integer l, Integer r) {
+                return l > r ? l : r;
+            }
+        });
+    }
+
+    static class MaxIntTask extends RecursiveTask<Integer> {
+        private static final int FORK_LIMIT = 1000;
+        final Integer[] data;
+        final int start, end;
+
+        MaxIntTask(Integer[] data, int start, int end) {
+            this.data = data;
+            this.start = start;
+            this.end = end;
+        }
+
+        @Override
+        protected Integer compute() {
+            int size = end - start;
+            if (size > FORK_LIMIT) {
+                int mid = start + size / 2;
+                MaxIntTask t1 = new MaxIntTask(data, start, mid);
+                MaxIntTask t2 = new MaxIntTask(data, mid, end);
+                t1.fork();
+                Integer v2 = t2.invoke();
+                Integer v1 = t1.join();
+                return Math.max(v1, v2);
+            } else {
+                int max = Integer.MIN_VALUE;
+                for (int i = start; i < end; i++) {
+                    if (data[i] > max) {
+                        max = data[i];
+                    }
+                }
+                return max;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/IntegerMaxProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import java.util.Random;
+
+public class IntegerMaxProblem {
+
+    private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024*1024);
+
+    private final Integer[] data = new Integer[DATA_SIZE];
+
+    public IntegerMaxProblem() {
+        // use fixed seed to reduce run-to-run variance
+        Random rand = new Random(0x30052012);
+
+        for (int i = 0; i < data.length; i++) {
+            data[i] = new Integer(rand.nextInt());
+        }
+    }
+
+    public Integer[] get() {
+        return data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Lambda.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: search for max value in array.
+ *
+ * This test covers lambda-specific solutions for the problem.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+    private IntegerMaxProblem problem;
+
+    @Setup(Level.Trial)
+    public void populateData(){
+        problem = new IntegerMaxProblem();
+    }
+
+    public static Integer maxInt(Integer l, Integer r) {
+        return l > r ? l : r;
+    }
+
+    @Benchmark
+    public int bulk_seq_lambda() {
+        return Arrays.stream(problem.get()).reduce(Integer.MIN_VALUE, (l, r) -> l > r ? l : r);
+    }
+
+    @Benchmark
+    public int bulk_seq_methodRef() {
+        return Arrays.stream(problem.get()).reduce(Integer.MIN_VALUE, Lambda::maxInt);
+    }
+
+    @Benchmark
+    public int bulk_par_lambda() {
+        return Arrays.stream(problem.get()).parallel().reduce(Integer.MIN_VALUE, (l, r) -> l > r ? l : r);
+    }
+
+    @Benchmark
+    public int bulk_par_methodRef() {
+        return Arrays.stream(problem.get()).parallel().reduce(Integer.MIN_VALUE, Lambda::maxInt);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerMax/Xtras.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerMax;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: search for max value in array.
+ *
+ * This test covers other interesting solutions for the original problem.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Xtras {
+
+    private IntegerMaxProblem problem;
+
+    @Setup(Level.Trial)
+    public void populateData(){
+        problem = new IntegerMaxProblem();
+    }
+
+
+//    @Benchmark
+//    public int bulk_seq_inner_pull() {
+//        Stream<Integer> stream = Arrays.stream(problem.get());
+//
+//        // force pull traversal
+//        Integer car = stream.iterator().next();
+//        Integer cdr = stream.reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+//            @Override
+//            public Integer apply(Integer l, Integer r) {
+//                return l > r ? l : r;
+//            }
+//        });
+//        return (car > cdr) ? car : cdr;
+//    }
+//
+//    @Benchmark
+//    public int bulk_par_inner_pull() {
+//        Stream<Integer> stream = Arrays.parallelStream(problem.get());
+//
+//        // force pull traversal
+//        Integer car = stream.iterator().next();
+//        Integer cdr = stream.reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {
+//            @Override
+//            public Integer apply(Integer l, Integer r) {
+//                return l > r ? l : r;
+//            }
+//        });
+//        return (car > cdr) ? car : cdr;
+//    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+
+/**
+ * Bulk scenario: compute the sum of Integer array.
+ *
+ * This test covers bulk infrastructure only. Refer to other tests for lambda-specific cases.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+    private IntegerSumProblem problem;
+
+    @Setup(Level.Trial)
+    public void populateData(){
+        problem = new IntegerSumProblem();
+    }
+
+    @Benchmark
+    public int hm_seq() {
+        int sum = 0;
+        for (int v : problem.get()) {
+            sum += v;
+        }
+        return sum;
+    }
+
+    @Benchmark
+    public int hm_par() {
+        return new SumIntTask(problem.get()).invoke();
+    }
+
+    @Benchmark
+    public int bulk_seq_inner() {
+        return Arrays.stream(problem.get()).reduce(0, new BinaryOperator<Integer>() {
+            @Override
+            public Integer apply(Integer left, Integer right) {
+                return left + right;
+            }
+        });
+    }
+
+    @Benchmark
+    public int bulk_par_inner() {
+        return Arrays.stream(problem.get()).parallel().reduce(0, new BinaryOperator<Integer>() {
+            @Override
+            public Integer apply(Integer left, Integer right) {
+                return left + right;
+            }
+        });
+    }
+
+    static class SumIntTask extends RecursiveTask<Integer> {
+        private static final int FORK_LIMIT = 1000;
+        final Integer[] data;
+        final int start, end;
+
+        SumIntTask(Integer[] data) {
+            this(data, 0, data.length);
+        }
+
+        SumIntTask(Integer[] data, int start, int end) {
+            this.data = data;
+            this.start = start;
+            this.end = end;
+        }
+
+        @Override
+        protected Integer compute() {
+            int size = end - start;
+            if (size > FORK_LIMIT) {
+                int mid = start + size / 2;
+                SumIntTask t1 = new SumIntTask(data, start, mid);
+                SumIntTask t2 = new SumIntTask(data, mid, end);
+                t1.fork();
+                return t2.invoke() + t1.join();
+            } else {
+                int sum = 0;
+                for (int i = start; i < end; i++) {
+                    sum += data[i];
+                }
+                return sum;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/IntegerSumProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+import java.util.Random;
+
+public class IntegerSumProblem {
+
+    private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024*1024);
+
+    private final Integer[] data = new Integer[DATA_SIZE];
+
+    public IntegerSumProblem() {
+        // use fixed seed to reduce run-to-run variance
+        Random rand = new Random(0x30052012);
+
+        for (int i = 0; i < data.length; i++) {
+            data[i] = new Integer(rand.nextInt());
+        }
+    }
+
+    public Integer[] get() {
+        return data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Lambda.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Bulk scenario: compute the sum of Integer array.
+ *
+ * This test covers lambda-specific solutions for the problem.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+    private IntegerSumProblem problem;
+
+    @Setup(Level.Trial)
+    public void populateData(){
+        problem = new IntegerSumProblem();
+    }
+
+    public static Integer sum(Integer a, Integer b) {
+        return a + b;
+    }
+
+    @Benchmark
+    public int bulk_seq_lambda() {
+        return Arrays.stream(problem.get()).reduce(0, (l, r) -> l + r);
+    }
+
+    @Benchmark
+    public int bulk_par_lambda() {
+        return Arrays.stream(problem.get()).parallel().reduce(0, (l, r) -> l + r);
+    }
+
+    @Benchmark
+    public int bulk_seq_mref() {
+        return Arrays.stream(problem.get()).reduce(0, Lambda::sum);
+    }
+
+    @Benchmark
+    public int bulk_par_mref() {
+        return Arrays.stream(problem.get()).parallel().reduce(0, Lambda::sum);
+    }
+
+    @Benchmark
+    public int bulk_seq_Integer_mref() {
+        return Arrays.stream(problem.get()).reduce(0, Integer::sum);
+    }
+
+    @Benchmark
+    public int bulk_par_Integer_mref() {
+        return Arrays.stream(problem.get()).parallel().reduce(0, Integer::sum);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/IntegerSum/Xtras.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.IntegerSum;
+
+/**
+ * Bulk scenario: compute the sum of Integer array.
+ *
+ * This test covers other interesting solutions for the original problem.
+ */
+public class Xtras {
+
+    // no workloads yet
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PhoneCode/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) , 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.
+ */
+
+package org.openjdk.bench.java.util.stream.tasks.PhoneCode;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static org.openjdk.bench.java.util.stream.tasks.PhoneCode.PhoneCodeProblem.wordsForNumber;
+
+/**
+ * This benchmark compare various strategies solving the phone code problem.
+ * The result should offer some insights on strength/drawbacks of underlying
+ * implementation.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MINUTES)
+@State(Scope.Benchmark)
+public class Bulk {
+    // several method choke up with 6-digit problem
+    private final static int SIZE = 5;
+    private Stream<String> join(String head,
+                                String tail,
+                                Function<String, Stream<String>> encoder)
+    {
+        Stream<String> s = wordsForNumber(head).stream();
+
+        if (! tail.isEmpty()) {
+            s = s.flatMap(h -> encoder.apply(tail).map(t -> h + " " + t));
+        }
+
+        return s;
+    }
+
+    private Stream<String> encode_par1(String number) {
+        return IntStream.range(1, number.length() + 1)
+                      .parallel()
+                      .boxed()
+                      .flatMap(i -> join(number.substring(0, i),
+                              number.substring(i),
+                              this::encode_par1));
+    }
+
+    private Stream<String> encode_par2(String number) {
+        return IntStream.range(1, number.length() + 1)
+                      .boxed()
+                      .parallel()
+                      .flatMap(i -> join(number.substring(0, i),
+                                         number.substring(i),
+                                         this::encode_par2));
+    }
+
+    private Stream<String> encode_ser(String number) {
+        return IntStream.range(1, number.length() + 1)
+                      .boxed()
+                      .flatMap(i -> join(number.substring(0, i),
+                                         number.substring(i),
+                                         this::encode_ser));
+    }
+
+    private Stream<String> encode_loop_concat(String number) {
+        if (number.isEmpty()) {
+            return Stream.empty();
+        }
+        // full number
+        Stream<String> s = wordsForNumber(number).stream();
+        // split
+        for (int i = 1; i < number.length(); i++) {
+            s = Stream.concat(s, join(number.substring(0, i),
+                                       number.substring(i),
+                                       this::encode_loop_concat));
+        }
+
+        return s;
+    }
+
+    private Collection<String> encode_loop_collect(String number) {
+        if (number.isEmpty()) {
+            return Collections.emptySet();
+        }
+
+        Collection<String> rv = new HashSet<>();
+
+        for (int i = 1; i <= number.length(); i++) {
+            join(number.substring(0, i),
+                 number.substring(i),
+                 s -> encode_loop_collect(s).stream()).forEach(rv::add);
+        }
+
+        return rv;
+    }
+
+    private Collection<String> encode_inline(String number) {
+        if (number.isEmpty()) {
+            return Collections.emptySet();
+        }
+
+        Collection<String> rv = new HashSet<>();
+
+        for (int i = 1; i < number.length(); i++) {
+            String front = number.substring(0, i);
+            String rest = number.substring(i);
+            wordsForNumber(front).stream()
+                .flatMap(h -> encode_inline(rest).stream().map(t -> h + " " + t))
+                .forEach(rv::add);
+        }
+
+        rv.addAll(wordsForNumber(number));
+
+        return rv;
+    }
+
+    @Benchmark
+    public int bulk_par_range_concurrent() {
+        // force collect
+        return PhoneCodeProblem.get(SIZE)
+                               .flatMap(this::encode_par1)
+                               .collect(Collectors.toConcurrentMap(
+                                    Function.identity(),
+                                    Function.identity(),
+                                    (l, r) -> l))
+                               .keySet()
+                               .size();
+    }
+
+    @Benchmark
+    public int bulk_par_boxed_range_concurrent() {
+        // force collect
+        return PhoneCodeProblem.get(SIZE)
+                               .flatMap(this::encode_par2)
+                               .collect(Collectors.toConcurrentMap(
+                                       Function.identity(),
+                                       Function.identity(),
+                                       (l, r) -> l))
+                               .keySet()
+                               .size();
+    }
+
+    @Benchmark
+    public int bulk_par_range() {
+        // force collect
+        return PhoneCodeProblem.get(SIZE)
+                               .flatMap(this::encode_par1)
+                               .collect(Collectors.toSet())
+                               .size();
+    }
+
+    @Benchmark
+    public int bulk_par_boxed_range() {
+        // force collect
+        return PhoneCodeProblem.get(SIZE)
+                               .flatMap(this::encode_par2)
+                               .collect(Collectors.toSet())
+                               .size();
+    }
+
+    @Benchmark
+    public int bulk_ser_range() {
+        // force collect
+        return PhoneCodeProblem.get(SIZE)
+                               .flatMap(this::encode_ser)
+                               .collect(Collectors.toSet())
+                               .size();
+    }
+
+    @Benchmark
+    public int bulk_ser_loop_concat() {
+        // force collect
+        return PhoneCodeProblem.get(SIZE)
+                               .flatMap(this::encode_loop_concat)
+                               .collect(Collectors.toSet())
+                               .size();
+    }
+
+    @Benchmark
+    public int bulk_ser_loop_collect() {
+        return PhoneCodeProblem.get(SIZE)
+                               .map(this::encode_loop_collect)
+                               .map(Collection::size)
+                               .reduce(0, Integer::sum);
+    }
+
+    @Benchmark
+    public int bulk_ser_inline() {
+        return PhoneCodeProblem.get(SIZE)
+                               .map(this::encode_inline)
+                               .map(Collection::size)
+                               .reduce(0, Integer::sum);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PhoneCode/PhoneCodeProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2013 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.
+ */
+
+package org.openjdk.bench.java.util.stream.tasks.PhoneCode;
+
+import org.openjdk.bench.java.util.stream.tasks.DataProviders;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * The phone coder problem is trying to find full list of possible
+ * mnemonic combination of numbers.
+ *
+ * The solution is based on Martin Odersky's devoxx 2010 scala talk,
+ * where numbers are not allowed in the result, which is not really
+ * correct, but we don't care.
+ */
+public class PhoneCodeProblem {
+    // Map Character 'A'-'Z' to digits "2"-"9", key is charCode
+    private static final Map<Integer, String> CHAR_CODE;
+    // Map a string of digits to a collection of dictionary words
+    private static final Map<String, List<String>> WORD_CODES;
+
+    static {
+        HashMap<String, String> mnemonics = new HashMap<>(8);
+        mnemonics.put("2", "ABC");
+        mnemonics.put("3", "DEF");
+        mnemonics.put("4", "GHI");
+        mnemonics.put("5", "JKL");
+        mnemonics.put("6", "MNO");
+        mnemonics.put("7", "PQRS");
+        mnemonics.put("8", "TUV");
+        mnemonics.put("9", "WXYZ");
+
+        CHAR_CODE = new ConcurrentHashMap<>();
+        mnemonics.entrySet().stream().forEach(e ->
+                e.getValue().chars().forEach(c ->
+                    { CHAR_CODE.put(c, e.getKey()); } ));
+
+        WORD_CODES = loadDictionary();
+        // System.out.println("Dictionary loaded with " + WORD_CODES.size() + " number entries");
+    }
+
+    // Convert a word to its number form
+    private static String wordToNumber(String word) {
+        return word.chars().mapToObj(CHAR_CODE::get)
+                           .reduce("", String::concat);
+    }
+
+    // Prepare number -> word lookup table
+    private static Map<String, List<String>> loadDictionary() {
+        try (Stream<String> s = DataProviders.dictionary()) {
+            return s.filter(w -> w.length() > 1)
+                    .filter(w -> w.matches("[a-zA-Z]*"))
+                    .map(String::toUpperCase)
+                    .collect(Collectors.groupingBy(PhoneCodeProblem::wordToNumber));
+        } catch (Exception ex) {
+            ex.printStackTrace(System.err);
+            return Collections.emptyMap();
+        }
+    }
+
+    public static Collection<String> wordsForNumber(String number) {
+        Collection<String> rv = WORD_CODES.get(number);
+        return (null == rv) ? Collections.emptySet() : rv;
+    }
+
+    public static Stream<String> get(int length) {
+        String digits[] = { "2", "3", "4", "5", "6", "7", "8", "9" };
+
+        Stream<String> s = Arrays.stream(digits);
+        for (int i = 1; i < length; i++) {
+            s = s.flatMap(d1 -> Arrays.stream(digits).map(d2 -> d1 + d2));
+        }
+        return s;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/PrimesProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PrimesProblem {
+
+    /**
+     * Factors n into its prime factors. If n is prime,
+     * the result is a list of length 1 containing n.
+     *
+     * @param n the number to be factored
+     * @return a list of prime factors
+     */
+    static List<Long> factor(long n) {
+        List<Long> flist = new ArrayList<>();
+
+        while (n % 2L == 0) {
+            flist.add(2L);
+            n /= 2L;
+        }
+
+        long divisor = 3L;
+        while (n > 1L) {
+            long quotient = n / divisor;
+            if (n % divisor == 0) {
+                flist.add(divisor);
+                n = quotient;
+            } else if (quotient > divisor) {
+                divisor += 2L;
+            } else {
+                flist.add(n);
+                break;
+            }
+        }
+
+        return flist;
+    }
+
+    /**
+     * Tests whether n is prime.
+     *
+     * @param n the number to be tested
+     * @return true if n is prime, false if n is composite
+     */
+    public static boolean isPrime(long n) {
+        List<Long> factors = factor(n);
+        return (factors.size() == 1);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t100;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+    private final long RANGE_START  = 1000_000_000_000_000L;
+    private final long RANGE_END = RANGE_START + 100;
+
+    @Benchmark
+    public List<Long> hm_seq() {
+        List<Long> results = new ArrayList<>();
+        for (long i = RANGE_START; i < RANGE_END; i++) {
+            if (PrimesProblem.isPrime(i)) {
+                results.add(i);
+            }
+        }
+        return results;
+    }
+
+    @Benchmark
+    public List<Long> hm_par() {
+        return new FactoringTask(RANGE_START, RANGE_END).invoke();
+    }
+
+    @Benchmark
+    public List<Long> bulk_seq_inner() {
+        return LongStream.range(RANGE_START, RANGE_END)
+                .boxed()
+                .filter(new Predicate<Long>() {
+                            @Override
+                            public boolean test(Long o) {
+                                return PrimesProblem.isPrime(o);
+                            }
+                        }
+                ).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_par_inner() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel()
+                .boxed()
+                .filter(new Predicate<Long>() {
+                            @Override
+                            public boolean test(Long o) {
+                                return PrimesProblem.isPrime(o);
+                            }
+                        }
+                ).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_parseq_inner() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel()
+                .boxed()
+                .filter(new Predicate<Long>() {
+                            @Override
+                            public boolean test(Long o) {
+                                return PrimesProblem.isPrime(o);
+                            }
+                        }
+                ).sequential().collect(Collectors.<Long>toList());
+    }
+
+    public static class FactoringTask extends RecursiveTask<List<Long>> {
+        final long low;
+        final long high;
+
+        @Override
+        protected List<Long> compute() {
+            if (high - low == 1L) {
+                if (PrimesProblem.isPrime(low))
+                    return Collections.singletonList(low);
+                else
+                    return Collections.emptyList();
+            }
+
+            long mid = (low + high) / 2L;
+            FactoringTask t1 = new FactoringTask(low, mid);
+            FactoringTask t2 = new FactoringTask(mid, high);
+
+            List<Long> results;
+
+            // The right way to do it. Forks off one task and
+            // continues the other task in this thread. I've
+            // seen up to 8x speed up on 16-way Intel and 32-way
+            // SPARC boxes (which probably matches the actual number
+            // of cores they have, as opposed to the number of threads)
+            t2.fork();
+            results = new ArrayList<>(t1.compute());
+            results.addAll(t2.join());
+
+            return results;
+        }
+
+        FactoringTask(long low, long high) {
+            this.low = low;
+            this.high = high;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Lambda.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t100;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+    private final long RANGE_START  = 1000_000_000_000_000L;
+    private final long RANGE_END = RANGE_START + 100;
+
+    @Benchmark
+    public List<Long> bulk_seq_lambda() {
+        return LongStream.range(RANGE_START, RANGE_END).boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_seq_methodRef() {
+        return LongStream.range(RANGE_START, RANGE_END).boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_par_lambda() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_par_methodRef() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_parseq_lambda() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).sequential().collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_parseq_methodRef() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).sequential().collect(Collectors.<Long>toList());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t100/Xtras.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t100;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+public class Xtras {
+
+    private final long RANGE_START  = 1000_000_000_000_000L;
+    private final long RANGE_END = RANGE_START + 100;
+
+    /** No code yet **/
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t10000;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+    private final long RANGE_START  = 1000_000_000_000_000L;
+    private final long RANGE_END = RANGE_START + 100;
+
+    @Benchmark
+    public List<Long> hm_seq() {
+        List<Long> results = new ArrayList<>();
+        for (long i = RANGE_START; i < RANGE_END; i++) {
+            if (PrimesProblem.isPrime(i)) {
+                results.add(i);
+            }
+        }
+        return results;
+    }
+
+    @Benchmark
+    public List<Long> hm_par() {
+        return new FactoringTask(RANGE_START, RANGE_END).invoke();
+    }
+
+    @Benchmark
+    public List<Long> bulk_seq_inner() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel()
+                .boxed()
+                .filter(new Predicate<Long>() {
+                            @Override
+                            public boolean test(Long o) {
+                                return PrimesProblem.isPrime(o);
+                            }
+                        }
+                ).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_par_inner() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel()
+                .boxed()
+                .filter(new Predicate<Long>() {
+                            @Override
+                            public boolean test(Long o) {
+                                return PrimesProblem.isPrime(o);
+                            }
+                        }
+                ).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_parseq_inner() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel()
+                .boxed()
+                .filter(new Predicate<Long>() {
+                            @Override
+                            public boolean test(Long o) {
+                                return PrimesProblem.isPrime(o);
+                            }
+                        }
+                ).sequential().collect(Collectors.<Long>toList());
+    }
+
+    public static class FactoringTask extends RecursiveTask<List<Long>> {
+        final long low;
+        final long high;
+
+        @Override
+        protected List<Long> compute() {
+            if (high - low == 1L) {
+                if (PrimesProblem.isPrime(low))
+                    return Collections.singletonList(low);
+                else
+                    return Collections.emptyList();
+            }
+
+            long mid = (low + high) / 2L;
+            FactoringTask t1 = new FactoringTask(low, mid);
+            FactoringTask t2 = new FactoringTask(mid, high);
+
+            List<Long> results;
+
+            // The right way to do it. Forks off one task and
+            // continues the other task in this thread. I've
+            // seen up to 8x speed up on 16-way Intel and 32-way
+            // SPARC boxes (which probably matches the actual number
+            // of cores they have, as opposed to the number of threads)
+            t2.fork();
+            results = new ArrayList<>(t1.compute());
+            results.addAll(t2.join());
+
+            return results;
+        }
+
+        FactoringTask(long low, long high) {
+            this.low = low;
+            this.high = high;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Lambda.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t10000;
+
+import org.openjdk.bench.java.util.stream.tasks.PrimesFilter.PrimesProblem;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Lambda {
+
+    private final long RANGE_START  = 1000_000_000_000_000L;
+    private final long RANGE_END = RANGE_START + 100;
+
+    @Benchmark
+    public List<Long> bulk_seq_lambda() {
+        return LongStream.range(RANGE_START, RANGE_END).boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_seq_methodRef() {
+        return LongStream.range(RANGE_START, RANGE_END).boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_par_lambda() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_par_methodRef() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_parseq_lambda() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(n -> PrimesProblem.isPrime(n)).sequential().collect(Collectors.<Long>toList());
+    }
+
+    @Benchmark
+    public List<Long> bulk_parseq_methodRef() {
+        return LongStream.range(RANGE_START, RANGE_END).parallel().boxed().filter(PrimesProblem::isPrime).sequential().collect(Collectors.<Long>toList());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesFilter/t10000/Xtras.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesFilter.t10000;
+
+/**
+ * This benchmark evaluates find all prime numbers in a range.
+ *
+ * filter()...into() actions are benchmarked.
+ */
+public class Xtras {
+
+    private final long RANGE_START  = 1000_000_000_000_000L;
+    private final long RANGE_END = RANGE_START + 100;
+
+    /** No code yet **/
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesSieve/Bulk.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesSieve;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Arrays;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+import java.util.function.Predicate;
+
+/**
+ * Bulk scenario: filter out candidate primes.
+ *
+ * This test covers bulk infrastructure only. Refer to other tests for lambda-specific cases.
+ */
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Benchmark)
+public class Bulk {
+
+    private PrimesSieveProblem problem;
+
+    @Setup(Level.Trial)
+    public void populateData(){
+        problem = new PrimesSieveProblem();
+    }
+
+    @Benchmark
+    public int hm_seq() {
+        int max = Integer.MIN_VALUE;
+        for (int d : problem.get()) {
+            if (PrimesSieveProblem.isNotDivisible(d, 2)
+                    && PrimesSieveProblem.isNotDivisible(d, 3)
+                    && PrimesSieveProblem.isNotDivisible(d, 5)
+                    && PrimesSieveProblem.isNotDivisible(d, 7)
+                    && PrimesSieveProblem.isNotDivisible(d, 11)
+                    && PrimesSieveProblem.isNotDivisible(d, 13)
+                    && PrimesSieveProblem.isNotDivisible(d, 17)
+                    && PrimesSieveProblem.isNotDivisible(d, 19)
+                ) {
+                if (d > max) {
+                    max = d;
+                }
+            }
+        }
+        return max;
+    }
+
+    @Benchmark
+    public int hm_par() {
+        return new FilterTask(problem.get()).invoke();
+    }
+
+    @Benchmark
+    public int bulk_seq_inner() {
+        return Arrays.stream(problem.get())
+                .filter(new FilterOp(2))
+                .filter(new FilterOp(3))
+                .filter(new FilterOp(5))
+                .filter(new FilterOp(7))
+                .filter(new FilterOp(11))
+                .filter(new FilterOp(13))
+                .filter(new FilterOp(17))
+                .filter(new FilterOp(19))
+                .reduce(Integer.MIN_VALUE, new ReduceOp());
+    }
+
+    @Benchmark
+    public int bulk_par_inner() {
+        return Arrays.stream(problem.get()).parallel()
+                .filter(new FilterOp(2))
+                .filter(new FilterOp(3))
+                .filter(new FilterOp(5))
+                .filter(new FilterOp(7))
+                .filter(new FilterOp(11))
+                .filter(new FilterOp(13))
+                .filter(new FilterOp(17))
+                .filter(new FilterOp(19))
+                .reduce(Integer.MIN_VALUE, new ReduceOp());
+    }
+
+    static class FilterOp implements Predicate<Integer> {
+        private final int divisor;
+
+        public FilterOp(int divisor) {
+            this.divisor = divisor;
+        }
+
+        @Override
+        public boolean test(Integer value) {
+            return PrimesSieveProblem.isNotDivisible(value, divisor);
+        }
+    }
+
+    static class ReduceOp implements BinaryOperator<Integer> {
+        @Override
+        public Integer apply(Integer left, Integer right) {
+            return (left > right) ? left : right;
+        }
+    }
+
+    static class FilterTask extends RecursiveTask<Integer> {
+        private static final int FORK_LIMIT = 1000;
+        final Integer[] data;
+        final int start, end;
+
+        FilterTask(Integer[] data) {
+            this(data, 0, data.length);
+        }
+
+        FilterTask(Integer[] data, int start, int end) {
+            this.data = data;
+            this.start = start;
+            this.end = end;
+        }
+
+        @Override
+        protected Integer compute() {
+            int size = end - start;
+            if (size > FORK_LIMIT) {
+                int mid = start + size / 2;
+                FilterTask t1 = new FilterTask(data, start, mid);
+                FilterTask t2 = new FilterTask(data, mid, end);
+                t1.fork();
+                Integer r1 = t2.invoke();
+                Integer r2 = t1.join();
+                return (r1 > r2) ? r1 : r2;
+            } else {
+                int max = Integer.MIN_VALUE;
+                for (int i = start; i < end; i++) {
+                    int d = data[i];
+                    if (PrimesSieveProblem.isNotDivisible(d, 2)
+                            && PrimesSieveProblem.isNotDivisible(d, 3)
+                            && PrimesSieveProblem.isNotDivisible(d, 5)
+                            && PrimesSieveProblem.isNotDivisible(d, 7)
+                            && PrimesSieveProblem.isNotDivisible(d, 11)
+                            && PrimesSieveProblem.isNotDivisible(d, 13)
+                            && PrimesSieveProblem.isNotDivisible(d, 17)
+                            && PrimesSieveProblem.isNotDivisible(d, 19)
+                            ) {
+                        if (d > max) {
+                            max = d;
+                        }
+                    }
+                }
+                return max;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/PrimesSieve/PrimesSieveProblem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.java.util.stream.tasks.PrimesSieve;
+
+public class PrimesSieveProblem {
+
+    private static final int DATA_SIZE = Integer.getInteger("bench.problemSize", 10*1024);
+
+    private final Integer[] data = new Integer[DATA_SIZE];
+
+    public PrimesSieveProblem() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = i;
+        }
+    }
+
+    public Integer[] get() {
+        return data;
+    }
+
+    public static boolean isNotDivisible(int i, int d) {
+        return (i % d) != 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/util/stream/tasks/README	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,55 @@
+Copyright (c) 2014, 2014, 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.
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+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.
+
+=======================================================================
+
+The tests are divided by scenario.
+
+Each scenario has the problem it tries to solve, and it does that with several options:
+  - BulkBench only compares handmade solutions vs. JDK bulk operations, without resorting to lambdas/methodrefs
+  - LambdaBench does bulk operations with lambdas/methodrefs
+  - XtrasBench has some other interesting options
+
+All tests in these benchmarks follow the following naming convention.
+Test names is the concatenation of several markers:
+
+{hm|bulk}: infrastructure used
+  - hm: "handmade" version which users would presumably implement otherwise
+  - bulk: JDK8-ish bulk operation
+
+{seq|par}: parallelism mode
+  - seq: sequential mode
+  - par: parallel mode; in "hm" case, this might have different implementations
+
+{.|inner|lambda|mref}: functional interface type
+  - .: no specific meaning
+  - inner: explicit inner class
+  - lambda: JDK8-ish lambda
+  - mref: JDK8-ish method ref
+
+E.g. bulk_seq_inner is the test harnesses JDK8 bulk operations in sequential mode, and explicit inner class as function
+
+All benchmarks should be executed in the following modes (see -t harness cmdline option):
+ - single mode (thread = 1),
+ - core mode   (thread = number of cores),
+ - max mode    (thread = number of HW threads).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/AES.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.crypto;
+
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AES {
+
+    @Param("10000000")
+    private int count;
+
+    private Cipher cipher;
+    private byte[] src;
+
+    @Setup
+    public void setup() throws Exception {
+        SecretKeySpec keySpec = new SecretKeySpec(new byte[]{-80, -103, -1, 68, -29, -94, 61, -52, 93, -59, -128, 105, 110, 88, 44, 105}, "AES");
+        IvParameterSpec iv = new IvParameterSpec(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+
+        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+
+        src = new byte[count];
+        new Random(1).nextBytes(src);
+    }
+
+    @Benchmark
+    @Fork(jvmArgsAppend = {"-XX:+UnlockDiagnosticVMOptions", "-XX:-UseAES", "-XX:-UseAESIntrinsics"})
+    public byte[] testBaseline() throws Exception {
+        return cipher.doFinal(src);
+    }
+
+    @Benchmark
+    @Fork(jvmArgsAppend = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+UseAES", "-XX:-UseAESIntrinsics"})
+    public byte[] testUseAes() throws Exception {
+        return cipher.doFinal(src);
+    }
+
+    @Benchmark
+    @Fork(jvmArgsAppend = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+UseAES", "-XX:+UseAESIntrinsics"})
+    public byte[] testUseAesIntrinsics() throws Exception {
+        return cipher.doFinal(src);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/Crypto.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.crypto;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Tests various encryption algorithms with the JCE framework. Sets Fork
+ * parameters as these tests are rather allocation intensive. Reduced numbers of
+ * forks and iteration as benchmarks are stable.
+ */
+@State(Scope.Thread)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 10)
+@Fork(jvmArgsAppend = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 5)
+public class Crypto {
+
+    @Param({"64", "1024", "16384"})
+    private int length;
+
+    @Param({"AES", "Blowfish", "DES", "DESede"})
+    private String cipherName;
+
+    private SecretKeySpec secretKey;
+    private Cipher encryptCipher;
+    private Cipher decryptCipher;
+    private byte[] plainBytes;
+    private byte[] encryptedBytes;
+
+    @Setup
+    public void setupSubclass() throws NoSuchAlgorithmException, NoSuchPaddingException,
+            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+
+        // Setup ciphers for encrypt/decrypt
+        byte[] encodedKey = KeyGenerator.getInstance(cipherName).generateKey().getEncoded();
+        secretKey = new SecretKeySpec(encodedKey, cipherName);
+
+        encryptCipher = Cipher.getInstance(cipherName);
+        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+        decryptCipher = Cipher.getInstance(cipherName);
+        decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
+
+        // Generate data to encrypt/decrypt
+        plainBytes = new byte[length];
+        new Random(1234567890).nextBytes(plainBytes);
+        encryptedBytes = encryptCipher.doFinal(plainBytes);
+    }
+
+    /**
+     * Encrypt byte array
+     *
+     * @return encrypted byte array
+     * @throws javax.crypto.IllegalBlockSizeException
+     * @throws javax.crypto.BadPaddingException
+     */
+    @Benchmark
+    public byte[] encrypt() throws IllegalBlockSizeException, BadPaddingException {
+        return encryptCipher.doFinal(plainBytes);
+    }
+
+    /**
+     * Decrypt byte array
+     *
+     * @return decrypted byte array
+     * @throws javax.crypto.IllegalBlockSizeException
+     * @throws javax.crypto.BadPaddingException
+     */
+    @Benchmark
+    public byte[] decrypt() throws IllegalBlockSizeException, BadPaddingException {
+        return decryptCipher.doFinal(encryptedBytes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/tools/Javac.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.tools;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import javax.tools.JavaCompiler;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+public class Javac {
+    private List<JavaSourceFromString> compilationUnits;
+    private JavaCompiler compiler;
+    private StandardJavaFileManager fileManager;
+
+    @Setup
+    public void prepare() {
+        String helloWorld = "class Apan {   \n" + "  public static void main(String args[]) {\n"
+                + "     System.out.println(\"hej apa\");\n" + "  }\n" + "}\n";
+
+        compiler = ToolProvider.getSystemJavaCompiler();
+        fileManager = compiler.getStandardFileManager(null, null, null);
+        compilationUnits = new ArrayList<>();
+        compilationUnits.add(new JavaSourceFromString("Apan", helloWorld));
+    }
+
+    @Benchmark
+    public Boolean testCompile() throws Exception {
+        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
+        return task.call();
+    }
+
+    private static class JavaSourceFromString extends SimpleJavaFileObject {
+        final String code;
+
+        JavaSourceFromString(String name, String code) {
+            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
+                    Kind.SOURCE);
+            this.code = code;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return code;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Abstract base class with functionality and constants used by the XML micros.
+ */
+@State(Scope.Benchmark)
+public abstract class AbstractXMLMicro {
+
+  public static final String BUILDIMPL = "build-impl.xml";
+  public static final String LOGCOMP = "log_comp.xml";
+  public static final String MESSAGE12 = "message_12.xml";
+  public static final String MSGATTACH = "msgAttach.xml";
+  public static final String REZ = "reZ003vExc23082309.xml";
+
+  protected static final ConcurrentHashMap<String, byte[]> byteCache = new ConcurrentHashMap<>();
+
+  @Param({BUILDIMPL,LOGCOMP,MESSAGE12,MSGATTACH,REZ})
+  protected String doc;
+
+  /**
+   * Gets a given InputStream as a byte-array.
+   *
+   * @param is stream to read from
+   * @return byte-array
+   * @throws IOException if things go crazy-crazy
+   */
+  private static byte[] getBytes(InputStream is) throws IOException {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    byte[] b = new byte[1024];
+
+    int available = is.available();
+    while (available > 0) {
+      int read = Math.min(b.length, available);
+
+      int actuallyRead = is.read(b, 0, read);
+      baos.write(b, 0, actuallyRead);
+
+      available = is.available();
+    }
+
+    is.close();
+    byte array[] = baos.toByteArray();
+    baos.close();
+
+    return array;
+  }
+
+  /**
+   * Gets a given resource as a byte-array.
+   *
+   * @param name resource to fetch
+   * @return byte-array
+   * @throws IOException if things go crazy-crazy
+   * @throws URISyntaxException if resource given doesn't match syntax
+   */
+  protected byte[] getFileBytesFromResource(String name) throws IOException, URISyntaxException {
+    byte[] bytes = byteCache.get(name);
+    if (bytes == null) {
+      bytes = getBytes(this.getClass().getResourceAsStream("/"
+              + AbstractXMLMicro.class.getPackage().getName().replace(".", "/")
+              + "/" + name));
+      byteCache.put(name, bytes);
+    }
+    return bytes;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/DOM.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+public class DOM extends AbstractXMLMicro {
+
+    @Benchmark
+    public Document testBuild() throws Exception {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        byte[] bytes = getFileBytesFromResource(doc);
+        InputSource source = new InputSource();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+        source.setByteStream(bais);
+        return buildDocument(dbf, source);
+    }
+
+    @Benchmark
+    public Document testModify() throws Exception {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        byte[] bytes = getFileBytesFromResource(doc);
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        InputSource source = new InputSource(bais);
+        Document doc1 = buildDocument(dbf, source);
+
+        modifyElementRecursive(doc1.getDocumentElement());
+        return doc1;
+    }
+
+    @Benchmark
+    public Document testWalk() throws Exception {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        byte[] bytes = getFileBytesFromResource(doc);
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        InputSource source = new InputSource(bais);
+        Document doc1 = buildDocument(dbf, source);
+
+        walkElementRecursive(doc1.getDocumentElement());
+        return doc1;
+    }
+
+    private Document buildDocument(DocumentBuilderFactory dbf, InputSource source)
+            throws ParserConfigurationException, SAXException, IOException {
+        dbf.setValidating(false);
+        dbf.setNamespaceAware(true);
+        DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+        return docBuilder.parse(source);
+    }
+
+    // TODO Fix so it isn't recursive?
+    private static void walkElementRecursive(Element element) {
+        // loop through children
+        if (element.hasChildNodes()) {
+            Node child = element.getFirstChild();
+            while (child != null) {
+
+                // handle child by type
+                int type = child.getNodeType();
+                if (type == Node.ELEMENT_NODE) {
+                    walkElementRecursive((Element) child);
+                }
+                child = child.getNextSibling();
+            }
+        }
+    }
+
+    // TODO Fix so it isn't recursive?
+    private void modifyElementRecursive(Element element) {
+
+        // check for children present
+        if (element.hasChildNodes()) {
+
+            // loop through child nodes
+            boolean content = false;
+
+            // Should not be null since we already have made a .hasChildNodes()
+            // check.
+            Node child = element.getFirstChild();
+
+            do {
+                // Handle child by node type.
+                if (child.getNodeType() == Node.TEXT_NODE) {
+                    String trimmed = child.getNodeValue().trim();
+                    if (trimmed.length() == 0) {
+                        // delete child if nothing but whitespace
+                        element.removeChild(child);
+                    } else {
+                        // make sure we have the parent element information
+                        content = true;
+                        Document doc = element.getOwnerDocument();
+                        String uri = element.getNamespaceURI();
+                        String prefix = element.getPrefix();
+                        content = true;
+
+                        // Create a "text" element matching parent namespace.
+                        Element text = (uri == null) ? doc.createElement("text") : doc.createElementNS(uri, prefix
+                                + ":text");
+
+                        // wrap the trimmed content with new element
+                        text.appendChild(doc.createTextNode(trimmed));
+                        element.replaceChild(text, child);
+
+                    }
+                } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    modifyElementRecursive((Element) child);
+                }
+
+            } while ((child = child.getNextSibling()) != null);
+
+            // check if we've seen any non-whitespace content for element
+            if (content) {
+                String prefix = element.getPrefix();
+                String uri = element.getNamespaceURI();
+                // add attribute flagging content found
+                if (prefix == null || prefix.length() == 0) {
+                    element.setAttribute("text", "true");
+                } else {
+                    element.setAttributeNS(uri, prefix + ":text", "true");
+                }
+
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/SAXUsingJDK.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Micro testing SAXParser performance using the JDK classes
+ */
+public class SAXUsingJDK extends AbstractXMLMicro {
+
+    @Benchmark
+    public XMLReader testParse() throws Exception {
+        SAXParserFactory spf = SAXParserFactory.newInstance();
+        byte[] bytes = getFileBytesFromResource(doc);
+        spf.setValidating(false);
+        SAXParser parser = spf.newSAXParser();
+        XMLReader reader = parser.getXMLReader();
+        InputSource source = new InputSource();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+        source.setByteStream(bais);
+        reader.parse(source);
+        return reader;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/xml/STAX.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.javax.xml;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.TearDown;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+import java.io.ByteArrayInputStream;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+public class STAX extends AbstractXMLMicro {
+
+    /** Live data */
+    public Map<String, LinkedList<String>> liveData;
+
+    @Setup(Level.Iteration)
+    public void setupLiveData() {
+        Map<String, LinkedList<String>> map = new HashMap<>();
+        // Somewhere around 100 MB live, but fragmented to start with.
+        for (int i = 0; i < 1000; i++) {
+            LinkedList<String> list = new LinkedList<>();
+            String key = "Dummy linked list " + i;
+            list.add(key);
+            for (int j = 0; j < 1000; j++) {
+                list.add("Dummy string " + i + "." + j);
+            }
+            map.put(key, list);
+        }
+        // thread safe, will only be one
+        liveData = map;
+    }
+
+    @TearDown(Level.Iteration)
+    public void teardownLiveData() {
+        liveData = null;
+    }
+
+    @Benchmark
+    public int testParse() throws Exception {
+        int intDummy = 0;
+        byte[] bytes = getFileBytesFromResource(doc);
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        XMLInputFactory factory = XMLInputFactory.newInstance();
+
+        XMLStreamReader parser = factory.createXMLStreamReader(bais);
+        int acc;
+        do {
+            acc = parser.next();
+            intDummy += acc;
+        } while (acc != XMLStreamConstants.END_DOCUMENT);
+        return intDummy;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayBoundCheckRemoval.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring the gain of removing array bound checks in various cases
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayBoundCheckRemoval {
+
+    private int[] a;
+    private int j, u, v;
+
+    @Setup
+    public void setup() {
+        a = new int[200];
+    }
+
+    @Benchmark
+    public int[] testForLoopAccess() throws Exception {
+        int[] a = this.a;
+        for (int i = 0; i < a.length; i++) {
+            a[i] = i;
+        }
+        return a;
+    }
+
+    @Benchmark
+    public int[] testBubblesortStripped() throws Exception {
+        int[] a = this.a;
+        int limit = a.length;
+        int st = -1;
+
+        while (st < limit) {
+            st++;
+            limit--;
+            for (j = st; j < limit; j++) {
+                u = a[j];
+                v = a[j + 1];
+            }
+        }
+        return a;
+    }
+
+    @Benchmark
+    public int[] testBubblesort() throws Exception {
+        int[] a = this.a;
+        int j1;
+        int limit = a.length;
+        int st = -1;
+        while (st < limit) {
+            boolean flipped = false;
+            st++;
+            limit--;
+            for (j1 = st; j1 < limit; j1++) {
+                if (a[j1] > a[j1 + 1]) {
+                    int T = a[j1];
+                    a[j1] = a[j1 + 1];
+                    a[j1 + 1] = T;
+                    flipped = true;
+                }
+            }
+            if (!flipped) {
+                return a;
+            }
+            flipped = false;
+            for (j1 = limit; --j1 >= st; ) {
+                if (a[j1] > a[j1 + 1]) {
+                    int T = a[j1];
+                    a[j1] = a[j1 + 1];
+                    a[j1 + 1] = T;
+                    flipped = true;
+                }
+            }
+            if (!flipped) {
+                return a;
+            }
+        }
+        return a;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayClear.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ArrayClear {
+
+    @Param("100000")
+    private int arraySize;
+
+    private int[] sourceIntArray;
+
+    @Setup
+    public void setupSubclass() {
+        sourceIntArray = new int[arraySize];
+        for (int i = 0; i < arraySize; i += 1) {
+            sourceIntArray[i] = i;
+        }
+    }
+
+    @Benchmark
+    public int[] testArrayClear() throws Exception {
+        int[] intArray = new int[arraySize];
+        System.arraycopy(sourceIntArray, 0, intArray, 0, arraySize);
+        return intArray;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/ArrayStoreCheck.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Stack;
+import java.util.Vector;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmarking measuring ArrayStoreCheck-performance plus the ability of the optimizer to remove storechecks
+ * altogether.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@SuppressWarnings("rawtypes")
+@State(Scope.Thread)
+public class ArrayStoreCheck {
+
+    /** How large should the test-arrays be. */
+    public static final int TESTSIZE = 1000;
+
+    private Vector[] fromVectorArr, toVectorArr;
+
+    private Object[] fromObjectArr, toObjectArr;
+
+    private Object[] fromObject2Arr, toObject2Arr;
+
+    private Object[] fromObject3Arr, toObject3Arr;
+
+    private Object[] fromObject4Arr, toObject4Arr;
+
+    @Setup(Level.Iteration)
+    public void createArrays() {
+        fromVectorArr = new Vector[TESTSIZE];
+        toVectorArr = new Vector[TESTSIZE];
+
+        fromObjectArr = fromVectorArr;
+        toObjectArr = toVectorArr;
+
+        /* set every almost 90% of all indices to an object. */
+        for (int i = 0; i < TESTSIZE; i++) {
+            fromVectorArr[i] = new Vector();
+        }
+        for (int i = 0; i < TESTSIZE; i += 10) {
+            fromVectorArr[i] = null;
+        }
+
+        fromObject2Arr = new Vector[TESTSIZE][1][][][];
+        toObject2Arr = new Vector[TESTSIZE][1][][][];
+
+        fromObject3Arr = new Stack[TESTSIZE][1][][][];
+        toObject3Arr = new Vector[TESTSIZE][1][][][];
+
+        fromObject4Arr = new Object[TESTSIZE];
+        toObject4Arr = new Comparable[TESTSIZE];
+        /* set every two indices to an object. */
+        for (int i = 0; i < TESTSIZE; i += 2) {
+            fromObject4Arr[i] = new String("apa?");
+        }
+    }
+
+    /**
+     * Test that loads from an Vector[] and stores in another Vector[]. The local types of the arrays are both Vector[].
+     * Hopefully we only will do a runtime check that we are storing in an exact Vector[].
+     */
+    @Benchmark
+    public void testArrayStoreCheckRT1() throws Exception {
+        Vector[] localFromArray = fromVectorArr;
+        Vector[] localToArray = toVectorArr;
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            localToArray[i] = localFromArray[i];
+        }
+    }
+
+    /**
+     * Test that stores a newly created Vector in a Vector[]. The local type of the array is Vector[]. Hopefully we only
+     * will do a runtime check that we are storing in the same Vector[].
+     */
+    @Benchmark
+    public void testArrayStoreCheckRT2() throws Exception {
+        Vector[] localToArray = toVectorArr;
+        Vector localVector = new Vector();
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            localToArray[i] = localVector;
+        }
+    }
+
+    /**
+     * Test that loads from a Vector[] and stores in the same Vector[]. Hopefully we only will remove the storecheck
+     * altogether due to the fact that the arrays are the same (and easily proven that they are they same).
+     */
+    @Benchmark
+    public void testArrayStoreCheckRemove1() throws Exception {
+        Vector[] localToArray = toVectorArr;
+        for (int i = 2; i < TESTSIZE; i++) {
+            localToArray[i] = localToArray[i - 2];
+        }
+    }
+
+    /**
+     * Test that loads from a Vector[] and stores in another Vector[]. The local types of the arrays are both Object[].
+     * This should be a tricky case where we statically have no clue what type the arrays actually are of. We should have
+     * to do a complex check.
+     */
+    @Benchmark
+    public void testArrayStoreCheckComplex1() throws Exception {
+        Object[] localFromArray = fromObjectArr;
+        Object[] localToArray = toObjectArr;
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            localToArray[i] = localFromArray[i];
+        }
+    }
+
+    /**
+     * Test that loads from a Vector[][][][] and stores in another Vector[][][][]. The local types of the arrays are both
+     * Object[]. This should be a tricky case where we statically have no clue what type the arrays actually are of. We
+     * should have to do a complex check. Difference from complex1-test is that the actual types of the arrays are
+     * multi-dimensioned.
+     */
+    @Benchmark
+    public void testArrayStoreCheckComplex2() throws Exception {
+        Object[] localFromArray = fromObject2Arr;
+        Object[] localToArray = toObject2Arr;
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            localToArray[i] = localFromArray[i];
+        }
+    }
+
+    /**
+     * Test that loads from a Stack[][][][] and stores in a Vector[][][][]. The local types of the arrays are both
+     * Object[]. This should be a tricky case where we statically have no clue what type the arrays actually are of. We
+     * should have to do a complex check. Difference from complex2-test is that the actual types of the from-array is
+     * different from the actual type of the to-array.
+     */
+    @Benchmark
+    public void testArrayStoreCheckComplex3() throws Exception {
+        Object[] localFromArray = fromObject3Arr;
+        Object[] localToArray = toObject3Arr;
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            localToArray[i] = localFromArray[i];
+        }
+    }
+
+    /**
+     * Test that loads from a Object[] and stores in a Comparable[]. The local types of the arrays are both Object[]. This
+     * should be a tricky case where we statically have no clue what type the arrays actually are of. We should have to do
+     * a complex check. The interesting part with this test is that the destination array is an interface array.
+     */
+    @Benchmark
+    public void testArrayStoreCheckComplex4() throws Exception {
+        Object[] localFromArray = fromObject4Arr;
+        Object[] localToArray = toObject4Arr;
+
+        for (int i = 0; i < TESTSIZE; i++) {
+            localToArray[i] = localFromArray[i];
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/CopyLoop.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring effect of loop optimizations.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class CopyLoop {
+
+    private MyString s;
+    private Buf b;
+
+    @Setup
+    public void setup() {
+        s = new MyString("foobarba");
+        b = new Buf();
+    }
+
+    /**
+     * Basic implementation, as a Java programmer would write it.
+     */
+    @Benchmark
+    public void testCharAtLoop() throws Exception {
+        for (int i = 0; i < s.length(); i++) {
+            int c = s.charAt(i);
+            b.byteBuf[i] = (byte) c;
+        }
+    }
+
+    /** Inline charAt and remove the redundant bounds checks. */
+    @Benchmark
+    public void testInlineCharAtLoop() throws Exception {
+        for (int i = 0; i < s.count; i++) {
+            int c = s.value[i + s.offset];
+            b.byteBuf[i] = (byte) c;
+        }
+    }
+
+    /**
+     * Unroll the loop (I cheat here because I know that the String will always be an even length, real implementation
+     * would require a pre-loop).
+     */
+    @Benchmark
+    public void testInlineAndUnrollCharAtLoop() throws Exception {
+        int startI = 0;
+        if ((s.count & 0xFFFE) != s.count) {
+            int c = s.value[s.offset];
+            b.byteBuf[0] = (byte) c;
+            startI = 1;
+        }
+        for (int i = startI; i < s.count - 1; i += 2) {
+            int c = s.value[i + s.offset];
+            int d = s.value[i + s.offset + 1];
+            b.byteBuf[i] = (byte) c;
+            b.byteBuf[i + 1] = (byte) d;
+        }
+    }
+
+    /** Hoist computation of constants outside of the loop. */
+    @Benchmark
+    public void testInlineAndUnrollAndHoistCharAtLoop() throws Exception {
+        byte[] byteBuf = b.byteBuf;
+        if (byteBuf == null) {
+            throw new NullPointerException();
+        }
+        char[] value = s.value;
+        int offset = s.offset;
+
+        int startI = offset;
+
+        if ((s.count & 0xFFFE) != s.count) {
+            int c = value[offset];
+            byteBuf[0] = (byte) c;
+            startI++;
+        }
+
+        int maxI = s.count + offset - 1;
+        for (int i = startI; i < maxI; i += 2) {
+            int c = value[i];
+            int d = value[i + 1];
+            byteBuf[i] = (byte) c;
+            byteBuf[i + 1] = (byte) d;
+        }
+    }
+
+    private static class Buf {
+        private byte[] byteBuf = new byte[100];
+    }
+
+    public static final class MyString {
+        private char value[];
+
+        private int offset;
+
+        private int count;
+
+        public MyString(String original) {
+            value = original.toCharArray();
+            offset = 0;
+            count = value.length;
+        }
+
+        public int length() {
+            return count;
+        }
+
+        public char charAt(int index) {
+            if ((index < 0) || (index >= count)) {
+                throw new StringIndexOutOfBoundsException(index);
+            }
+            return value[index + offset];
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/DivRem.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests speed of division and remainder calculations.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class DivRem {
+
+    private static final int ARRAYSIZE = 500;
+
+    /* instance fields for the constant int division tests. */
+    public int[] intValues, intValues2;
+
+    /* instance fields for the constant long division tests. */
+    public long[] longValues, longValues2;
+
+    /* instance fields for the tests using the testdr-method. */
+    public long[] drLongValues1, drLongValues2;
+
+    public long[] drLongValuesAsInts1, drLongValuesAsInts2;
+
+    @Setup
+    public void setupSubclass() {
+        Random r = new Random(4711);
+
+        intValues = new int[ARRAYSIZE];
+        intValues2 = new int[ARRAYSIZE];
+        longValues = new long[ARRAYSIZE];
+        longValues2 = new long[ARRAYSIZE];
+
+        for (int i = 0; i < ARRAYSIZE; i++) {
+            intValues[i] = r.nextInt();
+            if (intValues[i] == 0) {
+                intValues[i] = 5353;
+            }
+            intValues2[i] = r.nextInt();
+
+            longValues[i] = r.nextLong();
+            if (longValues[i] == 0) {
+                longValues[i] = 5353L;
+            }
+            longValues2[i] = r.nextLong();
+        }
+
+        /* generate random longs for 32-64 tests */
+
+        drLongValues1 = new long[ARRAYSIZE];
+        drLongValues2 = new long[ARRAYSIZE];
+        drLongValuesAsInts1 = new long[ARRAYSIZE];
+        drLongValuesAsInts2 = new long[ARRAYSIZE];
+        for (int i = 0; i < ARRAYSIZE; i++) {
+            long l = r.nextLong();
+            if (l == 0L) {
+                l++;
+            }
+            drLongValues1[i] = l;
+            drLongValuesAsInts1[i] = (long) (int) l;
+            l = r.nextLong();
+            if (l == 0L) {
+                l++;
+            }
+            drLongValues2[i] = l;
+            drLongValuesAsInts2[i] = (long) (int) l;
+        }
+    }
+
+    /**
+     * Tests integer division with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to
+     * a multiplication instead.
+     */
+    @Benchmark
+    public int testIntDivConstantDivisor() {
+        int dummy = 0;
+        for (int i = 0; i < intValues.length; i++) {
+            dummy += intValues[i] / 49;
+        }
+        return dummy;
+    }
+
+    /**
+     * Tests long division with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to a
+     * multiplication instead.
+     */
+    @Benchmark
+    public long testLongDivConstantDivisor() {
+        long dummy = 0;
+        for (int i = 0; i < longValues.length; i++) {
+            dummy += longValues[i] / 49L + longValues[i] / 0x4949494949L;
+        }
+        return dummy;
+    }
+
+    /**
+     * Tests integer remainder with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to
+     * two multiplications instead.
+     */
+    @Benchmark
+    public int testIntRemConstantDivisor() {
+        int dummy = 0;
+        for (int i = 0; i < intValues.length; i++) {
+            dummy += intValues[i] % 49;
+        }
+        return dummy;
+    }
+
+    /**
+     * Tests long division with a constant divisor. Hopefully the JVM will do a Granlund-Montgomery and convert it to a
+     * multiplication instead.
+     */
+    @Benchmark
+    public long testLongRemConstantDivisor() {
+        long dummy = 0;
+        for (int i = 0; i < longValues.length; i++) {
+            dummy += longValues[i] % 49L + longValues[i] % 0x4949494949L;
+        }
+        return dummy;
+    }
+
+    /**
+     * Tests integer division with a variable divisor. This benchmark is mainly here to be a comparison against the
+     * benchmark that performs both divisions and remainder calculations.
+     */
+    @Benchmark
+    public int testIntDivVariableDivisor() {
+        int dummy = 0;
+        for (int i = 0; i < intValues.length; i++) {
+            dummy += intValues2[i] / intValues[i];
+        }
+        return dummy;
+    }
+
+    /**
+     * Tests integer division and remainder with a variable divisor. Both calculations are performed with the same
+     * divisor, so a JVM should not have to perform two complex calculations. Either a division followed by a
+     * multiplication, or on X86 using idiv, where the reminder is also returned from the idiv instruction.
+     */
+    @Benchmark
+    public int testIntDivRemVariableDivisor() {
+        int dummy = 0;
+        for (int i = 0; i < intValues.length; i++) {
+            dummy += intValues2[i] / intValues[i];
+            dummy += intValues2[i] % intValues[i];
+        }
+        return dummy;
+    }
+
+    @Benchmark
+    public long test64DivRem64() {
+        long dummy = 0;
+        for (int i = 0; i < drLongValues1.length; i++) {
+            long l1 = drLongValues1[i];
+            long l2 = drLongValues2[i];
+            dummy += l1 / l2;
+            dummy += l1 % l2;
+        }
+        return dummy;
+    }
+
+    @Benchmark
+    public long test32DivRem32() {
+        long dummy = 0;
+        for (int i = 0; i < drLongValuesAsInts1.length; i++) {
+            long l1 = drLongValuesAsInts1[i];
+            long l2 = drLongValuesAsInts2[i];
+            dummy += l1 / l2;
+            dummy += l1 % l2;
+        }
+        return dummy;
+    }
+
+    @Benchmark
+    public long test64DivRem32() {
+        long dummy = 0;
+        for (int i = 0; i < drLongValues1.length; i++) {
+            long l1 = drLongValues1[i];
+            long l2 = drLongValuesAsInts2[i];
+            dummy += l1 / l2;
+            dummy += l1 % l2;
+        }
+        return dummy;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/Explosion.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests that the JVM performs object explosion (or some sort of stack allocation).
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Explosion {
+
+    @Param("5")
+    private int len;
+
+    @Benchmark
+    public void testHashtableExplosion(Blackhole bh) throws Exception {
+        Object o = new Object();
+        Object[] oa = new Object[len];
+        for (int i = 0; i < len; i++) {
+            oa[i] = new Object();
+        }
+
+        Hashtable<Object, Object> h = new Hashtable<>();
+
+        for (int i = 0; i < len; i++) {
+            h.put(oa[i], o);
+        }
+
+        Enumeration<Object> e = h.elements();
+        while (e.hasMoreElements()) {
+            bh.consume(e.nextElement());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/InnerClassNullRef.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class InnerClassNullRef {
+
+    class Pickles {
+        int count;
+
+        public Pickles(int x) {
+            count = x;
+        }
+
+        public int getCount() {
+            return count;
+        }
+
+        public void setCount(int x) {
+            count = x;
+        }
+    }
+
+    class BurgerStand {
+        public void makeBurgers() {
+            if (pickles != null) {
+                // add a pickle
+                pickles.setCount(pickles.getCount() - 1);
+            }
+        }
+    }
+
+    class BurgerStandNull {
+        public void makeBurgers() {
+            if (picklesNull != null) {
+                // add a pickle
+                picklesNull.setCount(picklesNull.getCount() - 1);
+            }
+        }
+    }
+
+    private BurgerStand bs;
+    private BurgerStandNull bsNull;
+    private Pickles pickles;
+    private Pickles picklesNull;
+
+    @Setup
+    public void setup() {
+        bs = new BurgerStand();
+        bsNull = new BurgerStandNull();
+        pickles = new Pickles(42);
+    }
+
+    @Benchmark
+    public void refIsNull() {
+        bsNull.makeBurgers();
+    }
+
+    @Benchmark
+    public void refIsNotNull() {
+        bs.makeBurgers();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/InterfaceCalls.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class InterfaceCalls {
+
+    interface AnInterface {
+        public int getInt();
+    }
+
+    interface SecondInterface {
+        public int get1();
+    }
+
+    interface OnlyHasOneImplInterface {
+        public int getLong();
+    }
+
+    interface AloneInterface {
+        public int getNumber();
+    }
+
+    class SingleImplementor implements OnlyHasOneImplInterface {
+        public int getLong() {
+            return 1;
+        }
+    }
+
+    class Extender1 extends SingleImplementor {
+    }
+
+    class FirstClass implements AnInterface {
+        public int getInt() {
+            return 1;
+        }
+    }
+
+    class SecondClass implements AnInterface {
+        public int getInt() {
+            return 2;
+        }
+    }
+
+    class ThirdClass implements AnInterface {
+        public int getInt() {
+            return -3;
+        }
+    }
+
+    class FourthClass implements AnInterface {
+        public int getInt() {
+            return -4;
+        }
+    }
+
+    class FifthClass implements AnInterface {
+        public int getInt() {
+            return -5;
+        }
+    }
+
+    class MultiClass1 implements AnInterface, SecondInterface {
+        public int get1() {
+            return 1;
+        }
+
+        public int getInt() {
+            return 2;
+        }
+    }
+
+    class MultiClass2 implements AnInterface, SecondInterface {
+        public int get1() {
+            return -1;
+        }
+
+        public int getInt() {
+            return -2;
+        }
+    }
+
+    class Aloner implements AloneInterface {
+        public int getNumber() {
+            return 7;
+        }
+    }
+
+    public Object dummy1;
+
+    public Object dummy2;
+
+    public Object dummy3;
+
+    public AnInterface multi1a, multi2a;
+
+    public SecondInterface multi1b, multi2b;
+
+    public Object multic, multic2;
+
+    public AnInterface[] as = new AnInterface[5];
+
+    public AnInterface multi;
+
+    public OnlyHasOneImplInterface single1;
+
+    public OnlyHasOneImplInterface single2;
+
+    public AloneInterface alone;
+
+    int count;
+
+    @Setup
+    public void setupSubclass() {
+        dummy1 = new FirstClass();
+        dummy2 = new SecondClass();
+        dummy3 = new ThirdClass();
+        as[0] = new FirstClass();
+        as[1] = new SecondClass();
+        as[2] = new ThirdClass();
+        as[3] = new FourthClass();
+        as[4] = new FifthClass();
+        MultiClass1 mc1 = new MultiClass1();
+        multi1a = mc1;
+        multi1b = mc1;
+        multic = mc1;
+        MultiClass2 mc2 = new MultiClass2();
+        multi2a = mc2;
+        multi2b = mc2;
+        multic2 = mc2;
+        single1 = new SingleImplementor();
+        single2 = new Extender1();
+        alone = new Aloner();
+    }
+
+    private void swapMultiParts() {
+        AnInterface tmpa = multi1a;
+        SecondInterface tmpb = multi1b;
+        multi1a = multi2a;
+        multi2a = tmpa;
+        multi1b = multi2b;
+        multi2b = tmpb;
+    }
+
+    @SuppressWarnings("unused")
+    private void swapMulti() {
+        Object tmp = multic;
+        multic = multic2;
+        multic2 = tmp;
+    }
+
+    /**
+     * Tests a call where there are multiple implementors but only one of the implementors is every used here so the
+     * call-site is monomorphic
+     */
+    @Benchmark
+    public int testMonomorphic() {
+        return as[0].getInt();
+    }
+
+    /** Tests a interface call that only has one single implementation */
+    @Benchmark
+    public int testSingle() {
+        return alone.getNumber();
+    }
+
+    /**
+     * Tests a call where there is a single implementation but multiple classes that inherit that implementation and both
+     * these implementors are used.
+     */
+    @Benchmark
+    public int testSingle2() {
+        OnlyHasOneImplInterface oi;
+        if ((count & 1) == 0) {
+            oi = single1;
+        } else {
+            oi = single2;
+        }
+        count++;
+        return oi.getLong();
+    }
+
+    /**
+     * Tests calling two different interface methods in two different interfaces on the same receiver. Make sure to switch
+     * between two different types of receivers to achieve polymorhpism
+     */
+    @Benchmark
+    public void testCall2Poly2(Blackhole bh) {
+        bh.consume(multi1a.getInt());
+        bh.consume(multi1b.get1());
+        swapMultiParts();
+    }
+
+    @Benchmark
+    public int testCallMulti1Poly2NoSwap() {
+        return multi1a.getInt();
+    }
+
+    /**
+     * This test goes together with Multi2 below It tests if a class implements multiple interfaces if the different
+     * interfaces take different amounts of time (They do for hotspot)
+     */
+    @Benchmark
+    public int testCallMulti1Poly2() {
+        swapMultiParts();
+        return multi1a.getInt();
+    }
+
+    /**
+     * This test goes together with Multi2 below It tests if a class implements multiple interfaces if the different
+     * interfaces take different amounts of time (They do for hotspot)
+     */
+    @Benchmark
+    public int testCallMulti2Poly2() {
+        swapMultiParts();
+        return multi1b.get1();
+    }
+
+    /** Interface call with three different receivers */
+    @Benchmark
+    public void testCallPoly3(Blackhole bh) {
+        for (int kk = 0; kk < 3; kk++) {
+            bh.consume(as[kk].getInt());
+        }
+    }
+
+    /** Interface call with five different receivers. */
+    @Benchmark
+    public void testCallPoly5(Blackhole bh) {
+        for (int kk = 0; kk < 3; kk++) {
+            bh.consume(as[kk].getInt());
+        }
+    }
+
+    int l;
+
+    /**
+     * Interface call address computation within loop but the receiver preexists the loop and the ac can be moved outside
+     * of the loop
+     */
+    @Benchmark
+    public int testAC1() {
+        AnInterface ai = as[l];
+        l = 1 - l;
+        return ai.getInt();
+    }
+
+    /** Tests an interface cast followed by an interface call. */
+    @Benchmark
+    public int testInterfaceCastAndCall() throws Exception {
+        return ((AnInterface) dummy1).getInt() + ((AnInterface) dummy2).getInt()
+                + ((AnInterface) dummy3).getInt();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/Multiplication.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests speed of multiplication calculations with constants.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Multiplication {
+
+    @Param("500")
+    private int arraySize;
+
+    private long[] longArraySmall, longArrayBig;
+
+    @Setup
+    public void setupSubclass() {
+        longArraySmall = new long[arraySize];
+        longArrayBig = new long[arraySize];
+
+        /*
+         * small values always have higher 32 bits cleared. big values always
+         * have higher 32 bits set.
+         */
+        for (int i = 0; i < arraySize; i++) {
+            longArraySmall[i] = 100L * i + i;
+            longArrayBig[i] = ((100L * i + i) << 32) + 4543 + i * 4;
+        }
+    }
+
+    /* helper for small constant benchmarks. */
+    private static long smallConstantHelper(long[] values) {
+        long sum = 0;
+        for (long value : values) {
+            sum += value * 453543L;
+        }
+        return sum;
+    }
+
+    /* helper for big constant benchmarks. */
+    private static long bigConstantHelper(long[] values) {
+        long sum = 0;
+        for (long value : values) {
+            sum += value * 4554345533543L;
+        }
+        return sum;
+    }
+
+    /**
+     * Test multiplications of longs. One of the operands is a small constant and the other is a variable that always is
+     * small.
+     */
+    @Benchmark
+    public long testLongSmallVariableSmallConstantMul() {
+        return smallConstantHelper(longArraySmall);
+    }
+
+    /**
+     * Test multiplications of longs. One of the operands is a big constant and the other is a variable that always is
+     * small.
+     */
+    @Benchmark
+    public long testLongSmallVariableBigConstantMul() {
+        return bigConstantHelper(longArraySmall);
+    }
+
+    /**
+     * Test multiplications of longs. One of the operands is a small constant and the other is a variable that always is
+     * big.
+     */
+    @Benchmark
+    public long testLongBigVariableSmallConstantMul() {
+        return smallConstantHelper(longArrayBig);
+    }
+
+    /**
+     * Test multiplications of longs. One of the operands is a big constant and the other is a variable that always is
+     * big.
+     */
+    @Benchmark
+    public long testLongBigVariableBigConstantMul() {
+        return bigConstantHelper(longArrayBig);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/PostAllocationStores.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests how well the JVM can remove stores after allocation of objects.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class PostAllocationStores {
+
+    /** Tests allocation with explicit stores of null/zero to all fields. */
+    @Benchmark
+    public Object testAllocationWithNullStores() throws Exception {
+        return new TestWithNullStores();
+    }
+
+    /**
+     * Tests allocation with explicit stores of non-null/non-zero to all fields. This test exists as a complement to the
+     * one above.
+     */
+    @Benchmark
+    public Object testAllocationWithNonNullStores() throws Exception {
+        return new TestWithNonNullStores();
+    }
+
+    /** Tests allocation with explicit stores of null/zero to all fields, where all fields are volatile. */
+    @Benchmark
+    public Object testAllocationWithNullVolatileStores() throws Exception {
+        return new TestWithNullVolatileStores();
+    }
+
+    /** Tests allocation without any explicit stores to any fields. */
+    @Benchmark
+    public Object testAllocationWithoutStores() throws Exception {
+        return new TestWithoutStores();
+    }
+
+    static class TestWithNullStores {
+        Object objectField1;
+        Object objectField2;
+        Object objectField3;
+        int intField1;
+        int intField2;
+        long longField1;
+
+        public TestWithNullStores() {
+            objectField1 = null;
+            objectField2 = null;
+            objectField3 = null;
+            intField1 = 0;
+            intField2 = 0;
+            longField1 = 0L;
+        }
+    }
+
+    static class TestWithNonNullStores {
+        Object objectField1;
+        Object objectField2;
+        Object objectField3;
+        int intField1;
+        int intField2;
+        long longField1;
+
+        public TestWithNonNullStores() {
+            objectField1 = this;
+            objectField2 = this;
+            objectField3 = this;
+            intField1 = 4;
+            intField2 = 7;
+            longField1 = 2L;
+        }
+    }
+
+    static class TestWithNullVolatileStores {
+        volatile Object objectField1;
+        volatile Object objectField2;
+        volatile Object objectField3;
+        volatile int intField1;
+        volatile int intField2;
+        volatile long longField1;
+
+        public TestWithNullVolatileStores() {
+            objectField1 = null;
+            objectField2 = null;
+            objectField3 = null;
+            intField1 = 0;
+            intField2 = 0;
+            longField1 = 0L;
+        }
+    }
+
+    static class TestWithoutStores {
+        Object objectField1;
+        Object objectField2;
+        Object objectField3;
+        int intField1;
+        int intField2;
+        long longField1;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/SpillCode.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test spill code generation.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class SpillCode {
+
+    @Param("10")
+    private int iterations;
+
+    private int dummy;
+
+    private int doSomeCalcsInLargeBlockWithInts(int start, int iter) {
+
+        int a1, a2, a3, a4;
+        int b1, b2, b3, b4;
+        int c1, c2, c3, c4;
+        int d1, d2, d3, d4;
+        int e1, e2, e3, e4;
+        int f1, f2, f3, f4;
+        int g1, g2, g3, g4;
+        int h1, h2, h3, h4;
+
+        // a1 = b1 = c1 = d1 = e1 = f1 = g1 = h1 = (start % 2);
+        a2 = b2 = c2 = d2 = e2 = f2 = g2 = h2 = (start % 2);
+        a3 = b3 = c3 = d3 = e3 = f3 = g3 = h3 = (start % 4);
+        a4 = b4 = c4 = d4 = e4 = f4 = g4 = h4 = (start % 8);
+
+        for (int i = 0; i < iter; i++) {
+
+            // for each section, only x1 needs to survive.
+
+            // a1 = a2 = a3 = a4 = (start + a1) % 2;
+            a1 = start;
+            a1 = a1 + a2 + a3 + a4;
+            a2 = a1 + a2 + a3 + a4;
+            a3 = a1 + a2 + a3 + a4;
+            a4 = a1 + a2 + a3 + a4;
+            a1 = a1 + a2 + a3 + a4;
+            a2 = a1 + a2 + a3 + a4;
+            a3 = a1 + a2 + a3 + a4;
+            a4 = a1 + a2 + a3 + a4;
+            a1 = a1 + a2 + a3 + a4;
+            a2 = a1 + a2 + a3 + a4;
+            a3 = a1 + a2 + a3 + a4;
+            a4 = a1 + a2 + a3 + a4;
+
+            // b1 = b2 = b3 = b4 = (a4 + b1) % 2;
+            b1 = a4;
+            b1 = b1 + b2 + b3 + b4;
+            b2 = b1 + b2 + b3 + b4;
+            b3 = b1 + b2 + b3 + b4;
+            b4 = b1 + b2 + b3 + b4;
+            b1 = b1 + b2 + b3 + b4;
+            b2 = b1 + b2 + b3 + b4;
+            b3 = b1 + b2 + b3 + b4;
+            b4 = b1 + b2 + b3 + b4;
+            b1 = b1 + b2 + b3 + b4;
+            b2 = b1 + b2 + b3 + b4;
+            b3 = b1 + b2 + b3 + b4;
+            b4 = b1 + b2 + b3 + b4;
+
+            // c1 = c2 = c3 = c4 = (b4 + c1) % 2;
+            c1 = b4;
+            c1 = c1 + c2 + c3 + c4;
+            c2 = c1 + c2 + c3 + c4;
+            c3 = c1 + c2 + c3 + c4;
+            c4 = c1 + c2 + c3 + c4;
+            c1 = c1 + c2 + c3 + c4;
+            c2 = c1 + c2 + c3 + c4;
+            c3 = c1 + c2 + c3 + c4;
+            c4 = c1 + c2 + c3 + c4;
+            c1 = c1 + c2 + c3 + c4;
+            c2 = c1 + c2 + c3 + c4;
+            c3 = c1 + c2 + c3 + c4;
+            c4 = c1 + c2 + c3 + c4;
+
+            // d1 = d2 = d3 = d4 = (c4 + d1) % 2;
+            d1 = c4;
+            d1 = d1 + d2 + d3 + d4;
+            d2 = d1 + d2 + d3 + d4;
+            d3 = d1 + d2 + d3 + d4;
+            d4 = d1 + d2 + d3 + d4;
+            d1 = d1 + d2 + d3 + d4;
+            d2 = d1 + d2 + d3 + d4;
+            d3 = d1 + d2 + d3 + d4;
+            d4 = d1 + d2 + d3 + d4;
+            d1 = d1 + d2 + d3 + d4;
+            d2 = d1 + d2 + d3 + d4;
+            d3 = d1 + d2 + d3 + d4;
+            d4 = d1 + d2 + d3 + d4;
+
+            // e1 = e2 = e3 = e4 = (d4 + e1) % 2;
+            e1 = d4;
+            e1 = e1 + e2 + e3 + e4;
+            e2 = e1 + e2 + e3 + e4;
+            e3 = e1 + e2 + e3 + e4;
+            e4 = e1 + e2 + e3 + e4;
+            e1 = e1 + e2 + e3 + e4;
+            e2 = e1 + e2 + e3 + e4;
+            e3 = e1 + e2 + e3 + e4;
+            e4 = e1 + e2 + e3 + e4;
+            e1 = e1 + e2 + e3 + e4;
+            e2 = e1 + e2 + e3 + e4;
+            e3 = e1 + e2 + e3 + e4;
+            e4 = e1 + e2 + e3 + e4;
+
+            // f1 = f2 = f3 = f4 = (e4 + f1) % 2;
+            f1 = e4;
+            f1 = f1 + f2 + f3 + f4;
+            f2 = f1 + f2 + f3 + f4;
+            f3 = f1 + f2 + f3 + f4;
+            f4 = f1 + f2 + f3 + f4;
+            f1 = f1 + f2 + f3 + f4;
+            f2 = f1 + f2 + f3 + f4;
+            f3 = f1 + f2 + f3 + f4;
+            f4 = f1 + f2 + f3 + f4;
+            f1 = f1 + f2 + f3 + f4;
+            f2 = f1 + f2 + f3 + f4;
+            f3 = f1 + f2 + f3 + f4;
+            f4 = f1 + f2 + f3 + f4;
+
+            // g1 = g2 = g3 = g4 = (f4 + g1) % 2;
+            g1 = f4;
+            g1 = g1 + g2 + g3 + g4;
+            g2 = g1 + g2 + g3 + g4;
+            g3 = g1 + g2 + g3 + g4;
+            g4 = g1 + g2 + g3 + g4;
+            g1 = g1 + g2 + g3 + g4;
+            g2 = g1 + g2 + g3 + g4;
+            g3 = g1 + g2 + g3 + g4;
+            g4 = g1 + g2 + g3 + g4;
+            g1 = g1 + g2 + g3 + g4;
+            g2 = g1 + g2 + g3 + g4;
+            g3 = g1 + g2 + g3 + g4;
+            g4 = g1 + g2 + g3 + g4;
+
+            // h1 = h2 = h3 = h4 = (g4 + h1) % 2;
+            h1 = g4;
+            h1 = h1 + h2 + h3 + h4;
+            h2 = h1 + h2 + h3 + h4;
+            h3 = h1 + h2 + h3 + h4;
+            h4 = h1 + h2 + h3 + h4;
+            h1 = h1 + h2 + h3 + h4;
+            h2 = h1 + h2 + h3 + h4;
+            h3 = h1 + h2 + h3 + h4;
+            h4 = h1 + h2 + h3 + h4;
+            h1 = h1 + h2 + h3 + h4;
+            h2 = h1 + h2 + h3 + h4;
+            h3 = h1 + h2 + h3 + h4;
+            h4 = h1 + h2 + h3 + h4;
+
+            start = h4;
+        }
+
+        return start;
+    }
+
+    /**
+     * The test runs a loop with many local variables. The issue it reproduces is that if handled wrong, too many variables
+     * are put on and referenced on stack. The number of iterations is taken from global variable, to prevent static loop
+     * unrolling. Many of the variables used in the larger loop are local inside the block and do dnot need to survive from
+     * one iteration to the next.
+     */
+    @Benchmark
+    public int testSpillForManyInts() throws Exception {
+        return doSomeCalcsInLargeBlockWithInts(dummy, iterations);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/StoreAfterStore.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for removal of redundant stores. It's crucial for the tests to be valid that inlining and allocation is
+ * performed as described in this file.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class StoreAfterStore {
+    public int s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8;
+
+    /**
+     * Test removal of redundant zero stores following an object allocation.
+     */
+    @Benchmark
+    public AllocAndZeroStoreHelper testAllocAndZeroStore() throws Exception {
+        return new AllocAndZeroStoreHelper(s1, s2, s3, s4, s5, s6, s7, s8);
+    }
+
+    /**
+     * Test removal of stores followed by stores to the same memory location.
+     */
+    @Benchmark
+    public StoreAndStoreHelper testStoreAndStore() throws Exception {
+        return new StoreAndStoreHelper(s1, s2, s3, s4, s5, s6, s7, s8);
+    }
+
+
+    /**
+     * Helper for alloc followed by zero store testing.
+     */
+    static class AllocAndZeroStoreHelper {
+        public volatile int vf1, vf2, vf3, vf4, vf5, vf6, vf7, vf8;
+
+        public static int s1, s2, s3, s4, s5, s6, s7, s8;
+
+        private AllocAndZeroStoreHelper() {
+            this.vf1 = 0;
+            this.vf2 = 0;
+            this.vf3 = 0;
+            this.vf4 = 0;
+            this.vf5 = 0;
+            this.vf6 = 0;
+            this.vf7 = 0;
+            this.vf8 = 0;
+        }
+
+        private AllocAndZeroStoreHelper(int l1, int l2, int l3, int l4, int l5, int l6, int l7, int l8) {
+            this(); // Redundant initialization to zero here
+
+            // dummy stores
+            s1 = l1;
+            s2 = l2;
+            s3 = l3;
+            s4 = l4;
+            s5 = l5;
+            s6 = l6;
+            s7 = l7;
+            s8 = l8;
+        }
+
+    }
+
+    /**
+     * Helper for store made redundant by subsequent store testing.
+     */
+    static class StoreAndStoreHelper {
+        public volatile int vf1, vf2, vf3, vf4, vf5, vf6, vf7, vf8;
+
+        private StoreAndStoreHelper() {
+            this.vf1 = -1;
+            this.vf2 = -1;
+            this.vf3 = -1;
+            this.vf4 = -1;
+            this.vf5 = -1;
+            this.vf6 = -1;
+            this.vf7 = -1;
+            this.vf8 = -1;
+        }
+
+        private StoreAndStoreHelper(int l1, int l2, int l3, int l4, int l5, int l6, int l7, int l8) {
+            this(); // Initialize all to -1 here, redundant wrt to the below stores
+
+            this.vf1 = l1;
+            this.vf2 = l2;
+            this.vf3 = l3;
+            this.vf4 = l4;
+            this.vf5 = l5;
+            this.vf6 = l6;
+            this.vf7 = l7;
+            this.vf8 = l8;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/Straighten.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Various small benchmarks testing how well the optimizer straightens code.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Straighten {
+
+    private int[] intArr;
+    private long[] longArr;
+
+    @Setup
+    public void setupSubclass() {
+        int TEST_SIZE = 300;
+
+        Random r = new Random(453543);
+
+        /*
+         * initialize arrays with some values between 0 and 7.
+         */
+        intArr = new int[TEST_SIZE];
+        for (int i = 0; i < TEST_SIZE; i++) {
+            intArr[i] = r.nextInt(8);
+        }
+
+        longArr = new long[TEST_SIZE];
+        for (int i = 0; i < TEST_SIZE; i++) {
+            longArr[i] = (long) r.nextInt(8);
+        }
+
+    }
+
+    private int innerCandidate1int(int i) {
+        int j = 0;
+
+        if (i == 5) {
+            /* we know that i isn't 4 and is less than 7 here. */
+            j++;
+        }
+        if (i == 4) {
+            /* we know that i is less than 7 here. */
+            j += 2;
+        }
+        if (i < 7) {
+            /* we know that i is less than 7, so it isn't greater than 7. */
+            j += 4;
+        }
+        if (i > 7) {
+            j += 8;
+        }
+        return j;
+    }
+
+    /** Tests how well serial constant integer compares are straightened. */
+    @Benchmark
+    public int testStraighten1int() throws Exception {
+        int dummy = 0;
+        int[] arr = intArr;
+        for (int i : arr) {
+            dummy += innerCandidate1int(i);
+        }
+        return dummy;
+    }
+
+    private long innerCandidate1long(long l) {
+        long j = 0;
+
+        if (l == 5) {
+            /* we know that l isn't 4 and is less than 7 here. */
+            j++;
+        }
+        if (l == 4) {
+            /* we know that l is less than 7 here. */
+            j += 2;
+        }
+        if (l < 7) {
+            /* we know that l is less than 7, so it isn't greater than 7. */
+            j += 4;
+        }
+        if (l > 7) {
+            j += 8;
+        }
+        return j;
+    }
+
+    /** Tests how well serial constant long compares are straightened. */
+    @Benchmark
+    public int testStraighten1long() throws Exception {
+        int dummy = 0;
+        long[] arr = longArr;
+        for (long l : arr) {
+            dummy += innerCandidate1long(l);
+        }
+        return dummy;
+    }
+
+    private int innerCandidate2int(int i) {
+        int j;
+
+        if (i < 5) {
+            /* j becomes 3, so it should be straightened to j == 3 case below. */
+            j = 3;
+        } else {
+            /* j becomes 4, so it should be straightened to j == 4 case below. */
+            j = 4;
+        }
+
+        if (j == 4) {
+            i += 2;
+        }
+        if (j == 3) {
+            i += 4;
+        }
+        return i;
+    }
+
+    /** Tests how well constant integer definitions are straightened. */
+    @Benchmark
+    public int testStraighten2int() throws Exception {
+        int[] arr = intArr;
+        int dummy = 0;
+        for (int i : arr) {
+            dummy += innerCandidate2int(i);
+        }
+        return dummy;
+    }
+
+    private long innerCandidate2long(long l) {
+        long j;
+
+        if (l < 5) {
+            /* j becomes 3, so it should be straightened to j == 3 case below. */
+            j = 3;
+        } else {
+            /* j becomes 4, so it should be straightened to j == 4 case below. */
+            j = 4;
+        }
+
+        if (j == 4) {
+            l += 2;
+        }
+        if (j == 3) {
+            l += 4;
+        }
+        return l;
+    }
+
+    /** Tests how well constant long definitions are straightened. */
+    @Benchmark
+    public int testStraighten2long() throws Exception {
+        int dummy = 0;
+        long[] arr = longArr;
+        for (long l : arr) {
+            dummy += innerCandidate2long(l);
+        }
+        return dummy;
+    }
+
+    private int innerCandidate3int(int i, int j) {
+        int k = 0;
+
+        if (i == j) {
+            k++;
+        }
+        if (i != j) {
+            k += 2;
+        }
+        if (i < j) {
+            k += 4;
+        }
+        return k;
+    }
+
+    /**
+     * Tests how well variable integer compares are straightened.
+     */
+    @Benchmark
+    public int testStraighten3int() throws Exception {
+        int dummy = 0;
+        int[] arr = intArr;
+        for (int i = 0; i < arr.length - 1; i++) {
+            dummy += innerCandidate3int(arr[i], arr[i + 1]);
+        }
+        return dummy;
+    }
+
+    private long innerCandidate3long(long i, long j) {
+        long k = 0;
+
+        if (i == j) {
+            k++;
+        }
+        if (i != j) {
+            k += 2;
+        }
+        if (i < j) {
+            k += 4;
+        }
+        return k;
+    }
+
+    /** Tests how well variable long compares are straightened. */
+    @Benchmark
+    public int testStraighten3long() throws Exception {
+        int dummy = 0;
+        long[] arr = longArr;
+        for (int i = 0; i < arr.length - 1; i++) {
+            dummy += innerCandidate3long(arr[i], arr[i + 1]);
+        }
+        return dummy;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.openjdk.bench.vm.compiler;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class WriteBarrier {
+
+    // For array references
+    public static final int NUM_REFERENCES_SMALL = 32;
+    public static final int NUM_REFERENCES_LARGE = 2048;
+
+    // For array update tests
+    private Object[] theArraySmall;
+    private Object[] realReferencesSmall;
+    private Object[] nullReferencesSmall;
+    private int[] indicesSmall;
+
+    private Object[] theArrayLarge;
+    private Object[] realReferencesLarge;
+    private Object[] nullReferencesLarge;
+    private int[] indicesLarge;
+
+    // For field update tests
+    public Referencer head = null;
+    public Referencer tail = null;
+
+    // For random number generation
+    private int m_w;
+    private int m_z;
+
+    // For field references
+    public class Referencer {
+        Referencer next = null;
+        Referencer() {
+            this.next = null;
+        }
+        void append(Referencer r) {
+            this.next = r;
+        }
+        void clear() {
+            this.next = null;
+        }
+    }
+
+    @Setup
+    public void setup() {
+        theArraySmall = new Object[NUM_REFERENCES_SMALL];
+        realReferencesSmall = new Object[NUM_REFERENCES_SMALL];
+        nullReferencesSmall = new Object[NUM_REFERENCES_SMALL];
+        indicesSmall = new int[NUM_REFERENCES_SMALL];
+
+        theArrayLarge = new Object[NUM_REFERENCES_LARGE];
+        realReferencesLarge = new Object[NUM_REFERENCES_LARGE];
+        nullReferencesLarge = new Object[NUM_REFERENCES_LARGE];
+        indicesLarge = new int[NUM_REFERENCES_LARGE];
+
+        m_w = (int) System.currentTimeMillis();
+        Random random = new Random();
+        m_z = random.nextInt(10000) + 1;
+
+        for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
+            indicesSmall[i] = get_random() % (NUM_REFERENCES_SMALL - 1);
+            realReferencesSmall[i] = new Object();
+        }
+
+        for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
+            indicesLarge[i] = get_random() % (NUM_REFERENCES_LARGE - 1);
+            realReferencesLarge[i] = new Object();
+        }
+
+        // Build a small linked structure
+        this.head = new Referencer();
+        this.tail = new Referencer();
+        this.head.append(this.tail);
+
+        // This will (hopefully) promote objects to old space
+        // Run with -XX:+DisableExplicitGC to keep
+        // objects in young space
+        System.gc();
+    }
+
+    private int get_random() {
+        m_z = 36969 * (m_z & 65535) + (m_z >> 16);
+        m_w = 18000 * (m_w & 65535) + (m_w >> 16);
+        return Math.abs((m_z << 16) + m_w);  /* 32-bit result */
+    }
+
+    @Benchmark
+    public void testArrayWriteBarrierFastPathRealSmall() {
+        for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
+            theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = realReferencesSmall[indicesSmall[i]];
+        }
+    }
+
+    @Benchmark
+    public void testArrayWriteBarrierFastPathNullSmall() {
+        for (int i = 0; i < NUM_REFERENCES_SMALL; i++) {
+            theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = nullReferencesSmall[indicesSmall[i]];
+        }
+    }
+
+    @Benchmark
+    public void testArrayWriteBarrierFastPathRealLarge() {
+        for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
+            theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = realReferencesLarge[indicesLarge[i]];
+        }
+    }
+
+    @Benchmark
+    public void testArrayWriteBarrierFastPathNullLarge() {
+        for (int i = 0; i < NUM_REFERENCES_LARGE; i++) {
+            theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = nullReferencesLarge[indicesLarge[i]];
+        }
+    }
+
+    @Benchmark()
+    public void testFieldWriteBarrierFastPath() {
+        // Shuffle everything around
+        this.tail.append(this.head);
+        this.head.clear();
+        this.head.append(this.tail);
+        this.tail.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/gc/Alloc.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.gc;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Alloc {
+
+    public static final int LENGTH = 400;
+    public static final int ARR_LEN = 100;
+    public int largeLen = 100;
+    public int smalllen = 6;
+
+    @Benchmark
+    public void testLargeConstArray(Blackhole bh) throws Exception {
+        int localArrlen = ARR_LEN;
+        for (int i = 0; i < LENGTH; i++) {
+            Object[] tmp = new Object[localArrlen];
+            bh.consume(tmp);
+        }
+    }
+
+    @Benchmark
+    public void testLargeVariableArray(Blackhole bh) throws Exception {
+        int localArrlen = largeLen;
+        for (int i = 0; i < LENGTH; i++) {
+            Object[] tmp = new Object[localArrlen];
+            bh.consume(tmp);
+        }
+    }
+
+    @Benchmark
+    public void testSmallConstArray(Blackhole bh) throws Exception {
+        int localArrlen = largeLen;
+        for (int i = 0; i < LENGTH; i++) {
+            Object[] tmp = new Object[localArrlen];
+            bh.consume(tmp);
+        }
+    }
+
+    @Benchmark
+    public void testSmallObject(Blackhole bh) throws Exception {
+        FortyBytes localDummy = null;
+        for (int i = 0; i < LENGTH; i++) {
+            FortyBytes tmp = new FortyBytes();
+            tmp.next = localDummy;
+            localDummy = tmp;
+            bh.consume(tmp);
+        }
+    }
+
+    @Benchmark
+    public void testSmallVariableArray(Blackhole bh) throws Exception {
+        int localArrlen = smalllen;
+        for (int i = 0; i < LENGTH; i++) {
+            Object[] tmp = new Object[localArrlen];
+            bh.consume(tmp);
+        }
+    }
+
+    final class FortyBytes {
+        Object next;
+        int y, z, k, f, g, e, t;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/Capture0.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates anonymous classes creation (for comparison with lambda)
+ *
+ * Naming convention:
+ *  - inner_N      - lambda captures N local variables
+ *  - inner_this_N - lambda captures 'this' and N local variables
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Capture0 {
+
+    /*
+     *  volatile is used in order to avoid constant propagation
+     *  That is why the bench is relevant only on TSO platforms (x86, SPARC).
+     *  ARM & PPC - TBD when necessary.
+     */
+    public volatile int wh0 = 0;
+    public volatile int wh1 = 1;
+    public volatile int wh2 = 2;
+    public volatile int wh3 = 3;
+    public volatile int wh4 = 4;
+    public volatile int wh5 = 5;
+    public volatile int wh6 = 6;
+    public volatile int wh7 = 7;
+
+    public String fortyTwo = "42";
+
+    @Benchmark()
+    public FunctionalInterface0 inner0(){
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return "42";
+            }
+        };
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 inner_1(){
+        final int l0 = wh0;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return "42" + l0;
+            }
+        };
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 inner_2(){
+        final int l0 = wh0;
+        final int l1 = wh1;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return "42" + l0 + " " + l1;
+            }
+        };
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 inner_4(){
+        final int l0 = wh0;
+        final int l1 = wh1;
+        final int l2 = wh2;
+        final int l3 = wh3;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return "42" + l0 + " " + l1 + " " + l2 + " " + l3;
+            }
+        };
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 inner_8(){
+        final int l0 = wh0;
+        final int l1 = wh1;
+        final int l2 = wh2;
+        final int l3 = wh3;
+        final int l4 = wh4;
+        final int l5 = wh5;
+        final int l6 = wh6;
+        final int l7 = wh7;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return "42" + l0 + " " + l1 + " " + l2 + " " + l3 +
+                        " " + l4 + " " + l5 + " " + l6 + " " + l7;
+            }
+        };
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 inner_this_0(){
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return fortyTwo;
+            }
+        };
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 inner_this_1(){
+        final int l0 = wh0;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return fortyTwo + l0;
+            }
+        };
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 inner_this_2(){
+        final int l0 = wh0;
+        final int l1 = wh1;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return fortyTwo + l0 + " " + l1;
+            }
+        };
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 inner_this_4(){
+        final int l0 = wh0;
+        final int l1 = wh1;
+        final int l2 = wh2;
+        final int l3 = wh3;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3;
+            }
+        };
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 inner_this_8(){
+        final int l0 = wh0;
+        final int l1 = wh1;
+        final int l2 = wh2;
+        final int l3 = wh3;
+        final int l4 = wh4;
+        final int l5 = wh5;
+        final int l6 = wh6;
+        final int l7 = wh7;
+        return new FunctionalInterface0() {
+            @Override
+            public Object foo() {
+                return fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3 +
+                        " " + l4 + " " + l5 + " " + l6 + " " + l7;
+            }
+        };
+    }
+
+//--------------------lambda part
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_00(){
+        return () -> "42";
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_01(){
+        int l0 = wh0;
+        return () -> "42" + l0;
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_02(){
+        int l0 = wh0;
+        int l1 = wh1;
+        return () -> "42" + l0 + " " + l1;
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_04(){
+        int l0 = wh0;
+        int l1 = wh1;
+        int l2 = wh2;
+        int l3 = wh3;
+        return () -> "42" + l0 + " " + l1 + " " + l2 + " " + l3;
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_08(){
+        int l0 = wh0;
+        int l1 = wh1;
+        int l2 = wh2;
+        int l3 = wh3;
+        int l4 = wh4;
+        int l5 = wh5;
+        int l6 = wh6;
+        int l7 = wh7;
+        return () -> "42" + l0 + " " + l1 + " " + l2 + " " + l3 + " " + l4 + " " + l5 + " " + l6 + " " + l7;
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_this_0(){
+        return () -> fortyTwo;
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_this_1(){
+        int l0 = wh0;
+        return () -> fortyTwo + l0;
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_this_2(){
+        int l0 = wh0;
+        int l1 = wh1;
+        return () -> fortyTwo + l0 + " " + l1;
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_this_4(){
+        int l0 = wh0;
+        int l1 = wh1;
+        int l2 = wh2;
+        int l3 = wh3;
+        return () -> fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3;
+    }
+
+
+    @Benchmark()
+    public FunctionalInterface0 lambda_this_8(){
+        int l0 = wh0;
+        int l1 = wh1;
+        int l2 = wh2;
+        int l3 = wh3;
+        int l4 = wh4;
+        int l5 = wh5;
+        int l6 = wh6;
+        int l7 = wh7;
+        return () -> fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3 +
+                " " + l4 + " " + l5 + " " + l6 + " " + l7;
+    }
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/Capture2.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.Comparator;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * measure lambda capture
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class Capture2 {
+
+    public static class StaticInner implements Comparator<Integer> {
+        @Override
+        public int compare(Integer x, Integer y) {
+            return (x < y) ? -1 : ((x > y) ? 1 : 0);
+        }
+    }
+
+    public class InstanceInner implements Comparator<Integer> {
+        @Override
+        public int compare(Integer x, Integer y) {
+            return (x < y) ? -1 : ((x > y) ? 1 : 0);
+        }
+    }
+
+
+    @Benchmark()
+    public Comparator<Integer> anonymous(){
+        return new Comparator<Integer>() {
+            @Override
+            public int compare(Integer x, Integer y) {
+                return (x < y) ? -1 : ((x > y) ? 1 : 0);
+            }
+        };
+    }
+
+    @Benchmark()
+    public Comparator<Integer> inner(){
+        return new InstanceInner();
+    }
+
+    @Benchmark()
+    public Comparator<Integer> inner_static(){
+        return new StaticInner();
+    }
+
+    @Benchmark()
+    public Comparator<Integer> lambda(){
+        return (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0);
+    }
+
+    public Comparator<Integer> mref_static(){
+        return Integer::compare;
+    }
+
+    @Benchmark()
+    public Comparator<Integer> mref_unbound(){
+        return Integer::compareTo;
+    }
+
+    @Benchmark()
+    public Comparator<Integer> mref_bound(){
+        return this::compareInteger;
+    }
+
+    public int compareInteger(Integer x, Integer y) {
+        return (x < y) ? -1 : ((x > y) ? 1 : 0);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/CaptureMR.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates method reference capture
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class CaptureMR {
+
+    public static class Mock0 {
+        public Mock0() {
+        }
+    }
+
+    public static Object method_static() {
+        return "42";
+    }
+
+    public Object method_instance() {
+        return "42";
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 mref_static0(){
+        return CaptureMR::method_static;
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 mref_bound0(){
+        return this::method_instance;
+    }
+
+    @Benchmark()
+    public FunctionalInterface0 mref_constructor0(){
+        return Mock0::new;
+    }
+
+
+//---------------------------
+
+    public static class Mock1 {
+        private Object oo;
+        public Mock1(Object o) {
+            oo = o;
+        }
+    }
+
+    public static Object method_static(Object bar) {
+        return "42" + bar;
+    }
+
+    public Object method_instance(Object bar) {
+        return "42" + bar;
+    }
+
+    @Benchmark()
+    public FunctionalInterface1 mref_static1(){
+        return CaptureMR::method_static;
+    }
+
+    @Benchmark()
+    public FunctionalInterface1 mref_bound1(){
+        return this::method_instance;
+    }
+
+    @Benchmark()
+    public FunctionalInterface1 mref_constructor1(){
+        return Mock1::new;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/FunctionalInterface0.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+/**
+ * Functional Interface for lambdas
+ * FunctionalInterfaceN - where N is number of parameters
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+public interface FunctionalInterface0 {
+
+    public Object foo();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/capture/FunctionalInterface1.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.capture;
+
+/**
+ * Functional Interface for lambdas
+ * FunctionalInterfaceN - where N is number of parameters
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+public interface FunctionalInterface1 {
+
+    public Object foo(Object bar);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap0.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainAnonymCap0 extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1();
+        start2 = get2();
+        start4 = get4();
+        start8 = get8();
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0() {
+        return new TopLevel() {
+            @Override
+            public String getImage() {
+                return "GOT: ";
+            }
+        };
+    }
+
+    public static Level get1() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get0();
+            }
+        };
+    }
+
+    public static Level get2() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get1();
+            }
+        };
+    }
+
+    public static Level get3() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get2();
+            }
+        };
+    }
+
+    public static Level get4() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get3();
+            }
+        };
+    }
+
+    public static Level get5() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get4();
+            }
+        };
+    }
+
+    public static Level get6() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get5();
+            }
+        };
+    }
+
+    public static Level get7() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get6();
+            }
+        };
+    }
+
+    public static Level get8() {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get7();
+            }
+        };
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap1.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainAnonymCap1 extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1("capture me");
+        start2 = get2("capture me");
+        start4 = get4("capture me");
+        start8 = get8("capture me");
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0(String v) {
+        return new TopLevel() {
+            @Override
+            public String getImage() {
+                return "GOT: "+v;
+            }
+        };
+    }
+
+    public static Level get1(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get0(v);
+            }
+        };
+    }
+
+    public static Level get2(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get1(v);
+            }
+        };
+    }
+
+    public static Level get3(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get2(v);
+            }
+        };
+    }
+
+    public static Level get4(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get3(v);
+            }
+        };
+    }
+
+    public static Level get5(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get4(v);
+            }
+        };
+    }
+
+    public static Level get6(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get5(v);
+            }
+        };
+    }
+
+    public static Level get7(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get6(v);
+            }
+        };
+    }
+
+    public static Level get8(String v) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get7(v);
+            }
+        };
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainAnonymCap4.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainAnonymCap4 extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1("capture me", "and me", "me too", "wait! what about me?");
+        start2 = get2("capture me", "and me", "me too", "wait! what about me?");
+        start4 = get4("capture me", "and me", "me too", "wait! what about me?");
+        start8 = get8("capture me", "and me", "me too", "wait! what about me?");
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0(String v0, String v1, String v2, String v3) {
+        return new TopLevel() {
+            @Override
+            public String getImage() {
+                return "GOT: " + v0 + "," + v1 + "," + v2 + "," + v3;
+            }
+        };
+    }
+
+    public static Level get1(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get0(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get2(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get1(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get3(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get2(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get4(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get3(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get5(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get4(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get6(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get5(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get7(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get6(v0, v1, v2, v3);
+            }
+        };
+    }
+
+    public static Level get8(String v0, String v1, String v2, String v3) {
+        return new Level() {
+            @Override
+            public Level up() {
+                return get7(v0, v1, v2, v3);
+            }
+        };
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainBase.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+
+import org.openjdk.jmh.infra.Blackhole;
+
+public class ChainBase {
+
+    protected void process(Blackhole bh, Level start) {
+        Level curr = start;
+        while (true) {
+            curr = curr.up();
+            if(curr == null) break;
+            bh.consume(curr);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap0.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainLambdaCap0 extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1();
+        start2 = get2();
+        start4 = get4();
+        start8 = get8();
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0() {
+        return () -> "GOT: ";
+    }
+
+    public static Level get1() {
+        return () -> get0();
+    }
+
+    public static Level get2() {
+        return () -> get1();
+    }
+
+    public static Level get3() {
+        return () -> get2();
+    }
+
+    public static Level get4() {
+        return () -> get3();
+    }
+
+    public static Level get5() {
+        return () -> get4();
+    }
+
+    public static Level get6() {
+        return () -> get5();
+    }
+
+    public static Level get7() {
+        return () -> get6();
+    }
+
+    public static Level get8() {
+        return () -> get7();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap1.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainLambdaCap1 extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1("capture me");
+        start2 = get2("capture me");
+        start4 = get4("capture me");
+        start8 = get8("capture me");
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0(String v) {
+        return () -> "GOT: "+v;
+    }
+
+    public static Level get1(String v) {
+        return () -> get0(v);
+    }
+
+    public static Level get2(String v) {
+        return () -> get1(v);
+    }
+
+    public static Level get3(String v) {
+        return () -> get2(v);
+    }
+
+    public static Level get4(String v) {
+        return () -> get3(v);
+    }
+
+    public static Level get5(String v) {
+        return () -> get4(v);
+    }
+
+    public static Level get6(String v) {
+        return () -> get5(v);
+    }
+
+    public static Level get7(String v) {
+        return () -> get6(v);
+    }
+
+    public static Level get8(String v) {
+        return () -> get7(v);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainLambdaCap4.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainLambdaCap4 extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1("capture me", "and me", "me too", "wait! what about me?");
+        start2 = get2("capture me", "and me", "me too", "wait! what about me?");
+        start4 = get4("capture me", "and me", "me too", "wait! what about me?");
+        start8 = get8("capture me", "and me", "me too", "wait! what about me?");
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0(String v0, String v1, String v2, String v3) {
+        return () -> "GOT: " + v0 + "," + v1 + "," + v2 + "," + v3;
+    }
+
+    public static Level get1(String v0, String v1, String v2, String v3) {
+        return () -> get0(v0, v1, v2, v3);
+    }
+
+    public static Level get2(String v0, String v1, String v2, String v3) {
+        return () -> get1(v0, v1, v2, v3);
+    }
+
+    public static Level get3(String v0, String v1, String v2, String v3) {
+        return () -> get2(v0, v1, v2, v3);
+    }
+
+    public static Level get4(String v0, String v1, String v2, String v3) {
+        return () -> get3(v0, v1, v2, v3);
+    }
+
+    public static Level get5(String v0, String v1, String v2, String v3) {
+        return () -> get4(v0, v1, v2, v3);
+    }
+
+    public static Level get6(String v0, String v1, String v2, String v3) {
+        return () -> get5(v0, v1, v2, v3);
+    }
+
+    public static Level get7(String v0, String v1, String v2, String v3) {
+        return () -> get6(v0, v1, v2, v3);
+    }
+
+    public static Level get8(String v0, String v1, String v2, String v3) {
+        return () -> get7(v0, v1, v2, v3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainMrefBound.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainMrefBound extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1();
+        start2 = get2();
+        start4 = get4();
+        start8 = get8();
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public TopLevel get0() {
+        return () -> "GOT: ";
+    }
+
+    public Level get1() {
+        return this::get0;
+    }
+
+    public Level get2() {
+        return this::get1;
+    }
+
+    public Level get3() {
+        return this::get2;
+    }
+
+    public Level get4() {
+        return this::get3;
+    }
+
+    public Level get5() {
+        return this::get4;
+    }
+
+    public Level get6() {
+        return this::get5;
+    }
+
+    public Level get7() {
+        return this::get6;
+    }
+
+    public Level get8() {
+        return this::get7;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/ChainMrefUnbound.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Chain of (capture + invocation) microbenchmark.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class ChainMrefUnbound extends ChainBase {
+
+    public Level start1;
+    public Level start2;
+    public Level start4;
+    public Level start8;
+
+    @Setup
+    public void init() {
+        start1 = get1();
+        start2 = get2();
+        start4 = get4();
+        start8 = get8();
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(1)
+    public void call1(Blackhole bh) {
+        process(bh, start1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(2)
+    public void call2(Blackhole bh) {
+        process(bh, start2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(4)
+    public void call4(Blackhole bh) {
+        process(bh, start4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(8)
+    public void call8(Blackhole bh) {
+        process(bh, start8);
+    }
+
+    public static TopLevel get0() {
+        return () -> "GOT: ";
+    }
+
+    public static Level get1() {
+        return ChainMrefUnbound::get0;
+    }
+
+    public static Level get2() {
+        return ChainMrefUnbound::get1;
+    }
+
+    public static Level get3() {
+        return ChainMrefUnbound::get2;
+    }
+
+    public static Level get4() {
+        return ChainMrefUnbound::get3;
+    }
+
+    public static Level get5() {
+        return ChainMrefUnbound::get4;
+    }
+
+    public static Level get6() {
+        return ChainMrefUnbound::get5;
+    }
+
+    public static Level get7() {
+        return ChainMrefUnbound::get6;
+    }
+
+    public static Level get8() {
+        return ChainMrefUnbound::get7;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/Level.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+
+/**
+ * Functional Interface.
+ */
+public interface Level {
+
+    public Level up();
+
+    default String getImage() {
+        return "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/chain/TopLevel.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.chain;
+
+/**
+ * Functional Interface as end of chain marker.
+ */
+public interface TopLevel extends Level {
+
+    @Override
+    default Level up() {
+        return null;
+    }
+
+    @Override
+    public String getImage();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/AckermannI.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntBinaryOperator;
+
+/**
+ * evaluates invocation costs in case of long recursive chains
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class AckermannI {
+
+    // ackermann(1,1748)+ ackermann(2,1897)+ ackermann(3,8); == 9999999 calls
+    public static final int Y1 = 1748;
+    public static final int Y2 = 1897;
+    public static final int Y3 = 8;
+
+    public static int ack(int x, int y) {
+        return x == 0 ?
+                y + 1 :
+                (y == 0 ?
+                        ack(x - 1, 1) :
+                        ack(x - 1, ack(x, y - 1)));
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public int func() {
+        return ack(1, Y1) + ack(2, Y2) + ack(3, Y3);
+    }
+
+    public static final IntBinaryOperator inner_ack =
+            new IntBinaryOperator() {
+                @Override
+                public int applyAsInt(int x, int y) {
+                    return x == 0 ?
+                            y + 1 :
+                            (y == 0 ?
+                                    inner_ack.applyAsInt(x - 1, 1) :
+                                    inner_ack.applyAsInt(x - 1, inner_ack.applyAsInt(x, y - 1)));
+
+                }
+            };
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public int inner() {
+        return inner_ack.applyAsInt(1, Y1) + inner_ack.applyAsInt(2, Y2) + inner_ack.applyAsInt(3, Y3);
+    }
+
+    public static final IntBinaryOperator lambda_ack =
+            (x, y) -> x == 0 ?
+                    y + 1 :
+                    (y == 0 ?
+                            AckermannI.lambda_ack.applyAsInt(x - 1, 1) :
+                            AckermannI.lambda_ack.applyAsInt(x - 1, AckermannI.lambda_ack.applyAsInt(x, y - 1)));
+
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public int lambda() {
+        return lambda_ack.applyAsInt(1, Y1) + lambda_ack.applyAsInt(2, Y2) + lambda_ack.applyAsInt(3, Y3);
+    }
+
+    public static final IntBinaryOperator mref_ack = AckermannI::mref_ack_helper;
+
+    public static int mref_ack_helper(int x, int y) {
+        return x == 0 ?
+                y + 1 :
+                (y == 0 ?
+                        mref_ack.applyAsInt(x - 1, 1) :
+                        mref_ack.applyAsInt(x - 1, mref_ack.applyAsInt(x, y - 1)));
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public int mref() {
+        return mref_ack.applyAsInt(1, Y1) + mref_ack.applyAsInt(2, Y2) + mref_ack.applyAsInt(3, Y3);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/AckermannL.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.BinaryOperator;
+
+/**
+ * evaluates invocation costs in case of long recursive chains
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+public class AckermannL {
+
+    // ackermann(1,1748)+ ackermann(2,1897)+ ackermann(3,8); == 9999999 calls
+    public static final int Y1 = 1748;
+    public static final int Y2 = 1897;
+    public static final int Y3 = 8;
+
+    public static Integer ack(Integer x, Integer y) {
+        return x == 0 ?
+                y + 1 :
+                (y == 0 ?
+                        ack(x - 1, 1) :
+                        ack(x - 1, ack(x, y - 1)));
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public Integer func() {
+        return ack(1, Y1) + ack(2, Y2) + ack(3, Y3);
+    }
+
+    public static final BinaryOperator<Integer> inner_ack =
+            new BinaryOperator<Integer>() {
+                @Override
+                public Integer apply(Integer x, Integer y) {
+                    return x == 0 ?
+                            y + 1 :
+                            (y == 0 ?
+                                    inner_ack.apply(x - 1, 1) :
+                                    inner_ack.apply(x - 1, inner_ack.apply(x, y - 1)));
+                }
+            };
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public Integer inner() {
+        return inner_ack.apply(1, Y1) + inner_ack.apply(2, Y2) + inner_ack.apply(3, Y3);
+    }
+
+    public static final BinaryOperator<Integer> lambda_ack =
+            (x, y) -> x == 0 ?
+                    y + 1 :
+                    (y == 0 ?
+                            AckermannL.lambda_ack.apply(x - 1, 1) :
+                            AckermannL.lambda_ack.apply(x - 1, AckermannL.lambda_ack.apply(x, y - 1)));
+
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public Integer lambda() {
+        return lambda_ack.apply(1, Y1) + lambda_ack.apply(2, Y2) + lambda_ack.apply(3, Y3);
+    }
+
+    public static final BinaryOperator<Integer> mref_ack = AckermannL::mref_ack_helper;
+
+    public static Integer mref_ack_helper(Integer x, Integer y) {
+        return x == 0 ?
+                y + 1 :
+                (y == 0 ?
+                        mref_ack.apply(x - 1, 1) :
+                        mref_ack.apply(x - 1, mref_ack.apply(x, y - 1)));
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public Integer mref() {
+        return mref_ack.apply(1, Y1) + mref_ack.apply(2, Y2) + mref_ack.apply(3, Y3);
+    }
+
+    public static final BinaryOperator<Integer> mref_ackIII = AckermannL::mref_ack_helperIII;
+
+    public static int mref_ack_helperIII(int x, int y) {
+        return x == 0 ?
+                y + 1 :
+                (y == 0 ?
+                        mref_ackIII.apply(x - 1, 1) :
+                        mref_ackIII.apply(x - 1, mref_ackIII.apply(x, y - 1)));
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(9999999)
+    public Integer mrefIII() {
+        return mref_ackIII.apply(1, Y1) + mref_ackIII.apply(2, Y2) + mref_ackIII.apply(3, Y3);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Function0.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates invocation costs.
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Function0 {
+
+    public interface FunctionI {
+        int foo();
+    }
+
+    public interface FunctionL {
+        Integer foo();
+    }
+
+    private static int valueI = 40002; // bypass Integer.cache
+    private static Integer valueL = Integer.valueOf(valueI);
+
+    public int fooInstanceI() {
+        return valueI;
+    }
+
+    public static int fooStaticI() {
+        return valueI;
+    }
+
+    public Integer fooInstanceL() {
+        return valueL;
+    }
+
+    public static Integer fooStaticL() {
+        return valueL;
+    }
+
+    @Benchmark
+    public int baselineI() {
+        return fooInstanceI();
+    }
+
+    @Benchmark
+    public Integer baselineL() {
+        return fooInstanceL();
+    }
+
+    public final FunctionI anonymI =
+            new FunctionI() {
+                @Override
+                public int foo() {
+                    return valueI;
+                }
+            };
+
+    public final FunctionL anonymL =
+            new FunctionL() {
+                @Override
+                public Integer foo() {
+                    return valueL;
+                }
+            };
+
+    @Benchmark
+    public int innerI() {
+        return anonymI.foo();
+    }
+
+    @Benchmark
+    public Integer innerL() {
+        return anonymL.foo();
+    }
+
+    public final FunctionI lambdaI = () -> valueI;
+
+    public final FunctionL lambdaL = () -> valueL;
+
+    @Benchmark
+    public int lambdaI() {
+        return lambdaI.foo();
+    }
+
+    @Benchmark
+    public Integer lambdaL() {
+        return lambdaL.foo();
+    }
+
+    public final FunctionI mref_I2I  = Function0::fooStaticI;
+    public final FunctionI mref_I2I_bound = this::fooInstanceI;
+
+    public final FunctionL mref_I2L  = Function0::fooStaticI;
+    public final FunctionL mref_I2L_bound = this::fooInstanceI;
+
+    public final FunctionI mref_L2I  = Function0::fooStaticL;
+    public final FunctionI mref_L2I_bound = this::fooInstanceL;
+
+    public final FunctionL mref_L2L  = Function0::fooStaticL;
+    public final FunctionL mref_L2L_bound = this::fooInstanceL;
+
+    // mref naming
+    // sig1_sig2 where:
+    // sig1 - signature of the method referenced by method ref
+    // sig2 - FuntionalInterface signature
+
+    @Benchmark
+    public int mrefI_I() {
+        return mref_I2I.foo();
+    }
+
+    @Benchmark
+    public int mref_bndI_I() {
+        return mref_I2I_bound.foo();
+    }
+
+    @Benchmark
+    public Integer mrefI_L() {
+        return mref_I2L.foo();
+    }
+
+    @Benchmark
+    public Integer mref_bndI_L() {
+        return mref_I2L_bound.foo();
+    }
+
+    @Benchmark
+    public int mrefL_I() {
+        return mref_L2I.foo();
+    }
+
+    @Benchmark
+    public int mref_bndL_I() {
+        return mref_L2I_bound.foo();
+    }
+
+    @Benchmark
+    public Integer mrefL_L() {
+        return mref_L2L.foo();
+    }
+
+    @Benchmark
+    public Integer mref_bndL_L() {
+        return mref_L2L_bound.foo();
+    }
+
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Function1.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * evaluates invocation costs.
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Function1 {
+
+    public interface FunctionII {
+        int foo(int x);
+    }
+
+    public interface FunctionIL {
+        int foo(Integer x);
+    }
+
+    public interface FunctionLL {
+        Integer foo(Integer x);
+    }
+
+    private static final int LIMIT = 1024;
+
+    private final int[]     dataI = new int[LIMIT + 1];
+    private final Integer[] dataL = new Integer[LIMIT + 1];
+
+    @Setup(Level.Iteration)
+    public void setup() {
+        for (int i = 0; i < dataI.length; i++) {
+            int value = ThreadLocalRandom.current().nextInt(10001,420000); // bypass Integer.cache
+            dataI[i] = value;
+            dataL[i] = value;
+        }
+    }
+
+
+
+    public int fooInstanceII(int x) {
+        return x;
+    }
+
+    public static int fooStaticII(int x) {
+        return x;
+    }
+
+    public int fooInstanceIL(Integer v) {
+        return v;
+    }
+
+    public static int fooStaticIL(Integer v) {
+        return v;
+    }
+
+    public Integer fooInstanceLL(Integer v) {
+        return v;
+    }
+
+    public static Integer fooStaticLL(Integer v) {
+        return v;
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void baselineII(Blackhole bh) {
+        for (int i = 0; i < LIMIT; i++) {
+            bh.consume(fooInstanceII(dataI[i]));
+        }
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void baselineIL(Blackhole bh) {
+        for (int i = 0; i < LIMIT; i++) {
+            bh.consume(fooInstanceIL(dataL[i]));
+        }
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void baselineLL(Blackhole bh) {
+        for (int i = 0; i < LIMIT; i++) {
+            bh.consume(fooInstanceLL(dataL[i]));
+        }
+    }
+
+    public final FunctionII anonymII =
+            new FunctionII() {
+                @Override
+                public int foo(int x) {
+                    return x;
+                }
+            };
+
+    public final FunctionIL anonymIL =
+            new FunctionIL() {
+                @Override
+                public int foo(Integer v) {
+                    return v;
+                }
+            };
+
+    public final FunctionLL anonymLL =
+            new FunctionLL() {
+                @Override
+                public Integer foo(Integer v) {
+                    return v;
+                }
+            };
+
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void innerII(Blackhole bh) {
+        processII(bh, anonymII);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void innerIL(Blackhole bh) {
+        processIL(bh, anonymIL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void innerLL(Blackhole bh) {
+        processLL(bh, anonymLL);
+    }
+
+    public final FunctionII lambdaII =  x -> x;
+
+    public final FunctionIL lambdaIL =  v -> v;
+
+    public final FunctionLL lambdaLL =  v -> v;
+
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void lambdaII(Blackhole bh) {
+        processII(bh, lambdaII);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void lambdaIL(Blackhole bh) {
+        processIL(bh, lambdaIL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void lambdaLL(Blackhole bh) {
+        processLL(bh, lambdaLL);
+    }
+
+
+
+    public final FunctionII mref_II2II  = Function1::fooStaticII;
+    public final FunctionII mref_II2II_bound = this::fooInstanceII;
+    public final FunctionIL mref_II2IL  = Function1::fooStaticII;
+    public final FunctionIL mref_II2IL_bound = this::fooInstanceII;
+    public final FunctionLL mref_II2LL  = Function1::fooStaticII;
+    public final FunctionLL mref_II2LL_bound = this::fooInstanceII;
+
+    public final FunctionII mref_IL2II  = Function1::fooStaticIL;
+    public final FunctionII mref_IL2II_bound = this::fooInstanceIL;
+    public final FunctionIL mref_IL2IL  = Function1::fooStaticIL;
+    public final FunctionIL mref_IL2IL_bound = this::fooInstanceIL;
+    public final FunctionLL mref_IL2LL  = Function1::fooStaticIL;
+    public final FunctionLL mref_IL2LL_bound = this::fooInstanceIL;
+
+    public final FunctionII mref_LL2II  = Function1::fooStaticLL;
+    public final FunctionII mref_LL2II_bound = this::fooInstanceLL;
+    public final FunctionIL mref_LL2IL  = Function1::fooStaticLL;
+    public final FunctionIL mref_LL2IL_bound = this::fooInstanceLL;
+    public final FunctionLL mref_LL2LL  = Function1::fooStaticLL;
+    public final FunctionLL mref_LL2LL_bound = this::fooInstanceLL;
+
+
+    // mref naming
+    // sig1_sig2 where:
+    // sig1 - signature of the method referenced by method ref
+    // sig2 - FuntionalInterface signature
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefII_II(Blackhole bh) {
+        processII(bh, mref_II2II);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndII_II(Blackhole bh) {
+        processII(bh, mref_II2II_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefII_IL(Blackhole bh) {
+        processIL(bh, mref_II2IL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndII_IL(Blackhole bh) {
+        processIL(bh, mref_II2IL_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefII_LL(Blackhole bh) {
+        processLL(bh, mref_II2LL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndII_LL(Blackhole bh) {
+        processLL(bh, mref_II2LL_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefIL_II(Blackhole bh) {
+        processII(bh, mref_IL2II);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndIL_II(Blackhole bh) {
+        processII(bh, mref_IL2II_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefIL_IL(Blackhole bh) {
+        processIL(bh, mref_IL2IL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndIL_IL(Blackhole bh) {
+        processIL(bh, mref_IL2IL_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefIL_LL(Blackhole bh) {
+        processLL(bh, mref_IL2LL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndIL_LL(Blackhole bh) {
+        processLL(bh, mref_IL2LL_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefLL_II(Blackhole bh) {
+        processII(bh, mref_LL2II);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndLL_II(Blackhole bh) {
+        processII(bh, mref_LL2II_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefLL_IL(Blackhole bh) {
+        processIL(bh, mref_LL2IL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndLL_IL(Blackhole bh) {
+        processIL(bh, mref_LL2IL_bound);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mrefLL_LL(Blackhole bh) {
+        processLL(bh, mref_LL2LL);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(LIMIT)
+    public void mref_bndLL_LL(Blackhole bh) {
+        processLL(bh, mref_LL2LL_bound);
+    }
+
+
+    private void processII(Blackhole bh, FunctionII func) {
+        for (int i = 0; i < LIMIT; i++) {
+            bh.consume(func.foo(dataI[i]));
+        }
+    }
+
+    private void processIL(Blackhole bh, FunctionIL func) {
+        for (int i = 0; i < LIMIT; i++) {
+            bh.consume(func.foo(dataL[i]));
+        }
+    }
+
+    private void processLL(Blackhole bh, FunctionLL func) {
+        for (int i = 0; i < LIMIT; i++) {
+            bh.consume(func.foo(dataL[i]));
+        }
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Morph0.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * evaluates N-morphic invocation costs.
+ * N different lambdas each capture 0 variable
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Morph0 {
+
+
+    private static final int LIMIT = 16536;
+    private static final int OPS = 4;
+    private static final int OPERATIONS = OPS*LIMIT;
+
+    // <source of functional interface>_N; where N - how many different targets
+    private IntUnaryOperator[] inner_1;
+    private IntUnaryOperator[] inner_2;
+    private IntUnaryOperator[] inner_4;
+
+    private IntUnaryOperator[] lambda_1;
+    private IntUnaryOperator[] lambda_2;
+    private IntUnaryOperator[] lambda_4;
+
+    private IntUnaryOperator[] unbounded_mref_1;
+    private IntUnaryOperator[] unbounded_mref_2;
+    private IntUnaryOperator[] unbounded_mref_4;
+
+    private IntUnaryOperator[] bounded_mref_1;
+    private IntUnaryOperator[] bounded_mref_2;
+    private IntUnaryOperator[] bounded_mref_4;
+
+    @Setup(Level.Trial)
+    public void setup() {
+        setup_inner();
+        setup_lambda();
+        setup_unbounded_mref();
+        setup_bounded_mref();
+    }
+
+    private void setup_inner() {
+        inner_4 =  new IntUnaryOperator[] {
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + 1;
+                }
+            },
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + 2;
+                }
+            },
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + 3;
+                }
+            },
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + 4;
+                }
+            },
+        };
+        inner_2 =  new IntUnaryOperator[] { inner_4[0], inner_4[1], inner_4[0], inner_4[1], };
+        inner_1 =  new IntUnaryOperator[] { inner_4[0], inner_4[0], inner_4[0], inner_4[0], };
+    }
+
+    private void setup_lambda() {
+        lambda_4 =  new IntUnaryOperator[] {
+                x -> x + 1,
+                x -> x + 2,
+                x -> x + 3,
+                x -> x + 4,
+        };
+        lambda_2 =  new IntUnaryOperator[] { lambda_4[0], lambda_4[1], lambda_4[0], lambda_4[1], };
+        lambda_1 =  new IntUnaryOperator[] { lambda_4[0], lambda_4[0], lambda_4[0], lambda_4[0], };
+    }
+
+    public static int func1(int x) {
+        return x + 1;
+    }
+
+    public static int func2(int x) {
+        return x + 2;
+    }
+
+    public static int func3(int x) {
+        return x + 3;
+    }
+
+    public static int func4(int x) {
+        return x + 4;
+    }
+
+    private void setup_unbounded_mref() {
+        unbounded_mref_4 =  new IntUnaryOperator[] {
+                Morph0::func1,
+                Morph0::func2,
+                Morph0::func3,
+                Morph0::func4,
+        };
+        unbounded_mref_2 =  new IntUnaryOperator[] { unbounded_mref_4[0], unbounded_mref_4[1], unbounded_mref_4[0], unbounded_mref_4[1], };
+        unbounded_mref_1 =  new IntUnaryOperator[] { unbounded_mref_4[0], unbounded_mref_4[0], unbounded_mref_4[0], unbounded_mref_4[0], };
+    }
+
+    public int ifunc1(int x) {
+        return x + 1;
+    }
+
+    public int ifunc2(int x) {
+        return x + 2;
+    }
+
+    public int ifunc3(int x) {
+        return x + 3;
+    }
+
+    public int ifunc4(int x) {
+        return x + 4;
+    }
+
+    private void setup_bounded_mref() {
+        bounded_mref_4 =  new IntUnaryOperator[] {
+                this::ifunc1,
+                this::ifunc2,
+                this::ifunc3,
+                this::ifunc4,
+        };
+        bounded_mref_2 =  new IntUnaryOperator[] { bounded_mref_4[0], bounded_mref_4[1], bounded_mref_4[0], bounded_mref_4[1], };
+        bounded_mref_1 =  new IntUnaryOperator[] { bounded_mref_4[0], bounded_mref_4[0], bounded_mref_4[0], bounded_mref_4[0], };
+    }
+
+    public void process(Blackhole bh, IntUnaryOperator[] operations) {
+        for (int i = 0; i < LIMIT; i++) {
+            for (IntUnaryOperator op : operations) {
+                bh.consume(op.applyAsInt(i));
+            }
+        }
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner1(Blackhole bh) {
+        process(bh, inner_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner2(Blackhole bh) {
+        process(bh, inner_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner4(Blackhole bh) {
+        process(bh, inner_4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda1(Blackhole bh) {
+        process(bh, lambda_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda2(Blackhole bh) {
+        process(bh, lambda_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda4(Blackhole bh) {
+        process(bh, lambda_4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void mref1(Blackhole bh) {
+        process(bh, unbounded_mref_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void mref2(Blackhole bh) {
+        process(bh, unbounded_mref_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void mref4(Blackhole bh) {
+        process(bh, unbounded_mref_4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void mref_bnd1(Blackhole bh) {
+        process(bh, bounded_mref_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void mref_bnd2(Blackhole bh) {
+        process(bh, bounded_mref_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void mref_bnd4(Blackhole bh) {
+        process(bh, bounded_mref_4);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Morph1.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * evaluates N-morphic invocation costs.
+ * N different lambdas each capture 1 variable
+ *
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Morph1 {
+
+
+    private static final int LIMIT = 16536;
+    private static final int OPS = 4;
+    private static final int OPERATIONS = OPS*LIMIT;
+
+    // <source of functional interface>_N; where N - how many different targets
+    private IntUnaryOperator[] inner_1;
+    private IntUnaryOperator[] inner_2;
+    private IntUnaryOperator[] inner_4;
+
+    private IntUnaryOperator[] lambda_1;
+    private IntUnaryOperator[] lambda_2;
+    private IntUnaryOperator[] lambda_4;
+
+    @Setup(Level.Trial)
+    public void setup() {
+        setup_inner(1,2,3,4);
+        setup_lambda(1,2,3,4);
+    }
+
+    private void setup_inner(int a, int b, int c, int d) {
+        inner_4 =  new IntUnaryOperator[] {
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + a;
+                }
+            },
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + b;
+                }
+            },
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + c;
+                }
+            },
+            new IntUnaryOperator() {
+                @Override
+                public int applyAsInt(int x) {
+                    return x + d;
+                }
+            },
+        };
+        inner_2 =  new IntUnaryOperator[] { inner_4[0], inner_4[1], inner_4[0], inner_4[1], };
+        inner_1 =  new IntUnaryOperator[] { inner_4[0], inner_4[0], inner_4[0], inner_4[0], };
+    }
+
+    private void setup_lambda(int a, int b, int c, int d) {
+        lambda_4 =  new IntUnaryOperator[] {
+                x -> x + a,
+                x -> x + b,
+                x -> x + c,
+                x -> x + d,
+        };
+        lambda_2 =  new IntUnaryOperator[] { lambda_4[0], lambda_4[1], lambda_4[0], lambda_4[1], };
+        lambda_1 =  new IntUnaryOperator[] { lambda_4[0], lambda_4[0], lambda_4[0], lambda_4[0], };
+    }
+
+    public void process(Blackhole bh, IntUnaryOperator[] operations) {
+        for (int i = 0; i < LIMIT; i++) {
+            for (IntUnaryOperator op : operations) {
+                bh.consume(op.applyAsInt(i));
+            }
+        }
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner1(Blackhole bh) {
+        process(bh, inner_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner2(Blackhole bh) {
+        process(bh, inner_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner4(Blackhole bh) {
+        process(bh, inner_4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda1(Blackhole bh) {
+        process(bh, lambda_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda2(Blackhole bh) {
+        process(bh, lambda_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda4(Blackhole bh) {
+        process(bh, lambda_4);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lambda/invoke/Morph2.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lambda.invoke;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * evaluates N-morphic invocation costs.
+ * the same lambda capture different variables
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Morph2 {
+
+
+    private static final int LIMIT = 16536;
+    private static final int OPS = 4;
+    private static final int OPERATIONS = OPS*LIMIT;
+
+    // <source of functional interface>_N; where N - how many different targets
+    private IntUnaryOperator[] inner_1;
+    private IntUnaryOperator[] inner_2;
+    private IntUnaryOperator[] inner_4;
+
+    private IntUnaryOperator[] lambda_1;
+    private IntUnaryOperator[] lambda_2;
+    private IntUnaryOperator[] lambda_4;
+
+    @Setup(Level.Trial)
+    public void setup() {
+        setup_inner(1,2,3,4);
+        setup_lambda(1,2,3,4);
+    }
+
+    private void setup_inner(int a, int b, int c, int d) {
+        inner_4 =  new IntUnaryOperator[] {
+                makeInner(a),
+                makeInner(b),
+                makeInner(c),
+                makeInner(d),
+        };
+        inner_2 =  new IntUnaryOperator[] { inner_4[0], inner_4[1], inner_4[0], inner_4[1], };
+        inner_1 =  new IntUnaryOperator[] { inner_4[0], inner_4[0], inner_4[0], inner_4[0], };
+    }
+
+    private IntUnaryOperator makeInner(final int a) {
+        return new IntUnaryOperator() {
+            @Override
+            public int applyAsInt(int x) {
+                return x + a;
+            }
+        };
+    }
+
+    private void setup_lambda(int a, int b, int c, int d) {
+        lambda_4 =  new IntUnaryOperator[] {
+                makeLambda(a),
+                makeLambda(b),
+                makeLambda(c),
+                makeLambda(d),
+        };
+        lambda_2 =  new IntUnaryOperator[] { lambda_4[0], lambda_4[1], lambda_4[0], lambda_4[1], };
+        lambda_1 =  new IntUnaryOperator[] { lambda_4[0], lambda_4[0], lambda_4[0], lambda_4[0], };
+    }
+
+    private IntUnaryOperator makeLambda(int a) {
+        return x -> x + a;
+    }
+
+    public void process(Blackhole bh, IntUnaryOperator[] operations) {
+        for (int i = 0; i < LIMIT; i++) {
+            for (IntUnaryOperator op : operations) {
+                bh.consume(op.applyAsInt(i));
+            }
+        }
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner1(Blackhole bh) {
+        process(bh, inner_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner2(Blackhole bh) {
+        process(bh, inner_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void inner4(Blackhole bh) {
+        process(bh, inner_4);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda1(Blackhole bh) {
+        process(bh, lambda_1);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda2(Blackhole bh) {
+        process(bh, lambda_2);
+    }
+
+    @Benchmark
+    @OperationsPerInvocation(OPERATIONS)
+    public void lambda4(Blackhole bh) {
+        process(bh, lambda_4);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/InstanceOf.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests various usages of instanceof.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class InstanceOf {
+
+    private static final int NOOFOBJECTS = 100;
+    private static final int NULLRATIO = 3;
+
+    public Date[] dateArray;
+    public Object[] objectArray;
+
+    @Setup
+    public void setup() {
+        dateArray = new Date[NOOFOBJECTS * NULLRATIO];
+        for (int i = 0; i < NOOFOBJECTS * NULLRATIO; i += NULLRATIO) {
+            dateArray[i] = new Date();
+        }
+        objectArray = dateArray;
+    }
+
+    /**
+     * Performs "instanceof Cloneable" on objects that definitely are of that interface. It is not clear however whether
+     * the objects are null or not, therefore a simple nullcheck is all that should be left of here.
+     */
+    @Benchmark
+    @OperationsPerInvocation((NOOFOBJECTS * NULLRATIO))
+    public int instanceOfInterfacePartialRemove() {
+        int dummy = 0;
+        Date[] localArray = dateArray;
+        for (int i = 0; i < NOOFOBJECTS * NULLRATIO; i++) {
+            if (localArray[i] instanceof Cloneable) {
+                dummy++;
+            }
+        }
+        return dummy;
+    }
+
+    /**
+     * Performs three serial instanceof statements on the same object for three different interfaces. The objects are
+     * 50% null, and all non-null are instanceof the last interface.
+     */
+    @Benchmark
+    @OperationsPerInvocation((NOOFOBJECTS * NULLRATIO))
+    public int instanceOfInterfaceSerial() {
+        int dummy = 0;
+        Object[] localArray = objectArray;
+        for (int i = 0; i < NOOFOBJECTS * NULLRATIO; i++) {
+            if (localArray[i] instanceof Runnable) {
+                dummy += 1000;
+            } else if (localArray[i] instanceof CharSequence) {
+                dummy += 2000;
+            } else if (localArray[i] instanceof Serializable) {
+                dummy++;
+            }
+        }
+        return dummy;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/LockUnlock.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * Benchmark class for simple lock unlock tests. Nothing big should ever go into this class.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class LockUnlock {
+
+    @Param("100")
+    private int innerCount;
+
+    public Object lockObject1;
+    public Object lockObject2;
+    public int factorial;
+    public int dummyInt1;
+    public int dummyInt2;
+
+    @Setup
+    public void setup() {
+        lockObject1 = new Object();
+        lockObject2 = new Object();
+        dummyInt1 = 47;
+        dummyInt2 = 11; // anything
+    }
+
+    /** Perform a synchronized on a local object within a loop. */
+    @Benchmark
+    public void testSimpleLockUnlock() {
+        Object localObject = lockObject1;
+        for (int i = 0; i < innerCount; i++) {
+            synchronized (localObject) {
+                dummyInt1++;
+                dummyInt2++;
+            }
+        }
+    }
+
+    /** Perform a recursive synchronized on a local object within a loop. */
+    @Benchmark
+    public void testRecursiveLockUnlock() {
+        Object localObject = lockObject1;
+        for (int i = 0; i < innerCount; i++) {
+            synchronized (localObject) {
+                synchronized (localObject) {
+                    dummyInt1++;
+                    dummyInt2++;
+                }
+            }
+        }
+    }
+
+    /** Perform two synchronized after each other on the same local object. */
+    @Benchmark
+    public void testSerialLockUnlock() {
+        Object localObject = lockObject1;
+        for (int i = 0; i < innerCount; i++) {
+            synchronized (localObject) {
+                dummyInt1++;
+            }
+            synchronized (localObject) {
+                dummyInt2++;
+            }
+        }
+    }
+
+    /**
+     * Performs recursive synchronizations on the same local object.
+     * <p/>
+     * Result is 3628800
+     */
+    @Benchmark
+    public void testRecursiveSynchronization() {
+        factorial = fact(10);
+    }
+
+    private synchronized int fact(int n) {
+        if (n == 0) {
+            return 1;
+        } else {
+            return fact(n - 1) * n;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/vm/lang/Throw.java	Fri Nov 16 23:39:51 2018 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+package org.openjdk.bench.vm.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests throwing exceptions.
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class Throw {
+
+    public static boolean alwaysTrue = true;
+    private static Object nullObject = null;
+    public Object useObject = new Object();
+
+    @Benchmark
+    public void throwSyncException(Blackhole bh) {
+        try {
+            throwingMethod();
+        } catch (Exception ex) {
+            bh.consume(useObject);
+        }
+    }
+
+    @Benchmark
+    public void throwASyncException(Blackhole bh) {
+        try {
+            throwNullpointer();
+        } catch (Exception ex) {
+            bh.consume(useObject);
+        }
+    }
+
+    @Benchmark
+    public void throwSyncExceptionUseException(Blackhole bh) {
+        try {
+            throwingMethod();
+        } catch (Exception ex) {
+            bh.consume(ex);
+        }
+    }
+
+    @Benchmark
+    public void throwSyncExceptionUseMessage(Blackhole bh) {
+        try {
+            throwingMethod();
+        } catch (Exception ex) {
+            bh.consume(ex.getMessage());
+        }
+    }
+
+    @Benchmark
+    public void throwSyncExceptionUseStacktrace(Blackhole bh) {
+        try {
+            throwingMethod();
+        } catch (Exception ex) {
+            bh.consume(ex.getStackTrace());
+        }
+    }
+
+    @Benchmark
+    public void throwWith16Frames(Blackhole bh) {
+        try {
+            throwingMethod(16);
+        } catch (Exception ex) {
+            bh.consume(useObject);
+        }
+    }
+
+    @Benchmark
+    public void throwWith32Frames(Blackhole bh) {
+        try {
+            throwingMethod(32);
+        } catch (Exception ex) {
+            bh.consume(useObject);
+        }
+    }
+
+    @Benchmark
+    public void throwWith64Frames(Blackhole bh) {
+        try {
+            throwingMethod(64);
+        } catch (Exception ex) {
+            bh.consume(useObject);
+        }
+    }
+
+    public void throwingMethod() throws Exception {
+        if (alwaysTrue) {
+            throw new Exception();
+        }
+    }
+
+    public void throwingMethod(int i) throws Exception {
+        if (i == 0) {
+            throw new Exception();
+        }
+        throwingMethod(i - 1);
+    }
+
+    public void throwNullpointer() {
+        nullObject.hashCode();
+    }
+}