http-client-branch: merge with default http-client-branch
authorchegar
Thu, 07 Dec 2017 11:54:55 +0000
branchhttp-client-branch
changeset 55973 4d9b002587db
parent 55972 3fe2ae6d97a4 (current diff)
parent 48202 309dbeb79657 (diff)
child 55977 a31a16b95f6f
http-client-branch: merge with default
src/hotspot/share/classfile/vmSymbols_ext.hpp
src/hotspot/share/gc/g1/hSpaceCounters.cpp
src/hotspot/share/gc/g1/hSpaceCounters.hpp
src/hotspot/share/services/g1MemoryPool.cpp
src/hotspot/share/services/g1MemoryPool.hpp
src/hotspot/share/services/jmm.h
src/hotspot/share/services/psMemoryPool.cpp
src/hotspot/share/services/psMemoryPool.hpp
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIA64.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/ia64/LinuxIA64ThreadContext.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64Thread.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64ThreadContext.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64ThreadFactory.java
src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncEvent.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AuthenticationFilter.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/BufferingSubscriber.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ConnectionPool.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/CookieFilter.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Exchange.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/FilterFactory.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HeaderParser.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1AsyncReceiver.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1Exchange.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1Request.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http1Response.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2ClientImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientBuilderImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientFacade.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpHeaders.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpRequest.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpRequestBuilderImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpRequestImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponse.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponseImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ImmutableHeaders.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiExchange.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiMapResult.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainHttpConnection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PullPublisher.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PushGroup.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/RawChannelImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/RedirectFilter.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/RequestPublishers.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Response.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseContent.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseSubscribers.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLDelegate.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SocketTube.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Stream.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WebSocket.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WindowController.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/WindowUpdateSender.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/ByteBufferReference.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/ConnectionExpiredException.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/DebugLogger.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/FlowTube.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/HttpHeadersImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Log.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/MinimalFuture.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/SSLFlowDelegate.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/SSLTube.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/SequentialScheduler.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/SubscriberWrapper.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Utils.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/ContinuationFrame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/DataFrame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/ErrorFrame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/FramesDecoder.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/FramesEncoder.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/HeaderFrame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/HeadersFrame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/Http2Frame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/frame/PushPromiseFrame.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/HPACK.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/HeaderTable.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/BuilderImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/MessageStreamConsumer.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/OpeningHandshake.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/Receiver.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/Transmitter.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/TransportSupplier.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketImpl.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketRequest.java
src/jdk.incubator.httpclient/share/classes/module-info.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/RawAddressNode.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Constants.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrap.java
src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java
test/hotspot/jtreg/gc/metaspace/PerfCounter.java
test/hotspot/jtreg/gc/metaspace/PerfCounters.java
test/jdk/ProblemList.txt
test/jdk/java/net/httpclient/AbstractNoBody.java
test/jdk/java/net/httpclient/BasicAuthTest.java
test/jdk/java/net/httpclient/BufferingSubscriberCancelTest.java
test/jdk/java/net/httpclient/BufferingSubscriberErrorCompleteTest.java
test/jdk/java/net/httpclient/BufferingSubscriberTest.java
test/jdk/java/net/httpclient/CancelledResponse.java
test/jdk/java/net/httpclient/HeadersTest1.java
test/jdk/java/net/httpclient/HeadersTest2.java
test/jdk/java/net/httpclient/HttpClientBuilderTest.java
test/jdk/java/net/httpclient/HttpInputStreamTest.java
test/jdk/java/net/httpclient/HttpRequestBuilderTest.java
test/jdk/java/net/httpclient/HttpResponseInputStreamTest.java
test/jdk/java/net/httpclient/ManyRequests.java
test/jdk/java/net/httpclient/ManyRequestsLegacy.java
test/jdk/java/net/httpclient/MockServer.java
test/jdk/java/net/httpclient/MultiAuthTest.java
test/jdk/java/net/httpclient/NoBodyPartOne.java
test/jdk/java/net/httpclient/NoBodyPartTwo.java
test/jdk/java/net/httpclient/ProxyServer.java
test/jdk/java/net/httpclient/RequestBodyTest.java
test/jdk/java/net/httpclient/RequestBuilderTest.java
test/jdk/java/net/httpclient/SmokeTest.java
test/jdk/java/net/httpclient/SplitResponse.java
test/jdk/java/net/httpclient/TimeoutBasic.java
test/jdk/java/net/httpclient/examples/WebSocketExample.java
test/jdk/java/net/httpclient/http2/BasicTest.java
test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java
test/jdk/java/net/httpclient/http2/RedirectTest.java
test/jdk/java/net/httpclient/http2/ServerPush.java
test/jdk/java/net/httpclient/http2/TLSConnection.java
test/jdk/java/net/httpclient/http2/Timeout.java
test/jdk/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/HeaderTableTest.java
test/jdk/java/net/httpclient/http2/server/BodyInputStream.java
test/jdk/java/net/httpclient/http2/server/BodyOutputStream.java
test/jdk/java/net/httpclient/http2/server/ExceptionallyCloseable.java
test/jdk/java/net/httpclient/http2/server/Http2RedirectHandler.java
test/jdk/java/net/httpclient/http2/server/Http2TestExchange.java
test/jdk/java/net/httpclient/http2/server/Http2TestExchangeImpl.java
test/jdk/java/net/httpclient/http2/server/Http2TestServer.java
test/jdk/java/net/httpclient/http2/server/Http2TestServerConnection.java
test/jdk/java/net/httpclient/http2/server/Queue.java
test/jdk/java/net/httpclient/security/0.policy
test/jdk/java/net/httpclient/security/1.policy
test/jdk/java/net/httpclient/security/10.policy
test/jdk/java/net/httpclient/security/11.policy
test/jdk/java/net/httpclient/security/12.policy
test/jdk/java/net/httpclient/security/14.policy
test/jdk/java/net/httpclient/security/15.policy
test/jdk/java/net/httpclient/security/2.policy
test/jdk/java/net/httpclient/security/3.policy
test/jdk/java/net/httpclient/security/4.policy
test/jdk/java/net/httpclient/security/5.policy
test/jdk/java/net/httpclient/security/6.policy
test/jdk/java/net/httpclient/security/7.policy
test/jdk/java/net/httpclient/security/8.policy
test/jdk/java/net/httpclient/security/9.policy
test/jdk/java/net/httpclient/security/Driver.java
test/jdk/java/net/httpclient/security/Security.java
test/jdk/java/net/httpclient/security/filePerms/httpclient.policy
test/jdk/java/net/httpclient/websocket/BuildingWebSocketDriver.java
test/jdk/java/net/httpclient/websocket/ConnectionHandover.java
test/jdk/java/net/httpclient/websocket/HeaderWriterDriver.java
test/jdk/java/net/httpclient/websocket/MaskerDriver.java
test/jdk/java/net/httpclient/websocket/ReaderDriver.java
test/jdk/java/net/httpclient/websocket/SendingTestDriver.java
test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/BuildingWebSocketTest.java
test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockListener.java
test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/MockReceiver.java
test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/ReceivingTest.java
test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/SendingTest.java
test/jdk/java/net/httpclient/websocket/jdk.incubator.httpclient/jdk/incubator/http/internal/websocket/TestSupport.java
test/jdk/java/net/httpclient/websocket/security/WSURLPermissionTest.java
test/jdk/java/net/httpclient/websocket/security/httpclient.policy
test/jdk/java/net/httpclient/whitebox/Driver.java
test/jdk/java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java
test/jdk/java/net/httpclient/whitebox/SSLTubeTestDriver.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/AbstractSSLTubeTest.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/ConnectionPoolTest.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/FlowTest.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/Http1HeaderParserTest.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/SSLEchoTubeTest.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/SSLTubeTest.java
test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/SelectorTest.java
test/jdk/jdk/internal/misc/JavaLangAccess/NewUnsafeString.java
--- a/make/CompileInterimLangtools.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/CompileInterimLangtools.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -69,8 +69,8 @@
           Standard.java, \
       EXTRA_FILES := $(BUILDTOOLS_OUTPUTDIR)/gensrc/$1.interim/module-info.java, \
       COPY := .gif .png .xml .css .js javax.tools.JavaCompilerTool, \
-      BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_modules/$1.interim, \
-      ADD_JAVAC_FLAGS := --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_modules \
+      BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules/$1.interim, \
+      ADD_JAVAC_FLAGS := --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules \
           $$(INTERIM_LANGTOOLS_ADD_EXPORTS) \
           -Xlint:-module, \
   ))
--- a/make/CompileInterimRmic.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/CompileInterimRmic.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -65,10 +65,10 @@
     EXCLUDE_FILES := $(TOPDIR)/src/jdk.rmic/share/classes/module-info.java, \
     EXTRA_FILES := $(BUILDTOOLS_OUTPUTDIR)/gensrc/jdk.rmic.interim/module-info.java, \
     INCLUDES := $(RMIC_PKGS), \
-    BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_modules/jdk.rmic.interim, \
+    BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_rmic_modules/jdk.rmic.interim, \
     COPY := .properties, \
     ADD_JAVAC_FLAGS := \
-        --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_modules \
+        --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_rmic_modules \
         --add-modules java.corba \
         --add-exports java.corba/com.sun.corba.se.impl.util=jdk.rmic.interim \
         $(INTERIM_RMIC_ADD_EXPORTS), \
--- a/make/CreateJmods.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/CreateJmods.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,4 @@
-
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, 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
@@ -33,6 +32,8 @@
   $(error MODULE must be set when calling CreateJmods.gmk)
 endif
 
+$(eval $(call IncludeCustomExtension, CreateJmods.gmk))
+
 ################################################################################
 
 JMODS_DIR := $(IMAGES_OUTPUTDIR)/jmods
--- a/make/Help.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/Help.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -115,6 +115,13 @@
         # We need a dummy rule otherwise make will complain
 	@true
 
-ALL_GLOBAL_TARGETS := help print-configurations
+# This is not really a "help" target, but it is a global target, and those are
+# all contained in this file.
+run-test-prebuilt:
+	@( cd $(topdir) && \
+	    $(MAKE) --no-print-directory -r -R -I make/common/ -f make/RunTestsPrebuilt.gmk \
+	    run-test-prebuilt TEST="$(TEST)" )
+
+ALL_GLOBAL_TARGETS := help print-configurations run-test-prebuilt
 
 .PHONY: $(ALL_GLOBAL_TARGETS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/RunTestsPrebuilt.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,283 @@
+#
+# Copyright (c) 2017, 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.
+#
+
+################################################################################
+# Initial bootstrapping, copied and stripped down from Makefile and Init.gmk
+################################################################################
+
+# In Cygwin, the MAKE variable gets prepended with the current directory if the
+# make executable is called using a Windows mixed path (c:/cygwin/bin/make.exe).
+ifneq ($(findstring :, $(MAKE)), )
+  export MAKE := $(patsubst $(CURDIR)%, %, $(patsubst $(CURDIR)/%, %, $(MAKE)))
+endif
+
+# Locate this Makefile
+ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),)
+  makefile_path := $(CURDIR)/$(strip $(lastword $(MAKEFILE_LIST)))
+else
+  makefile_path := $(lastword $(MAKEFILE_LIST))
+endif
+TOPDIR := $(strip $(patsubst %/make/, %, $(dir $(makefile_path))))
+
+################################################################################
+# Functions
+################################################################################
+
+# Setup a required or optional variable, and/or check that it is properly
+# given.
+# Note: No spaces are allowed around the arguments.
+#
+# $1: The name of the argument
+# $2: The default value, if any, or OPTIONAL (do not provide a default but
+#     do not exit if it is missing)
+# $3: If NO_CHECK, disable checking for target file/directory existence
+define SetupVariable
+  ifeq ($$($1), )
+    ifeq ($2, )
+      $$(info Error: Prebuilt variable $1 is missing, needed for run-tests-prebuilt)
+      $$(error Cannot continue.)
+    else ifeq ($2, OPTIONAL)
+      ifneq ($$(findstring $$(LOG), info debug trace), )
+        $$(info Prebuilt variable $1 is not provided)
+      endif
+    else
+      ifneq ($$(findstring $$(LOG), info debug trace), )
+        $$(info Prebuilt variable $1=$2 (default value))
+      endif
+      $1:=$2
+    endif
+  else
+    ifneq ($$(findstring $$(LOG), info debug trace), )
+      $$(info Prebuilt variable $1=$$($1))
+    endif
+  endif
+  # If $1 has a value (is not optional), and $3 is not set (to NO_CHECK),
+  # and if wildcard is empty, then complain that the file is missing.
+  ifeq ($$(strip $$(if $$($1), , OPTIONAL) $$(wildcard $$($1)) $3), )
+    $$(info Error: Prebuilt variable $1 points to missing file/directory:)
+    $$(info '$$($1)')
+    $$(error Cannot continue.)
+  endif
+endef
+
+# Create an ephemeral spec file
+#
+# $1: The output file name
+# $2..$N: The lines to output to the file
+define CreateNewSpec
+  $(if $(strip $(26)), \
+    $(error Internal makefile error: \
+      Too many arguments to macro, please update CreateNewSpec in RunTestsPrebuilt.gmk) \
+  ) \
+  $(shell $(RM) $1) \
+  $(foreach i, $(call sequence, 2, 25), \
+    $(if $(strip $($i)), \
+      $(call AppendFile, $(strip $($i)), $1) \
+    ) \
+  )
+endef
+
+################################################################################
+# Check input and setup basic buildsystem support
+################################################################################
+
+# Verify that user has given correct additional input.
+
+# These variables are absolutely necessary
+$(eval $(call SetupVariable,OUTPUTDIR))
+$(eval $(call SetupVariable,BOOT_JDK))
+$(eval $(call SetupVariable,JT_HOME))
+
+# These can have default values based on the ones above
+$(eval $(call SetupVariable,JDK_IMAGE_DIR,$(OUTPUTDIR)/images/jdk))
+$(eval $(call SetupVariable,TEST_IMAGE_DIR,$(OUTPUTDIR)/images/test))
+
+# Provide default values for tools that we need
+$(eval $(call SetupVariable,MAKE,make,NO_CHECK))
+$(eval $(call SetupVariable,BASH,bash,NO_CHECK))
+
+# Check optional variables
+$(eval $(call SetupVariable,JIB_JAR,OPTIONAL))
+
+# Now that we have verified that we have the required variables available, we
+# can include the prebuilt spec file ourselves, without an ephemeral spec
+# wrapper. This is required so we can include MakeBase which is needed for
+# CreateNewSpec.
+HAS_SPEC :=
+include $(TOPDIR)/make/InitSupport.gmk
+
+$(eval $(call CheckDeprecatedEnvironment))
+$(eval $(call CheckInvalidMakeFlags))
+$(eval $(call ParseLogLevel))
+
+SPEC := $(TOPDIR)/make/RunTestsPrebuiltSpec.gmk
+include $(SPEC)
+include $(TOPDIR)/make/common/MakeBase.gmk
+
+################################################################################
+# Determine what platform we're running on
+################################################################################
+UNAME := uname
+
+# Get OS name from uname (Cygwin inexplicably adds _NT-x.x)
+UNAME_OS := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
+
+ifeq ($(UNAME_OS), CYGWIN)
+  OPENJDK_TARGET_OS := windows
+  OPENJDK_TARGET_OS_TYPE := windows
+  OPENJDK_TARGET_OS_ENV := windows.cygwin
+else
+  OPENJDK_TARGET_OS_TYPE:=unix
+  ifeq ($(UNAME_OS), Linux)
+    OPENJDK_TARGET_OS := linux
+  else ifeq ($(UNAME_OS), Darwin)
+    OPENJDK_TARGET_OS := macosx
+  else ifeq ($(UNAME_OS), SunOS)
+    OPENJDK_TARGET_OS := solaris
+  else
+    OPENJDK_TARGET_OS := $(UNAME_OS)
+  endif
+  OPENJDK_TARGET_OS_ENV := $(OPENJDK_TARGET_OS)
+endif
+
+# Assume little endian unless otherwise specified
+OPENJDK_TARGET_CPU_ENDIAN := little
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+  # On solaris, use uname -p
+  UNAME_CPU := $(shell $(UNAME) -p)
+  # Assume 64-bit platform
+  OPENJDK_TARGET_CPU_BITS := 64
+  ifeq ($(UNAME_CPU), i386)
+    OPENJDK_TARGET_CPU := x86_64
+  else ifeq ($(UNAME_CPU), sparc)
+    OPENJDK_TARGET_CPU := sparcv9
+    OPENJDK_TARGET_CPU_ENDIAN := big
+  else
+    OPENJDK_TARGET_CPU := $(UNAME_CPU)
+  endif
+else
+  # ... all others use uname -m
+  UNAME_CPU := $(shell $(UNAME) -m)
+  ifeq ($(UNAME_CPU), i686)
+    OPENJDK_TARGET_CPU := x86
+    OPENJDK_TARGET_CPU_BITS := 32
+  else
+    # Assume all others are 64-bit. We use the same CPU name as uname for
+    # at least x86_64 and aarch64.
+    OPENJDK_TARGET_CPU := $(UNAME_CPU)
+    OPENJDK_TARGET_CPU_BITS := 64
+  endif
+endif
+
+OPENJDK_TARGET_CPU_ARCH := $(OPENJDK_TARGET_CPU)
+ifeq ($(OPENJDK_TARGET_CPU), x86_64)
+  OPENJDK_TARGET_CPU_ARCH := x86
+else ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
+  OPENJDK_TARGET_CPU_ARCH := sparc
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  ifeq ($(wildcard $(TEST_IMAGE_DIR)/bin/fixpath.exe), )
+    $$(info Error: fixpath is missing from test image '$(TEST_IMAGE_DIR)')
+    $$(error Cannot continue.)
+  endif
+  FIXPATH := $(TEST_IMAGE_DIR)/bin/fixpath.exe -c
+  PATH_SEP:=;
+else
+  FIXPATH :=
+  PATH_SEP:=:
+endif
+
+# Check number of cores
+ifeq ($(OPENJDK_TARGET_OS), linux)
+    NUM_CORES := $(shell $(CAT) /proc/cpuinfo  | $(GREP) -c processor)
+else ifeq ($(OPENJDK_TARGET_OS), macosx)
+    NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu)
+else ifeq ($(OPENJDK_TARGET_OS), solaris)
+    NUM_CORES := $(shell LC_MESSAGES=C /usr/sbin/psrinfo -v | $(GREP) -c on-line)
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+    NUM_CORES := $(NUMBER_OF_PROCESSORS)
+else
+    NUM_CORES := 1
+endif
+
+################################################################################
+# Generate the ephemeral spec file
+################################################################################
+
+# Now we can include additional custom support.
+# This might define CUSTOM_NEW_SPEC_LINE
+ifneq ($(CUSTOM_MAKE_DIR), )
+  include $(CUSTOM_MAKE_DIR)/RunTestsPrebuilt.gmk
+endif
+
+NEW_SPEC := $(OUTPUTDIR)/run-test-spec.gmk
+
+$(call CreateNewSpec, $(NEW_SPEC), \
+    # Generated file -- do not edit!, \
+    SPEC := $(NEW_SPEC), \
+    TOPDIR := $(TOPDIR), \
+    OUTPUTDIR := $(OUTPUTDIR), \
+    BOOT_JDK := $(BOOT_JDK), \
+    JT_HOME := $(JT_HOME), \
+    JDK_IMAGE_DIR := $(JDK_IMAGE_DIR), \
+    TEST_IMAGE_DIR := $(TEST_IMAGE_DIR), \
+    MAKE := $(MAKE), \
+    BASH := $(BASH), \
+    JIB_JAR := $(JIB_JAR), \
+    FIXPATH := $(FIXPATH), \
+    PATH_SEP := $(PATH_SEP), \
+    OPENJDK_TARGET_OS := $(OPENJDK_TARGET_OS), \
+    OPENJDK_TARGET_OS_TYPE := $(OPENJDK_TARGET_OS_TYPE), \
+    OPENJDK_TARGET_OS_ENV := $(OPENJDK_TARGET_OS_ENV), \
+    OPENJDK_TARGET_CPU := $(OPENJDK_TARGET_CPU), \
+    OPENJDK_TARGET_CPU_ARCH := $(OPENJDK_TARGET_CPU_ARCH), \
+    OPENJDK_TARGET_CPU_BITS := $(OPENJDK_TARGET_CPU_BITS), \
+    OPENJDK_TARGET_CPU_ENDIAN := $(OPENJDK_TARGET_CPU_ENDIAN), \
+    NUM_CORES := $(NUM_CORES), \
+    include $(TOPDIR)/make/RunTestsPrebuiltSpec.gmk, \
+    $(CUSTOM_NEW_SPEC_LINE), \
+)
+
+################################################################################
+# The run-test-prebuilt target
+################################################################################
+
+SPEC := $(NEW_SPEC)
+
+default: all
+
+run-test-prebuilt:
+	@$(RM) -f $(MAKESUPPORT_OUTPUTDIR)/exit-with-error
+	@cd $(TOPDIR) && $(MAKE) $(MAKE_ARGS) -f make/RunTests.gmk run-test \
+	    TEST="$(TEST)"
+	@if test -f $(MAKESUPPORT_OUTPUTDIR)/exit-with-error ; then \
+	  exit 1 ; \
+	fi
+
+all: run-test-prebuilt
+
+.PHONY: default all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/RunTestsPrebuiltSpec.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,175 @@
+#
+# Copyright (c) 2017, 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.
+#
+
+################################################################################
+# Fake minimalistic spec file for RunTestsPrebuilt.gmk.
+################################################################################
+
+define VerifyVariable
+  ifeq ($$($1), )
+    $$(info Error: Variable $1 is missing, needed by RunTestPrebuiltSpec.gmk)
+    $$(error Cannot continue.)
+  else
+    ifneq ($$(findstring $$(LOG_LEVEL), debug trace), )
+      $$(info Prebuilt variable $1=$$($1))
+    endif
+  endif
+endef
+
+# It is the responsibility of the file including us to have set these up.
+# Verify that this is correct.
+$(eval $(call VerifyVariable,SPEC))
+$(eval $(call VerifyVariable,TOPDIR))
+$(eval $(call VerifyVariable,OUTPUTDIR))
+$(eval $(call VerifyVariable,BOOT_JDK))
+$(eval $(call VerifyVariable,JT_HOME))
+$(eval $(call VerifyVariable,JDK_IMAGE_DIR))
+$(eval $(call VerifyVariable,TEST_IMAGE_DIR))
+$(eval $(call VerifyVariable,MAKE))
+$(eval $(call VerifyVariable,BASH))
+
+################################################################################
+# The "human readable" name of this configuration
+CONF_NAME := run-test-prebuilt
+
+# Number of parallel jobs to use for compilation
+JOBS ?= $(NUM_CORES)
+TEST_JOBS ?= 0
+
+# Use hard-coded values for java flags (one size, fits all!)
+JAVA_FLAGS := -Duser.language=en -Duser.country=US
+JAVA_FLAGS_BIG:= -Xms64M -Xmx1600M -XX:ThreadStackSize=1536
+JAVA_FLAGS_SMALL:= -XX:+UseSerialGC -Xms32M -Xmx512M -XX:TieredStopAtLevel=1
+BUILD_JAVA_FLAGS := $(JAVA_FLAGS_BIG)
+
+################################################################################
+# Hard-coded values copied from spec.gmk.in.
+X:=
+SPACE:=$(X) $(X)
+COMMA:=,
+MAKE_ARGS = $(MAKE_LOG_FLAGS) -r -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
+    MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" LOG_LEVEL=$(LOG_LEVEL)
+BASH_ARGS := -o pipefail -e
+SHELL := $(BASH) $(BASH_ARGS)
+
+################################################################################
+# Set some reasonable defaults for features
+DEBUG_LEVEL := release
+HOTSPOT_DEBUG_LEVEL := release
+BUILD_GTEST := true
+BUILD_FAILURE_HANDLER := true
+
+################################################################################
+# Alias some paths (that should not really be used) to our JDK image under test.
+SUPPORT_OUTPUTDIR := $(OUTPUTDIR)/support
+BUILDTOOLS_OUTPUTDIR := $(OUTPUTDIR)/buildtools
+HOTSPOT_OUTPUTDIR := $(OUTPUTDIR)/hotspot
+JDK_OUTPUTDIR := $(OUTPUTDIR)/jdk
+IMAGES_OUTPUTDIR := $(OUTPUTDIR)/images
+BUNDLES_OUTPUTDIR := $(OUTPUTDIR)/bundles
+TESTMAKE_OUTPUTDIR := $(OUTPUTDIR)/test-make
+MAKESUPPORT_OUTPUTDIR := $(OUTPUTDIR)/make-support
+BUILDJDK_OUTPUTDIR := $(OUTPUTDIR)/buildjdk
+
+JRE_IMAGE_DIR := $(JDK_IMAGE_DIR)
+
+################################################################################
+# Assume build platform is same as target platform
+OPENJDK_BUILD_OS := $(OPENJDK_TARGET_OS)
+OPENJDK_BUILD_OS_TYPE := $(OPENJDK_TARGET_OS_TYPE)
+OPENJDK_BUILD_OS_ENV := $(OPENJDK_TARGET_OS_ENV)
+
+OPENJDK_BUILD_CPU := $(OPENJDK_TARGET_CPU)
+OPENJDK_BUILD_CPU_ARCH := $(OPENJDK_TARGET_CPU_ARCH)
+OPENJDK_BUILD_CPU_BITS := $(OPENJDK_TARGET_CPU_BITS)
+OPENJDK_BUILD_CPU_ENDIAN := $(OPENJDK_TARGET_CPU_ENDIAN)
+
+################################################################################
+# Java executable definitions
+JAVA_CMD := $(BOOT_JDK)/bin/java
+JAVAC_CMD := $(BOOT_JDK)/bin/javac
+JAVAH_CMD := $(BOOT_JDK)/bin/javah
+JAR_CMD := $(BOOT_JDK)/bin/jar
+JLINK_CMD := $(JDK_OUTPUTDIR)/bin/jlink
+JMOD_CMD := $(JDK_OUTPUTDIR)/bin/jmod
+JARSIGNER_CMD := $(BOOT_JDK)/bin/jarsigner
+
+JAVA := $(FIXPATH) $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
+JAVA_SMALL := $(FIXPATH) $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
+JAVA_JAVAC := $(FIXPATH) $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
+JAVAC := $(FIXPATH) $(JAVAC_CMD)
+JAVAH := $(FIXPATH) $(JAVAH_CMD)
+JAR := $(FIXPATH) $(JAR_CMD)
+JLINK := $(FIXPATH) $(JLINK_CMD)
+JMOD := $(FIXPATH) $(JMOD_CMD)
+JARSIGNER := $(FIXPATH) $(JARSIGNER_CMD)
+
+BUILD_JAVA := $(JAVA)
+################################################################################
+# Some common tools. Assume most common name and no path.
+AWK := awk
+BASENAME := basename
+CAT := cat
+CD := cd
+CHMOD := chmod
+CP := cp
+CUT := cut
+DATE := date
+DIFF := diff
+DIRNAME := dirname
+FIND := find
+FIND_DELETE := -delete
+ECHO := echo
+EGREP := grep -E
+FGREP := grep -F
+GREP := grep
+GZIP := gzip
+HEAD := head
+LS := ls
+LN := ln
+MKDIR := mkdir
+MV := mv
+NAWK := nawk
+NICE := nice
+PATCH := patch
+PRINTF := printf
+RM := rm -f
+RMDIR := rmdir
+SED := sed
+SH := sh
+SORT := sort
+TAR := tar
+TAIL := tail
+TEE := tee
+TR := tr
+TOUCH := touch
+UNIQ := uniq
+WC := wc
+XARGS := xargs
+ZIPEXE := zip
+UNZIP := unzip
+EXPR := expr
+FILE := file
+HG := hg
--- a/make/autoconf/boot-jdk.m4	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/autoconf/boot-jdk.m4	Thu Dec 07 11:54:55 2017 +0000
@@ -353,9 +353,6 @@
 
   AC_MSG_CHECKING([flags for boot jdk java command] )
 
-  # Disable special log output when a debug build is used as Boot JDK...
-  ADD_JVM_ARG_IF_OK([-XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput],boot_jdk_jvmargs,[$JAVA])
-
   # Force en-US environment
   ADD_JVM_ARG_IF_OK([-Duser.language=en -Duser.country=US],boot_jdk_jvmargs,[$JAVA])
 
--- a/make/autoconf/generated-configure.sh	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/autoconf/generated-configure.sh	Thu Dec 07 11:54:55 2017 +0000
@@ -5159,7 +5159,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1512410983
+DATE_WHEN_GENERATED=1512479382
 
 ###############################################################################
 #
@@ -67379,23 +67379,6 @@
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command " >&5
 $as_echo_n "checking flags for boot jdk java command ... " >&6; }
 
-  # Disable special log output when a debug build is used as Boot JDK...
-
-  $ECHO "Check if jvm arg is ok: -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput" >&5
-  $ECHO "Command: $JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version" >&5
-  OUTPUT=`$JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version 2>&1`
-  FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
-  FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
-  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
-    boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput"
-    JVM_ARG_OK=true
-  else
-    $ECHO "Arg failed:" >&5
-    $ECHO "$OUTPUT" >&5
-    JVM_ARG_OK=false
-  fi
-
-
   # Force en-US environment
 
   $ECHO "Check if jvm arg is ok: -Duser.language=en -Duser.country=US" >&5
--- a/make/autoconf/spec.gmk.in	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/autoconf/spec.gmk.in	Thu Dec 07 11:54:55 2017 +0000
@@ -565,6 +565,7 @@
 
 BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
 BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
+BUILD_JAR=@FIXPATH@ $(BUILD_JDK)/bin/jar
 
 # Interim langtools and rmic modules and arguments
 INTERIM_LANGTOOLS_BASE_MODULES := java.compiler jdk.compiler jdk.javadoc
@@ -577,7 +578,7 @@
 INTERIM_LANGTOOLS_ARGS := \
     --limit-modules java.base,jdk.zipfs,$(INTERIM_LANGTOOLS_MODULES_COMMA) \
     --add-modules $(INTERIM_LANGTOOLS_MODULES_COMMA) \
-    --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_modules \
+    --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules \
     $(INTERIM_LANGTOOLS_ADD_EXPORTS) \
     #
 JAVAC_MAIN_CLASS = -m jdk.compiler.interim/com.sun.tools.javac.Main
@@ -588,8 +589,10 @@
 INTERIM_RMIC_ADD_EXPORTS := \
     --add-exports java.corba/com.sun.corba.se.impl.util=jdk.rmic.interim \
     #
-INTERIM_RMIC_ARGS := --limit-modules java.base,jdk.compiler,jdk.javadoc,java.corba \
-    --module-path $(BUILDTOOLS_OUTPUTDIR)/interim_modules \
+# Use = to delay expansion of PathList since it's not available in this file.
+INTERIM_RMIC_ARGS = --limit-modules java.base,jdk.compiler,jdk.javadoc,java.corba \
+    --module-path $(call PathList, $(BUILDTOOLS_OUTPUTDIR)/interim_rmic_modules \
+        $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules) \
     $(INTERIM_RMIC_ADD_EXPORTS) \
     #
 
--- a/make/common/JarArchive.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/common/JarArchive.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -56,6 +56,7 @@
 #       added to the archive.
 #   EXTRA_MANIFEST_ATTR:=Extra attribute to add to manifest.
 #   CHECK_COMPRESS_JAR Check the COMPRESS_JAR variable
+#   JAR_CMD:=Optionally override the jar command to use when creating the archive.
 SetupJarArchive = $(NamedParamsMacroTemplate)
 define SetupJarArchiveBody
 
@@ -65,6 +66,7 @@
   $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))
+  $$(call SetIfEmpty, $1_JAR_CMD, $$(JAR))
 
   ifeq (,$$($1_SUFFIXES))
     # No suffix was set, default to classes.
@@ -109,7 +111,7 @@
 
   # Check if this jar needs to have its index generated.
   ifneq (,$$($1_JARINDEX))
-    $1_JARINDEX = (cd $$(dir $$@) && $(JAR) -i $$(notdir $$@))
+    $1_JARINDEX = (cd $$(dir $$@) && $$($1_JAR_CMD) -i $$(notdir $$@))
   else
     $1_JARINDEX = true
   endif
@@ -189,7 +191,7 @@
   $1_UPDATE_CONTENTS=\
       if [ "`$(WC) -l $$($1_BIN)/_the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'`" -gt "0" ]; then \
         $(ECHO) "  updating" `$(WC) -l $$($1_BIN)/_the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'` files && \
-        $(JAR) $$($1_JAR_UPDATE_OPTIONS) $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents; \
+        $$($1_JAR_CMD) $$($1_JAR_UPDATE_OPTIONS) $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents; \
       fi $$(NEWLINE)
   # The s-variants of the above macros are used when the jar is created from scratch.
   # NOTICE: please leave the parentheses space separated otherwise the AIX build will break!
@@ -208,7 +210,7 @@
             | $(SED) 's|$$(src)/|-C $$(src) |g' >> \
         $$($1_BIN)/_the.$$($1_JARNAME)_contents) $$(NEWLINE) )
   endif
-  $1_SUPDATE_CONTENTS=$(JAR) $$($1_JAR_UPDATE_OPTIONS) $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents $$(NEWLINE)
+  $1_SUPDATE_CONTENTS=$$($1_JAR_CMD) $$($1_JAR_UPDATE_OPTIONS) $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents $$(NEWLINE)
 
   # Use a slightly shorter name for logging, but with enough path to identify this jar.
   $1_NAME:=$$(subst $$(OUTPUTDIR)/,,$$($1_JAR))
@@ -226,7 +228,7 @@
   endif
 
   # Include all variables of significance in the vardeps file
-  $1_VARDEPS := $(JAR) $$($1_JAR_CREATE_OPTIONS) $$($1_MANIFEST) \
+  $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)
@@ -250,7 +252,7 @@
 	  $$(if $$($1_EXTRA_MANIFEST_ATTR), \
 	    $(PRINTF) "$$($1_EXTRA_MANIFEST_ATTR)\n" >> $$($1_MANIFEST_FILE) $$(NEWLINE)) \
 	  $(ECHO) Creating $$($1_NAME) $$(NEWLINE) \
-	  $(JAR) $$($1_JAR_CREATE_OPTIONS) $$@ $$($1_MANIFEST_FILE) $$(NEWLINE) \
+	  $$($1_JAR_CMD) $$($1_JAR_CREATE_OPTIONS) $$@ $$($1_MANIFEST_FILE) $$(NEWLINE) \
 	  $$($1_SCAPTURE_CONTENTS) \
 	  $$($1_SCAPTURE_METAINF) \
 	  $$($1_SUPDATE_CONTENTS) \
--- a/make/common/MakeBase.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/common/MakeBase.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -912,6 +912,17 @@
       $(shell $(PRINTF) "%s" $(call ShellQuote, $1) > $2)
 endif
 
+# Param 1 - Text to write
+# Param 2 - File to write to
+ifeq ($(HAS_FILE_FUNCTION), true)
+  AppendFile = \
+      $(file >>$2,$(strip $1))
+else
+  # Use printf to get consistent behavior on all platforms.
+  AppendFile = \
+      $(shell $(PRINTF) "%s" $(call ShellQuote, $1) >> $2)
+endif
+
 ################################################################################
 # DependOnVariable
 #
--- a/make/conf/jib-profiles.js	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/conf/jib-profiles.js	Thu Dec 07 11:54:55 2017 +0000
@@ -779,6 +779,10 @@
         macosx_x64: "2.7.1-Xcode6.3-MacOSX10.9+1.0"
     }[input.target_platform];
 
+    var makeBinDir = (input.build_os == "windows"
+        ? input.get("gnumake", "install_path") + "/cygwin/bin"
+        : input.get("gnumake", "install_path") + "/bin");
+
     var dependencies = {
 
         boot_jdk: {
@@ -831,13 +835,13 @@
                 ? "gnumake-" + input.build_osenv_platform
                 : "gnumake-" + input.build_platform),
 
-            configure_args: (input.build_os == "windows"
-                ? "MAKE=" + input.get("gnumake", "install_path") + "/cygwin/bin/make"
-                : "MAKE=" + input.get("gnumake", "install_path") + "/bin/make"),
+            configure_args: "MAKE=" + makeBinDir + "/make",
 
-            environment_path: (input.build_os == "windows"
-                ? input.get("gnumake", "install_path") + "/cygwin/bin"
-                : input.get("gnumake", "install_path") + "/bin")
+            environment: {
+                "MAKE": makeBinDir + "/make"
+            },
+
+            environment_path: makeBinDir
         },
 
         freetype: {
--- a/make/hotspot/lib/CompileJvm.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/hotspot/lib/CompileJvm.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -59,6 +59,7 @@
     -I$(TOPDIR)/src/hotspot/share/precompiled \
     -I$(TOPDIR)/src/java.base/share/native/include \
     -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \
+    -I$(TOPDIR)/src/java.management/share/native/include \
     -I$(TOPDIR)/src/java.base/share/native/libjimage \
     #
 
--- a/make/jdk/src/classes/build/tools/jdwpgen/RootNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/jdk/src/classes/build/tools/jdwpgen/RootNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -40,6 +40,7 @@
     }
 
     void document(PrintWriter writer) {
+        writer.println("<!DOCTYPE html>");
         writer.println("<html><head><title>" + comment() + "</title></head>");
         writer.println("<body bgcolor=\"white\">");
         for (Node node : components) {
--- a/make/test/JtregNativeHotspot.gmk	Wed Dec 06 19:07:16 2017 +0000
+++ b/make/test/JtregNativeHotspot.gmk	Thu Dec 07 11:54:55 2017 +0000
@@ -79,6 +79,7 @@
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ThreadStart \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions \
+    $(TOPDIR)/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed \
     #
 
 # Add conditional directories here when needed.
@@ -110,6 +111,8 @@
     BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libAllowedFunctions := -lc
     BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libRedefineDoubleDelete := -lc
     BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHandshakeTransitionTest := -lc
+    BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHasNoEntryPoint := -lc
+    BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libReturnError := -lc
 endif
 
 ifeq ($(OPENJDK_TARGET_OS), linux)
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -985,12 +985,33 @@
   }
 
   void hint(int imm) {
-    system(0b00, 0b011, 0b0010, imm, 0b000);
+    system(0b00, 0b011, 0b0010, 0b0000, imm);
   }
 
   void nop() {
     hint(0);
   }
+
+  void yield() {
+    hint(1);
+  }
+
+  void wfe() {
+    hint(2);
+  }
+
+  void wfi() {
+    hint(3);
+  }
+
+  void sev() {
+    hint(4);
+  }
+
+  void sevl() {
+    hint(5);
+  }
+
   // we only provide mrs and msr for the special purpose system
   // registers where op1 (instr[20:19]) == 11 and, (currently) only
   // use it for FPSR n.b msr has L (instr[21]) == 0 mrs has L == 1
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -494,42 +494,6 @@
   }
 }
 
-// Rather than take a segfault when the polling page is protected,
-// explicitly check for a safepoint in progress and if there is one,
-// fake a call to the handler as if a segfault had been caught.
-void LIR_Assembler::poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info) {
-  __ mov(rscratch1, SafepointSynchronize::address_of_state());
-  __ ldrb(rscratch1, Address(rscratch1));
-  Label nope, poll;
-  __ cbz(rscratch1, nope);
-  __ block_comment("safepoint");
-  __ enter();
-  __ push(0x3, sp);                // r0 & r1
-  __ push(0x3ffffffc, sp);         // integer registers except lr & sp & r0 & r1
-  __ adr(r0, poll);
-  __ str(r0, Address(rthread, JavaThread::saved_exception_pc_offset()));
-  __ mov(rscratch1, CAST_FROM_FN_PTR(address, SharedRuntime::get_poll_stub));
-  __ blrt(rscratch1, 1, 0, 1);
-  __ maybe_isb();
-  __ pop(0x3ffffffc, sp);          // integer registers except lr & sp & r0 & r1
-  __ mov(rscratch1, r0);
-  __ pop(0x3, sp);                 // r0 & r1
-  __ leave();
-  __ br(rscratch1);
-  address polling_page(os::get_polling_page());
-  assert(os::is_poll_address(polling_page), "should be");
-  unsigned long off;
-  __ adrp(rscratch1, Address(polling_page, rtype), off);
-  __ bind(poll);
-  if (info)
-    add_debug_info_for_branch(info);  // This isn't just debug info:
-                                      // it's the oop map
-  else
-    __ code_section()->relocate(pc(), rtype);
-  __ ldrw(zr, Address(rscratch1, off));
-  __ bind(nope);
-}
-
 void LIR_Assembler::return_op(LIR_Opr result) {
   assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == r0, "word returns are in r0,");
 
@@ -549,11 +513,9 @@
   address polling_page(os::get_polling_page());
   guarantee(info != NULL, "Shouldn't be NULL");
   assert(os::is_poll_address(polling_page), "should be");
-  unsigned long off;
-  __ adrp(rscratch1, Address(polling_page, relocInfo::poll_type), off);
-  assert(off == 0, "must be");
+  __ get_polling_page(rscratch1, polling_page, relocInfo::poll_type);
   add_debug_info_for_branch(info);  // This isn't just debug info:
-  // it's the oop map
+                                    // it's the oop map
   __ read_polling_page(rscratch1, relocInfo::poll_type);
   return __ offset();
 }
--- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -51,4 +51,6 @@
 
 #define SUPPORT_RESERVED_STACK_AREA
 
+#define THREAD_LOCAL_POLL
+
 #endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -79,7 +79,7 @@
 // Clear short arrays bigger than one word in an arch-specific way
 define_pd_global(intx, InitArrayShortSize, BytesPerLong);
 
-define_pd_global(bool, ThreadLocalHandshakes, false);
+define_pd_global(bool, ThreadLocalHandshakes, true);
 
 #if defined(COMPILER1) || defined(COMPILER2)
 define_pd_global(intx, InlineSmallCode,          1000);
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -30,12 +30,13 @@
 #include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/markOop.hpp"
+#include "oops/method.hpp"
 #include "oops/methodData.hpp"
-#include "oops/method.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
+#include "runtime/safepointMechanism.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -438,13 +439,26 @@
 
 void InterpreterMacroAssembler::dispatch_base(TosState state,
                                               address* table,
-                                              bool verifyoop) {
+                                              bool verifyoop,
+                                              bool generate_poll) {
   if (VerifyActivationFrameSize) {
     Unimplemented();
   }
   if (verifyoop) {
     verify_oop(r0, state);
   }
+
+  Label safepoint;
+  address* const safepoint_table = Interpreter::safept_table(state);
+  bool needs_thread_local_poll = generate_poll &&
+    SafepointMechanism::uses_thread_local_poll() && table != safepoint_table;
+
+  if (needs_thread_local_poll) {
+    NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
+    ldr(rscratch2, Address(rthread, Thread::polling_page_offset()));
+    tbnz(rscratch2, exact_log2(SafepointMechanism::poll_bit()), safepoint);
+  }
+
   if (table == Interpreter::dispatch_table(state)) {
     addw(rscratch2, rscratch1, Interpreter::distance_from_dispatch_table(state));
     ldr(rscratch2, Address(rdispatch, rscratch2, Address::uxtw(3)));
@@ -453,10 +467,17 @@
     ldr(rscratch2, Address(rscratch2, rscratch1, Address::uxtw(3)));
   }
   br(rscratch2);
+
+  if (needs_thread_local_poll) {
+    bind(safepoint);
+    lea(rscratch2, ExternalAddress((address)safepoint_table));
+    ldr(rscratch2, Address(rscratch2, rscratch1, Address::uxtw(3)));
+    br(rscratch2);
+  }
 }
 
-void InterpreterMacroAssembler::dispatch_only(TosState state) {
-  dispatch_base(state, Interpreter::dispatch_table(state));
+void InterpreterMacroAssembler::dispatch_only(TosState state, bool generate_poll) {
+  dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll);
 }
 
 void InterpreterMacroAssembler::dispatch_only_normal(TosState state) {
@@ -468,10 +489,10 @@
 }
 
 
-void InterpreterMacroAssembler::dispatch_next(TosState state, int step) {
+void InterpreterMacroAssembler::dispatch_next(TosState state, int step, bool generate_poll) {
   // load next bytecode
   ldrb(rscratch1, Address(pre(rbcp, step)));
-  dispatch_base(state, Interpreter::dispatch_table(state));
+  dispatch_base(state, Interpreter::dispatch_table(state), generate_poll);
 }
 
 void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
@@ -1585,6 +1606,7 @@
 }
 
 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
+  assert_different_registers(obj, rscratch1);
   Label update, next, none;
 
   verify_oop(obj);
@@ -1745,6 +1767,7 @@
 }
 
 void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2) {
+  assert_different_registers(rscratch1, rscratch2, mdp, tmp1, tmp2);
   if (ProfileInterpreter && MethodData::profile_parameters()) {
     Label profile_continue, done;
 
@@ -1752,8 +1775,8 @@
 
     // Load the offset of the area within the MDO used for
     // parameters. If it's negative we're not profiling any parameters
-    ldr(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
-    tbnz(tmp1, 63, profile_continue);  // i.e. sign bit set
+    ldrw(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
+    tbnz(tmp1, 31, profile_continue);  // i.e. sign bit set
 
     // Compute a pointer to the area for parameters from the offset
     // and move the pointer to the slot for the last
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -55,7 +55,8 @@
                             bool check_exceptions);
 
   // base routine for all dispatches
-  void dispatch_base(TosState state, address* table, bool verifyoop = true);
+  void dispatch_base(TosState state, address* table,
+                     bool verifyoop = true, bool generate_poll = false);
 
  public:
   InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
@@ -165,12 +166,12 @@
   void dispatch_prolog(TosState state, int step = 0);
   void dispatch_epilog(TosState state, int step = 0);
   // dispatch via rscratch1
-  void dispatch_only(TosState state);
+  void dispatch_only(TosState state, bool generate_poll = false);
   // dispatch normal table via rscratch1 (assume rscratch1 is loaded already)
   void dispatch_only_normal(TosState state);
   void dispatch_only_noverify(TosState state);
   // load rscratch1 from [rbcp + step] and dispatch via rscratch1
-  void dispatch_next(TosState state, int step = 0);
+  void dispatch_next(TosState state, int step = 0, bool generate_poll = false);
   // load rscratch1 from [esi] and dispatch via rscratch1 and table
   void dispatch_via (TosState state, address* table);
 
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -287,6 +287,40 @@
   dsb(Assembler::SY);
 }
 
+void MacroAssembler::safepoint_poll(Label& slow_path) {
+  if (SafepointMechanism::uses_thread_local_poll()) {
+    ldr(rscratch1, Address(rthread, Thread::polling_page_offset()));
+    tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
+  } else {
+    unsigned long offset;
+    adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
+    ldrw(rscratch1, Address(rscratch1, offset));
+    assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
+    cbnz(rscratch1, slow_path);
+  }
+}
+
+// Just like safepoint_poll, but use an acquiring load for thread-
+// local polling.
+//
+// We need an acquire here to ensure that any subsequent load of the
+// global SafepointSynchronize::_state flag is ordered after this load
+// of the local Thread::_polling page.  We don't want this poll to
+// return false (i.e. not safepointing) and a later poll of the global
+// SafepointSynchronize::_state spuriously to return true.
+//
+// This is to avoid a race when we're in a native->Java transition
+// racing the code which wakes up from a safepoint.
+//
+void MacroAssembler::safepoint_poll_acquire(Label& slow_path) {
+  if (SafepointMechanism::uses_thread_local_poll()) {
+    lea(rscratch1, Address(rthread, Thread::polling_page_offset()));
+    ldar(rscratch1, rscratch1);
+    tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
+  } else {
+    safepoint_poll(slow_path);
+  }
+}
 
 void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
   // we must set sp to zero to clear frame
@@ -4336,15 +4370,26 @@
 }
 
 
+// Move the address of the polling page into dest.
+void MacroAssembler::get_polling_page(Register dest, address page, relocInfo::relocType rtype) {
+  if (SafepointMechanism::uses_thread_local_poll()) {
+    ldr(dest, Address(rthread, Thread::polling_page_offset()));
+  } else {
+    unsigned long off;
+    adrp(dest, Address(page, rtype), off);
+    assert(off == 0, "polling page must be page aligned");
+  }
+}
+
+// Move the address of the polling page into r, then read the polling
+// page.
 address MacroAssembler::read_polling_page(Register r, address page, relocInfo::relocType rtype) {
-  unsigned long off;
-  adrp(r, Address(page, rtype), off);
-  InstructionMark im(this);
-  code_section()->relocate(inst_mark(), rtype);
-  ldrw(zr, Address(r, off));
-  return inst_mark();
-}
-
+  get_polling_page(r, page, rtype);
+  return read_polling_page(r, rtype);
+}
+
+// Read the polling page.  The address of the polling page must
+// already be in r.
 address MacroAssembler::read_polling_page(Register r, relocInfo::relocType rtype) {
   InstructionMark im(this);
   code_section()->relocate(inst_mark(), rtype);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -97,6 +97,9 @@
  virtual void check_and_handle_popframe(Register java_thread);
  virtual void check_and_handle_earlyret(Register java_thread);
 
+  void safepoint_poll(Label& slow_path);
+  void safepoint_poll_acquire(Label& slow_path);
+
   // Biased locking support
   // lock_reg and obj_reg must be loaded up with the appropriate values.
   // swap_reg is killed.
@@ -995,12 +998,12 @@
   void atomic_xchgalw(Register prev, Register newv, Register addr);
 
   void orptr(Address adr, RegisterOrConstant src) {
-    ldr(rscratch2, adr);
+    ldr(rscratch1, adr);
     if (src.is_register())
-      orr(rscratch2, rscratch2, src.as_register());
+      orr(rscratch1, rscratch1, src.as_register());
     else
-      orr(rscratch2, rscratch2, src.as_constant());
-    str(rscratch2, adr);
+      orr(rscratch1, rscratch1, src.as_constant());
+    str(rscratch1, adr);
   }
 
   // A generic CAS; success or failure is in the EQ flag.
@@ -1199,6 +1202,7 @@
 
   address read_polling_page(Register r, address page, relocInfo::relocType rtype);
   address read_polling_page(Register r, relocInfo::relocType rtype);
+  void get_polling_page(Register dest, address page, relocInfo::relocType rtype);
 
   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
   void update_byte_crc32(Register crc, Register val, Register table);
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -245,6 +245,11 @@
   // mov(reg, polling_page);
   // ldr(zr, [reg, #offset]);
   //
+  // or
+  //
+  // ldr(reg, [rthread, #offset]);
+  // ldr(zr, [reg, #offset]);
+  //
   // however, we cannot rely on the polling page address load always
   // directly preceding the read from the page. C1 does that but C2
   // has to do the load and read as two independent instruction
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1664,7 +1664,7 @@
   // critical natives they are offset down.
   GrowableArray<int> arg_order(2 * total_in_args);
   VMRegPair tmp_vmreg;
-  tmp_vmreg.set1(r19->as_VMReg());
+  tmp_vmreg.set2(r19->as_VMReg());
 
   if (!is_critical_native) {
     for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) {
@@ -1952,7 +1952,7 @@
       __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));
 
       // Force this write out before the read below
-      __ dmb(Assembler::SY);
+      __ dmb(Assembler::ISH);
     } else {
       __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
       __ stlrw(rscratch1, rscratch2);
@@ -1970,13 +1970,7 @@
   // check for safepoint operation in progress and/or pending suspend requests
   Label safepoint_in_progress, safepoint_in_progress_done;
   {
-    assert(SafepointSynchronize::_not_synchronized == 0, "fix this code");
-    unsigned long offset;
-    __ adrp(rscratch1,
-            ExternalAddress((address)SafepointSynchronize::address_of_state()),
-            offset);
-    __ ldrw(rscratch1, Address(rscratch1, offset));
-    __ cbnzw(rscratch1, safepoint_in_progress);
+    __ safepoint_poll_acquire(safepoint_in_progress);
     __ ldrw(rscratch1, Address(rthread, JavaThread::suspend_flags_offset()));
     __ cbnzw(rscratch1, safepoint_in_progress);
     __ bind(safepoint_in_progress_done);
@@ -2932,8 +2926,11 @@
 
   if (!cause_return) {
     // overwrite the return address pushed by save_live_registers
-    __ ldr(c_rarg0, Address(rthread, JavaThread::saved_exception_pc_offset()));
-    __ str(c_rarg0, Address(rfp, wordSize));
+    // Additionally, r20 is a callee-saved register so we can look at
+    // it later to determine if someone changed the return address for
+    // us!
+    __ ldr(r20, Address(rthread, JavaThread::saved_exception_pc_offset()));
+    __ str(r20, Address(rfp, wordSize));
   }
 
   // Do the call
@@ -2968,11 +2965,40 @@
   // No exception case
   __ bind(noException);
 
+  Label no_adjust, bail;
+  if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
+    // If our stashed return pc was modified by the runtime we avoid touching it
+    __ ldr(rscratch1, Address(rfp, wordSize));
+    __ cmp(r20, rscratch1);
+    __ br(Assembler::NE, no_adjust);
+
+#ifdef ASSERT
+    // Verify the correct encoding of the poll we're about to skip.
+    // See NativeInstruction::is_ldrw_to_zr()
+    __ ldrw(rscratch1, Address(r20));
+    __ ubfx(rscratch2, rscratch1, 22, 10);
+    __ cmpw(rscratch2, 0b1011100101);
+    __ br(Assembler::NE, bail);
+    __ ubfx(rscratch2, rscratch1, 0, 5);
+    __ cmpw(rscratch2, 0b11111);
+    __ br(Assembler::NE, bail);
+#endif
+    // Adjust return pc forward to step over the safepoint poll instruction
+    __ add(r20, r20, NativeInstruction::instruction_size);
+    __ str(r20, Address(rfp, wordSize));
+  }
+
+  __ bind(no_adjust);
   // Normal exit, restore registers and exit.
   RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ ret(lr);
 
+#ifdef ASSERT
+  __ bind(bail);
+  __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected");
+#endif
+
   // Make sure all code is generated
   masm->flush();
 
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -414,6 +414,14 @@
   __ restore_constant_pool_cache();
   __ get_method(rmethod);
 
+  if (state == atos) {
+    Register obj = r0;
+    Register mdp = r1;
+    Register tmp = r2;
+    __ ldr(mdp, Address(rmethod, Method::method_data_offset()));
+    __ profile_return_type(mdp, obj, tmp);
+  }
+
   // Pop N words from the stack
   __ get_cache_and_index_at_bcp(r1, r2, 1, index_size);
   __ ldr(r1, Address(r1, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
@@ -967,12 +975,7 @@
 
     Label slow_path;
     // If we need a safepoint check, generate full interpreter entry.
-    ExternalAddress state(SafepointSynchronize::address_of_state());
-    unsigned long offset;
-    __ adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
-    __ ldrw(rscratch1, Address(rscratch1, offset));
-    assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
-    __ cbnz(rscratch1, slow_path);
+    __ safepoint_poll(slow_path);
 
     // We don't generate local frame and don't align stack because
     // we call stub code and there is no safepoint on this path.
@@ -986,6 +989,7 @@
     __ ldrw(val, Address(esp, 0));              // byte value
     __ ldrw(crc, Address(esp, wordSize));       // Initial CRC
 
+    unsigned long offset;
     __ adrp(tbl, ExternalAddress(StubRoutines::crc_table_addr()), offset);
     __ add(tbl, tbl, offset);
 
@@ -1020,12 +1024,7 @@
 
     Label slow_path;
     // If we need a safepoint check, generate full interpreter entry.
-    ExternalAddress state(SafepointSynchronize::address_of_state());
-    unsigned long offset;
-    __ adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
-    __ ldrw(rscratch1, Address(rscratch1, offset));
-    assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
-    __ cbnz(rscratch1, slow_path);
+    __ safepoint_poll(slow_path);
 
     // We don't generate local frame and don't align stack because
     // we call stub code and there is no safepoint on this path.
@@ -1375,7 +1374,7 @@
   if (os::is_MP()) {
     if (UseMembar) {
       // Force this write out before the read below
-      __ dsb(Assembler::SY);
+      __ dmb(Assembler::ISH);
     } else {
       // Write serialization page so VM thread can do a pseudo remote membar.
       // We use the current thread pointer to calculate a thread specific
@@ -1387,16 +1386,8 @@
 
   // check for safepoint operation in progress and/or pending suspend requests
   {
-    Label Continue;
-    {
-      unsigned long offset;
-      __ adrp(rscratch2, SafepointSynchronize::address_of_state(), offset);
-      __ ldrw(rscratch2, Address(rscratch2, offset));
-    }
-    assert(SafepointSynchronize::_not_synchronized == 0,
-           "SafepointSynchronize::_not_synchronized");
-    Label L;
-    __ cbnz(rscratch2, L);
+    Label L, Continue;
+    __ safepoint_poll_acquire(L);
     __ ldrw(rscratch2, Address(rthread, JavaThread::suspend_flags_offset()));
     __ cbz(rscratch2, Continue);
     __ bind(L);
@@ -1671,6 +1662,14 @@
   __ mov(rscratch2, true);
   __ strb(rscratch2, do_not_unlock_if_synchronized);
 
+  Label no_mdp;
+  Register mdp = r3;
+  __ ldr(mdp, Address(rmethod, Method::method_data_offset()));
+  __ cbz(mdp, no_mdp);
+  __ add(mdp, mdp, in_bytes(MethodData::data_offset()));
+  __ profile_parameters_type(mdp, r1, r2);
+  __ bind(no_mdp);
+
   // increment invocation count & check for overflow
   Label invocation_counter_overflow;
   Label profile_method;
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1717,7 +1717,7 @@
     __ push_i(r1);
     // Adjust the bcp by the 16-bit displacement in r2
     __ add(rbcp, rbcp, r2);
-    __ dispatch_only(vtos);
+    __ dispatch_only(vtos, /*generate_poll*/true);
     return;
   }
 
@@ -1833,7 +1833,7 @@
   // continue with the bytecode @ target
   // rscratch1: target bytecode
   // rbcp: target bcp
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 
   if (UseLoopCounter) {
     if (ProfileInterpreter) {
@@ -1973,7 +1973,7 @@
   __ ldr(rbcp, Address(rmethod, Method::const_offset()));
   __ lea(rbcp, Address(rbcp, r1));
   __ add(rbcp, rbcp, in_bytes(ConstMethod::codes_offset()));
-  __ dispatch_next(vtos);
+  __ dispatch_next(vtos, 0, /*generate_poll*/true);
 }
 
 void TemplateTable::wide_ret() {
@@ -1984,7 +1984,7 @@
   __ ldr(rbcp, Address(rmethod, Method::const_offset()));
   __ lea(rbcp, Address(rbcp, r1));
   __ add(rbcp, rbcp, in_bytes(ConstMethod::codes_offset()));
-  __ dispatch_next(vtos);
+  __ dispatch_next(vtos, 0, /*generate_poll*/true);
 }
 
 
@@ -2014,7 +2014,7 @@
   __ rev32(r3, r3);
   __ load_unsigned_byte(rscratch1, Address(rbcp, r3, Address::sxtw(0)));
   __ add(rbcp, rbcp, r3, ext::sxtw);
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
   // handle default
   __ bind(default_case);
   __ profile_switch_default(r0);
@@ -2064,7 +2064,7 @@
   __ rev32(r3, r3);
   __ add(rbcp, rbcp, r3, ext::sxtw);
   __ ldrb(rscratch1, Address(rbcp, 0));
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 }
 
 void TemplateTable::fast_binaryswitch() {
@@ -2162,7 +2162,7 @@
   __ rev32(j, j);
   __ load_unsigned_byte(rscratch1, Address(rbcp, j, Address::sxtw(0)));
   __ lea(rbcp, Address(rbcp, j, Address::sxtw(0)));
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 
   // default case -> j = default offset
   __ bind(default_case);
@@ -2171,7 +2171,7 @@
   __ rev32(j, j);
   __ load_unsigned_byte(rscratch1, Address(rbcp, j, Address::sxtw(0)));
   __ lea(rbcp, Address(rbcp, j, Address::sxtw(0)));
-  __ dispatch_only(vtos);
+  __ dispatch_only(vtos, /*generate_poll*/true);
 }
 
 
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -394,4 +394,6 @@
                                    g.generate_getPsrInfo());
 
   get_processor_features();
+
+  UNSUPPORTED_OPTION(CriticalJNINatives);
 }
--- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2968,7 +2968,9 @@
         CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
-        Label L_cardtable_loop;
+        Label L_cardtable_loop, L_done;
+
+        __ cbz_32(count, L_done); // zero count - nothing to do
 
         __ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop);
         __ sub(count, count, BytesPerHeapOop);                            // last addr
@@ -2987,6 +2989,7 @@
         __ strb(zero, Address(addr, 1, post_indexed));
         __ subs(count, count, 1);
         __ b(L_cardtable_loop, ge);
+        __ BIND(L_done);
       }
       break;
     case BarrierSet::ModRef:
--- a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -41,20 +41,25 @@
 
 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
   const Register temp_reg = R12_scratch2;
+  Label Lmiss;
+
   verify_oop(receiver);
+  MacroAssembler::null_check(receiver, oopDesc::klass_offset_in_bytes(), &Lmiss);
   load_klass(temp_reg, receiver);
-  if (TrapBasedICMissChecks) {
+
+  if (TrapBasedICMissChecks && TrapBasedNullChecks) {
     trap_ic_miss_check(temp_reg, iCache);
   } else {
-    Label L;
+    Label Lok;
     cmpd(CCR0, temp_reg, iCache);
-    beq(CCR0, L);
+    beq(CCR0, Lok);
+    bind(Lmiss);
     //load_const_optimized(temp_reg, SharedRuntime::get_ic_miss_stub(), R0);
     calculate_address_from_global_toc(temp_reg, SharedRuntime::get_ic_miss_stub(), true, true, false);
     mtctr(temp_reg);
     bctr();
     align(32, 12);
-    bind(L);
+    bind(Lok);
   }
 }
 
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -3371,7 +3371,7 @@
   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
   __ bfalse(CCR0, LnotFinal);
 
-  if (RewriteBytecodes && !UseSharedSpaces) {
+  if (RewriteBytecodes && !UseSharedSpaces && !DumpSharedSpaces) {
     patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2);
   }
   invokevfinal_helper(Rvtableindex_or_method, Rflags, R11_scratch1, R12_scratch2);
--- a/src/hotspot/cpu/s390/assembler_s390.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/s390/assembler_s390.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -582,7 +582,11 @@
 #define LOC_ZOPC    (unsigned long)(0xebL << 40 | 0xf2L)        // z196
 #define LOCG_ZOPC   (unsigned long)(0xebL << 40 | 0xe2L)        // z196
 
-#define LMG_ZOPC    (unsigned long)(235L << 40 | 4L)
+
+// LOAD multiple registers at once
+#define LM_ZOPC     (unsigned  int)(0x98  << 24)
+#define LMY_ZOPC    (unsigned long)(0xebL << 40 | 0x98L)
+#define LMG_ZOPC    (unsigned long)(0xebL << 40 | 0x04L)
 
 #define LE_ZOPC     (unsigned  int)(0x78 << 24)
 #define LEY_ZOPC    (unsigned long)(237L << 40 | 100L)
@@ -613,7 +617,10 @@
 #define STOC_ZOPC   (unsigned long)(0xebL << 40 | 0xf3L)        // z196
 #define STOCG_ZOPC  (unsigned long)(0xebL << 40 | 0xe3L)        // z196
 
-#define STMG_ZOPC   (unsigned long)(235L << 40 | 36L)
+// STORE multiple registers at once
+#define STM_ZOPC    (unsigned  int)(0x90  << 24)
+#define STMY_ZOPC   (unsigned long)(0xebL << 40 | 0x90L)
+#define STMG_ZOPC   (unsigned long)(0xebL << 40 | 0x24L)
 
 #define STE_ZOPC    (unsigned  int)(0x70 << 24)
 #define STEY_ZOPC   (unsigned long)(237L << 40 | 102L)
@@ -874,15 +881,19 @@
 
 // Shift
 // arithmetic
-#define SLA_ZOPC    (unsigned  int)(139 << 24)
-#define SLAG_ZOPC   (unsigned long)(235L << 40 | 11L)
-#define SRA_ZOPC    (unsigned  int)(138 << 24)
-#define SRAG_ZOPC   (unsigned long)(235L << 40 | 10L)
+#define SLA_ZOPC    (unsigned  int)(0x8b  << 24)
+#define SLAK_ZOPC   (unsigned long)(0xebL << 40 | 0xddL)
+#define SLAG_ZOPC   (unsigned long)(0xebL << 40 | 0x0bL)
+#define SRA_ZOPC    (unsigned  int)(0x8a  << 24)
+#define SRAK_ZOPC   (unsigned long)(0xebL << 40 | 0xdcL)
+#define SRAG_ZOPC   (unsigned long)(0xebL << 40 | 0x0aL)
 // logical
-#define SLL_ZOPC    (unsigned  int)(137 << 24)
-#define SLLG_ZOPC   (unsigned long)(235L << 40 | 13L)
-#define SRL_ZOPC    (unsigned  int)(136 << 24)
-#define SRLG_ZOPC   (unsigned long)(235L << 40 | 12L)
+#define SLL_ZOPC    (unsigned  int)(0x89  << 24)
+#define SLLK_ZOPC   (unsigned long)(0xebL << 40 | 0xdfL)
+#define SLLG_ZOPC   (unsigned long)(0xebL << 40 | 0x0dL)
+#define SRL_ZOPC    (unsigned  int)(0x88  << 24)
+#define SRLK_ZOPC   (unsigned long)(0xebL << 40 | 0xdeL)
+#define SRLG_ZOPC   (unsigned long)(0xebL << 40 | 0x0cL)
 
 // Rotate, then AND/XOR/OR/insert
 // rotate
@@ -2262,12 +2273,16 @@
 
   // shift
   inline void z_sla( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
+  inline void z_slak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
   inline void z_slag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, only 63 bits shifted, sign preserved!
   inline void z_sra( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, sign extended
+  inline void z_srak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, sign extended
   inline void z_srag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, sign extended
   inline void z_sll( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, zeros added
+  inline void z_sllk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int32, zeros added
   inline void z_sllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, zeros added
   inline void z_srl( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, zero extended
+  inline void z_srlk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, zero extended
   inline void z_srlg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, zero extended
 
   // rotate
@@ -3035,7 +3050,11 @@
 
   inline void z_tam();
   inline void z_stckf(int64_t d2, Register b2);
+  inline void z_stm( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_stmy(Register r1, Register r3, int64_t d2, Register b2);
   inline void z_stmg(Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lm( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lmy(Register r1, Register r3, int64_t d2, Register b2);
   inline void z_lmg(Register r1, Register r3, int64_t d2, Register b2);
 
   inline void z_cs( Register r1, Register r3, int64_t d2, Register b2);
--- a/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -334,12 +334,16 @@
 // SHIFT/RORATE OPERATIONS
 //-----------------------------------
 inline void Assembler::z_sla( Register r1,              int64_t d2, Register b2) { emit_32( SLA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_slak(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_slag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sra( Register r1,              int64_t d2, Register b2) { emit_32( SRA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srak(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sll( Register r1,              int64_t d2, Register b2) { emit_32( SLL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_sllk(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sllg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srl( Register r1,              int64_t d2, Register b2) { emit_32( SRL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srlk(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srlg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 
 // rotate left
@@ -690,10 +694,14 @@
 
 inline void Assembler::z_tam() { emit_16( TAM_ZOPC); }
 inline void Assembler::z_stckf(int64_t d2, Register b2) { emit_32( STCKF_ZOPC | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
-inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
-inline void Assembler::z_lmg(Register r1, Register r3, int64_t d2, Register b2)  { emit_48( LMG_ZOPC  | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
+inline void Assembler::z_stm( Register r1, Register r3, int64_t d2, Register b2) { emit_32( STM_ZOPC  | reg(r1, 8, 32) | reg(r3,12,32)| reg(b2,16,32) | uimm12(d2, 20,32)); }
+inline void Assembler::z_stmy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMY_ZOPC | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_lm(  Register r1, Register r3, int64_t d2, Register b2) { emit_32( LM_ZOPC   | reg(r1, 8, 32) | reg(r3,12,32)| reg(b2,16,32) | uimm12(d2, 20,32)); }
+inline void Assembler::z_lmy( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LMY_ZOPC  | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_lmg( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LMG_ZOPC  | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
 
-inline void Assembler::z_cs(Register r1, Register r3, int64_t d2, Register b2)  { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
+inline void Assembler::z_cs( Register r1, Register r3, int64_t d2, Register b2) { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
 inline void Assembler::z_csy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSY_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
 inline void Assembler::z_csg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSG_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
 inline void Assembler::z_cs( Register r1, Register r3, const Address& a) { assert(!a.has_index(), "Cannot encode index"); z_cs( r1, r3, a.disp(), a.baseOrR0()); }
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -936,7 +936,7 @@
 
   // Some extra safety net.
   if (!RelAddr::is_in_range_of_RelAddr32(total_distance)) {
-    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "too far away");
+    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "load_long_pcrelative can't handle distance " INTPTR_FORMAT, total_distance);
   }
 
   (this)->relocate(rspec, relocInfo::pcrel_addr_format);
@@ -956,7 +956,7 @@
 
   // Some extra safety net.
   if (!RelAddr::is_in_range_of_RelAddr32(total_distance)) {
-    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "too far away");
+    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "load_long_pcrelative can't handle distance " INTPTR_FORMAT, total_distance);
   }
 
   (this)->relocate(rspec, relocInfo::pcrel_addr_format);
@@ -1025,6 +1025,13 @@
   }
 }
 
+void MacroAssembler::prefetch_read(Address a) {
+  z_pfd(1, a.disp20(), a.indexOrR0(), a.base());
+}
+void MacroAssembler::prefetch_update(Address a) {
+  z_pfd(2, a.disp20(), a.indexOrR0(), a.base());
+}
+
 // Clear a register, i.e. load const zero into reg.
 // Return len (in bytes) of generated instruction(s).
 // whole_reg: Clear 64 bits if true, 32 bits otherwise.
@@ -4896,77 +4903,296 @@
 
 // Intrinsics for CompactStrings
 
-// Compress char[] to byte[]. odd_reg contains cnt. Kills dst. Early clobber: result
+// Compress char[] to byte[].
+//   Restores: src, dst
+//   Uses:     cnt
+//   Kills:    tmp, Z_R0, Z_R1.
+//   Early clobber: result.
+// Note:
+//   cnt is signed int. Do not rely on high word!
+//       counts # characters, not bytes.
 // The result is the number of characters copied before the first incompatible character was found.
-// If tmp2 is provided and the compression fails, the compression stops exactly at this point and the result is precise.
+// If precise is true, the processing stops exactly at this point. Otherwise, the result may be off
+// by a few bytes. The result always indicates the number of copied characters.
 //
 // Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure:
-// - Different number of characters may have been written to dead array (if tmp2 not provided).
+// - Different number of characters may have been written to dead array (if precise is false).
 // - Returns a number <cnt instead of 0. (Result gets compared with cnt.)
-unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register odd_reg,
-                                             Register even_reg, Register tmp, Register tmp2) {
-  int block_start = offset();
-  Label Lloop1, Lloop2, Lslow, Ldone;
-  const Register addr2 = dst, ind1 = result, mask = tmp;
-  const bool precise = (tmp2 != noreg);
-
-  BLOCK_COMMENT("string_compress {");
-
-  z_sll(odd_reg, 1);       // Number of bytes to read. (Must be a positive simm32.)
-  clear_reg(ind1);         // Index to read.
-  z_llilf(mask, 0xFF00FF00);
-  z_ahi(odd_reg, -16);     // Last possible index for fast loop.
-  z_brl(Lslow);
-
-  // ind1: index, even_reg: index increment, odd_reg: index limit
-  z_iihf(mask, 0xFF00FF00);
-  z_lhi(even_reg, 16);
-
-  bind(Lloop1); // 8 Characters per iteration.
-  z_lg(Z_R0, Address(src, ind1));
-  z_lg(Z_R1, Address(src, ind1, 8));
+unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register cnt,
+                                             Register tmp,    bool precise) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
+
   if (precise) {
+    BLOCK_COMMENT("encode_iso_array {");
+  } else {
+    BLOCK_COMMENT("string_compress {");
+  }
+  int  block_start = offset();
+
+  Register       Rsrc  = src;
+  Register       Rdst  = dst;
+  Register       Rix   = tmp;
+  Register       Rcnt  = cnt;
+  Register       Rmask = result;  // holds incompatibility check mask until result value is stored.
+  Label          ScalarShortcut, AllDone;
+
+  z_iilf(Rmask, 0xFF00FF00);
+  z_iihf(Rmask, 0xFF00FF00);
+
+#if 0  // Sacrifice shortcuts for code compactness
+  {
+    //---<  shortcuts for short strings (very frequent)   >---
+    //   Strings with 4 and 8 characters were fond to occur very frequently.
+    //   Therefore, we handle them right away with minimal overhead.
+    Label     skipShortcut, skip4Shortcut, skip8Shortcut;
+    Register  Rout = Z_R0;
+    z_chi(Rcnt, 4);
+    z_brne(skip4Shortcut);                 // 4 characters are very frequent
+      z_lg(Z_R0, 0, Rsrc);                 // Treat exactly 4 characters specially.
+      if (VM_Version::has_DistinctOpnds()) {
+        Rout = Z_R0;
+        z_ngrk(Rix, Z_R0, Rmask);
+      } else {
+        Rout = Rix;
+        z_lgr(Rix, Z_R0);
+        z_ngr(Z_R0, Rmask);
+      }
+      z_brnz(skipShortcut);
+      z_stcmh(Rout, 5, 0, Rdst);
+      z_stcm(Rout,  5, 2, Rdst);
+      z_lgfr(result, Rcnt);
+      z_bru(AllDone);
+    bind(skip4Shortcut);
+
+    z_chi(Rcnt, 8);
+    z_brne(skip8Shortcut);                 // There's more to do...
+      z_lmg(Z_R0, Z_R1, 0, Rsrc);          // Treat exactly 8 characters specially.
+      if (VM_Version::has_DistinctOpnds()) {
+        Rout = Z_R0;
+        z_ogrk(Rix, Z_R0, Z_R1);
+        z_ngr(Rix, Rmask);
+      } else {
+        Rout = Rix;
+        z_lgr(Rix, Z_R0);
+        z_ogr(Z_R0, Z_R1);
+        z_ngr(Z_R0, Rmask);
+      }
+      z_brnz(skipShortcut);
+      z_stcmh(Rout, 5, 0, Rdst);
+      z_stcm(Rout,  5, 2, Rdst);
+      z_stcmh(Z_R1, 5, 4, Rdst);
+      z_stcm(Z_R1,  5, 6, Rdst);
+      z_lgfr(result, Rcnt);
+      z_bru(AllDone);
+
+    bind(skip8Shortcut);
+    clear_reg(Z_R0, true, false);          // #characters already processed (none). Precond for scalar loop.
+    z_brl(ScalarShortcut);                 // Just a few characters
+
+    bind(skipShortcut);
+  }
+#endif
+  clear_reg(Z_R0);                         // make sure register is properly initialized.
+
+  if (VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of 2*(vector register length in chars (8 HW = 128 bits)).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    Label      VectorLoop, VectorDone, VectorBreak;
+
+    VectorRegister Vtmp1      = Z_V16;
+    VectorRegister Vtmp2      = Z_V17;
+    VectorRegister Vmask      = Z_V18;
+    VectorRegister Vzero      = Z_V19;
+    VectorRegister Vsrc_first = Z_V20;
+    VectorRegister Vsrc_last  = Z_V23;
+
+    assert((Vsrc_last->encoding() - Vsrc_first->encoding() + 1) == min_vcnt/8, "logic error");
+    assert(VM_Version::has_DistinctOpnds(), "Assumption when has_VectorFacility()");
+    z_srak(Rix, Rcnt, log_min_vcnt);       // # vector loop iterations
+    z_brz(VectorDone);                     // not enough data for vector loop
+
+    z_vzero(Vzero);                        // all zeroes
+    z_vgmh(Vmask, 0, 7);                   // generate 0xff00 mask for all 2-byte elements
+    z_sllg(Z_R0, Rix, log_min_vcnt);       // remember #chars that will be processed by vector loop
+
+    bind(VectorLoop);
+      z_vlm(Vsrc_first, Vsrc_last, 0, Rsrc);
+      add2reg(Rsrc, min_vcnt*2);
+
+      //---<  check for incompatible character  >---
+      z_vo(Vtmp1, Z_V20, Z_V21);
+      z_vo(Vtmp2, Z_V22, Z_V23);
+      z_vo(Vtmp1, Vtmp1, Vtmp2);
+      z_vn(Vtmp1, Vtmp1, Vmask);
+      z_vceqhs(Vtmp1, Vtmp1, Vzero);       // high half of all chars must be zero for successful compress.
+      z_brne(VectorBreak);                 // break vector loop, incompatible character found.
+                                           // re-process data from current iteration in break handler.
+
+      //---<  pack & store characters  >---
+      z_vpkh(Vtmp1, Z_V20, Z_V21);         // pack (src1, src2) -> tmp1
+      z_vpkh(Vtmp2, Z_V22, Z_V23);         // pack (src3, src4) -> tmp2
+      z_vstm(Vtmp1, Vtmp2, 0, Rdst);       // store packed string
+      add2reg(Rdst, min_vcnt);
+
+      z_brct(Rix, VectorLoop);
+
+    z_bru(VectorDone);
+
+    bind(VectorBreak);
+      add2reg(Rsrc, -min_vcnt*2);          // Fix Rsrc. Rsrc was already updated, but Rdst and Rix are not.
+      z_sll(Rix, log_min_vcnt);            // # chars processed so far in VectorLoop, excl. current iteration.
+      z_sr(Z_R0, Rix);                     // correct # chars processed in total.
+
+    bind(VectorDone);
+  }
+
+  {
+    const int  min_cnt     =  8;           // Minimum #characters required to use unrolled loop.
+                                           // Otherwise just do nothing in unrolled loop.
+                                           // Must be multiple of 8.
+    const int  log_min_cnt = exact_log2(min_cnt);
+    Label      UnrolledLoop, UnrolledDone, UnrolledBreak;
+
     if (VM_Version::has_DistinctOpnds()) {
-      z_ogrk(tmp2, Z_R0, Z_R1);
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to compress in unrolled loop
     } else {
-      z_lgr(tmp2, Z_R0);
-      z_ogr(tmp2, Z_R1);
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
     }
-    z_ngr(tmp2, mask);
-    z_brne(Lslow);         // Failed fast case, retry slowly.
-  }
-  z_stcmh(Z_R0, 5, 0, addr2);
-  z_stcm(Z_R0, 5, 2, addr2);
-  if (!precise) { z_ogr(Z_R0, Z_R1); }
-  z_stcmh(Z_R1, 5, 4, addr2);
-  z_stcm(Z_R1, 5, 6, addr2);
-  if (!precise) {
-    z_ngr(Z_R0, mask);
-    z_brne(Ldone);         // Failed (more than needed was written).
-  }
-  z_aghi(addr2, 8);
-  z_brxle(ind1, even_reg, Lloop1);
-
-  bind(Lslow);
-  // Compute index limit and skip if negative.
-  z_ahi(odd_reg, 16-2);    // Last possible index for slow loop.
-  z_lhi(even_reg, 2);
-  z_cr(ind1, odd_reg);
-  z_brh(Ldone);
-
-  bind(Lloop2); // 1 Character per iteration.
-  z_llh(Z_R0, Address(src, ind1));
-  z_tmll(Z_R0, 0xFF00);
-  z_brnaz(Ldone);          // Failed slow case: Return number of written characters.
-  z_stc(Z_R0, Address(addr2));
-  z_aghi(addr2, 1);
-  z_brxle(ind1, even_reg, Lloop2);
-
-  bind(Ldone);             // result = ind1 = 2*cnt
-  z_srl(ind1, 1);
-
-  BLOCK_COMMENT("} string_compress");
-
+    z_sra(Rix, log_min_cnt);             // unrolled loop count
+    z_brz(UnrolledDone);
+
+    bind(UnrolledLoop);
+      z_lmg(Z_R0, Z_R1, 0, Rsrc);
+      if (precise) {
+        z_ogr(Z_R1, Z_R0);                 // check all 8 chars for incompatibility
+        z_ngr(Z_R1, Rmask);
+        z_brnz(UnrolledBreak);
+
+        z_lg(Z_R1, 8, Rsrc);               // reload destroyed register
+        z_stcmh(Z_R0, 5, 0, Rdst);
+        z_stcm(Z_R0,  5, 2, Rdst);
+      } else {
+        z_stcmh(Z_R0, 5, 0, Rdst);
+        z_stcm(Z_R0,  5, 2, Rdst);
+
+        z_ogr(Z_R0, Z_R1);
+        z_ngr(Z_R0, Rmask);
+        z_brnz(UnrolledBreak);
+      }
+      z_stcmh(Z_R1, 5, 4, Rdst);
+      z_stcm(Z_R1,  5, 6, Rdst);
+
+      add2reg(Rsrc, min_cnt*2);
+      add2reg(Rdst, min_cnt);
+      z_brct(Rix, UnrolledLoop);
+
+    z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop.
+    z_nilf(Z_R0, ~(min_cnt-1));
+    z_tmll(Rcnt, min_cnt-1);
+    z_brnaz(ScalarShortcut);               // if all bits zero, there is nothing left to do for scalar loop.
+                                           // Rix == 0 in all cases.
+    z_lgfr(result, Rcnt);                  // all characters processed.
+    z_sgfr(Rdst, Rcnt);                    // restore ptr
+    z_sgfr(Rsrc, Rcnt);                    // restore ptr, double the element count for Rsrc restore
+    z_sgfr(Rsrc, Rcnt);
+    z_bru(AllDone);
+
+    bind(UnrolledBreak);
+    z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop
+    z_nilf(Z_R0, ~(min_cnt-1));
+    z_sll(Rix, log_min_cnt);               // # chars processed so far in UnrolledLoop, excl. current iteration.
+    z_sr(Z_R0, Rix);                       // correct # chars processed in total.
+    if (!precise) {
+      z_lgfr(result, Z_R0);
+      z_aghi(result, min_cnt/2);           // min_cnt/2 characters have already been written
+                                           // but ptrs were not updated yet.
+      z_sgfr(Rdst, Z_R0);                  // restore ptr
+      z_sgfr(Rsrc, Z_R0);                  // restore ptr, double the element count for Rsrc restore
+      z_sgfr(Rsrc, Z_R0);
+      z_bru(AllDone);
+    }
+    bind(UnrolledDone);
+  }
+
+  {
+    Label     ScalarLoop, ScalarDone, ScalarBreak;
+
+    bind(ScalarShortcut);
+    z_ltgfr(result, Rcnt);
+    z_brz(AllDone);
+
+#if 0  // Sacrifice shortcuts for code compactness
+    {
+      //---<  Special treatment for very short strings (one or two characters)  >---
+      //   For these strings, we are sure that the above code was skipped.
+      //   Thus, no registers were modified, register restore is not required.
+      Label     ScalarDoit, Scalar2Char;
+      z_chi(Rcnt, 2);
+      z_brh(ScalarDoit);
+      z_llh(Z_R1,  0, Z_R0, Rsrc);
+      z_bre(Scalar2Char);
+      z_tmll(Z_R1, 0xff00);
+      z_lghi(result, 0);                   // cnt == 1, first char invalid, no chars successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R1,  0, Z_R0, Rdst);
+      z_lghi(result, 1);
+      z_bru(AllDone);
+
+      bind(Scalar2Char);
+      z_llh(Z_R0,  2, Z_R0, Rsrc);
+      z_tmll(Z_R1, 0xff00);
+      z_lghi(result, 0);                   // cnt == 2, first char invalid, no chars successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R1,  0, Z_R0, Rdst);
+      z_tmll(Z_R0, 0xff00);
+      z_lghi(result, 1);                   // cnt == 2, second char invalid, one char successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R0,  1, Z_R0, Rdst);
+      z_lghi(result, 2);
+      z_bru(AllDone);
+
+      bind(ScalarDoit);
+    }
+#endif
+
+    if (VM_Version::has_DistinctOpnds()) {
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to compress in unrolled loop
+    } else {
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
+    }
+    z_lgfr(result, Rcnt);                  // # processed characters (if all runs ok).
+    z_brz(ScalarDone);
+
+    bind(ScalarLoop);
+      z_llh(Z_R1, 0, Z_R0, Rsrc);
+      z_tmll(Z_R1, 0xff00);
+      z_brnaz(ScalarBreak);
+      z_stc(Z_R1, 0, Z_R0, Rdst);
+      add2reg(Rsrc, 2);
+      add2reg(Rdst, 1);
+      z_brct(Rix, ScalarLoop);
+
+    z_bru(ScalarDone);
+
+    bind(ScalarBreak);
+    z_sr(result, Rix);
+
+    bind(ScalarDone);
+    z_sgfr(Rdst, result);                  // restore ptr
+    z_sgfr(Rsrc, result);                  // restore ptr, double the element count for Rsrc restore
+    z_sgfr(Rsrc, result);
+  }
+  bind(AllDone);
+
+  if (precise) {
+    BLOCK_COMMENT("} encode_iso_array");
+  } else {
+    BLOCK_COMMENT("} string_compress");
+  }
   return offset() - block_start;
 }
 
@@ -4997,53 +5223,432 @@
   return offset() - block_start;
 }
 
-// Inflate byte[] to char[]. odd_reg contains cnt. Kills src.
-unsigned int MacroAssembler::string_inflate(Register src, Register dst, Register odd_reg,
-                                            Register even_reg, Register tmp) {
-  int block_start = offset();
+// Inflate byte[] to char[].
+//   Restores: src, dst
+//   Uses:     cnt
+//   Kills:    tmp, Z_R0, Z_R1.
+// Note:
+//   cnt is signed int. Do not rely on high word!
+//       counts # characters, not bytes.
+unsigned int MacroAssembler::string_inflate(Register src, Register dst, Register cnt, Register tmp) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
 
   BLOCK_COMMENT("string_inflate {");
-
-  Label Lloop1, Lloop2, Lslow, Ldone;
-  const Register addr1 = src, ind2 = tmp;
-
-  z_sll(odd_reg, 1);       // Number of bytes to write. (Must be a positive simm32.)
-  clear_reg(ind2);         // Index to write.
-  z_ahi(odd_reg, -16);     // Last possible index for fast loop.
-  z_brl(Lslow);
-
-  // ind2: index, even_reg: index increment, odd_reg: index limit
-  clear_reg(Z_R0);
-  clear_reg(Z_R1);
-  z_lhi(even_reg, 16);
-
-  bind(Lloop1); // 8 Characters per iteration.
-  z_icmh(Z_R0, 5, 0, addr1);
-  z_icmh(Z_R1, 5, 4, addr1);
-  z_icm(Z_R0, 5, 2, addr1);
-  z_icm(Z_R1, 5, 6, addr1);
-  z_aghi(addr1, 8);
-  z_stg(Z_R0, Address(dst, ind2));
-  z_stg(Z_R1, Address(dst, ind2, 8));
-  z_brxle(ind2, even_reg, Lloop1);
-
-  bind(Lslow);
-  // Compute index limit and skip if negative.
-  z_ahi(odd_reg, 16-2);    // Last possible index for slow loop.
-  z_lhi(even_reg, 2);
-  z_cr(ind2, odd_reg);
-  z_brh(Ldone);
-
-  bind(Lloop2); // 1 Character per iteration.
-  z_llc(Z_R0, Address(addr1));
-  z_sth(Z_R0, Address(dst, ind2));
-  z_aghi(addr1, 1);
-  z_brxle(ind2, even_reg, Lloop2);
-
-  bind(Ldone);
+  int block_start = offset();
+
+  Register   Rcnt = cnt;   // # characters (src: bytes, dst: char (2-byte)), remaining after current loop.
+  Register   Rix  = tmp;   // loop index
+  Register   Rsrc = src;   // addr(src array)
+  Register   Rdst = dst;   // addr(dst array)
+  Label      ScalarShortcut, AllDone;
+
+#if 0  // Sacrifice shortcuts for code compactness
+  {
+    //---<  shortcuts for short strings (very frequent)   >---
+    Label   skipShortcut, skip4Shortcut;
+    z_ltr(Rcnt, Rcnt);                     // absolutely nothing to do for strings of len == 0.
+    z_brz(AllDone);
+    clear_reg(Z_R0);                       // make sure registers are properly initialized.
+    clear_reg(Z_R1);
+    z_chi(Rcnt, 4);
+    z_brne(skip4Shortcut);                 // 4 characters are very frequent
+      z_icm(Z_R0, 5,    0, Rsrc);          // Treat exactly 4 characters specially.
+      z_icm(Z_R1, 5,    2, Rsrc);
+      z_stm(Z_R0, Z_R1, 0, Rdst);
+      z_bru(AllDone);
+    bind(skip4Shortcut);
+
+    z_chi(Rcnt, 8);
+    z_brh(skipShortcut);                   // There's a lot to do...
+    z_lgfr(Z_R0, Rcnt);                    // remaining #characters (<= 8). Precond for scalar loop.
+                                           // This does not destroy the "register cleared" state of Z_R0.
+    z_brl(ScalarShortcut);                 // Just a few characters
+      z_icmh(Z_R0, 5, 0, Rsrc);            // Treat exactly 8 characters specially.
+      z_icmh(Z_R1, 5, 4, Rsrc);
+      z_icm(Z_R0,  5, 2, Rsrc);
+      z_icm(Z_R1,  5, 6, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0, Rdst);
+      z_bru(AllDone);
+    bind(skipShortcut);
+  }
+#endif
+  clear_reg(Z_R0);                         // make sure register is properly initialized.
+
+  if (VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    Label      VectorLoop, VectorDone;
+
+    assert(VM_Version::has_DistinctOpnds(), "Assumption when has_VectorFacility()");
+    z_srak(Rix, Rcnt, log_min_vcnt);       // calculate # vector loop iterations
+    z_brz(VectorDone);                     // skip if none
+
+    z_sllg(Z_R0, Rix, log_min_vcnt);       // remember #chars that will be processed by vector loop
+
+    bind(VectorLoop);
+      z_vlm(Z_V20, Z_V21, 0, Rsrc);        // get next 32 characters (single-byte)
+      add2reg(Rsrc, min_vcnt);
+
+      z_vuplhb(Z_V22, Z_V20);              // V2 <- (expand) V0(high)
+      z_vupllb(Z_V23, Z_V20);              // V3 <- (expand) V0(low)
+      z_vuplhb(Z_V24, Z_V21);              // V4 <- (expand) V1(high)
+      z_vupllb(Z_V25, Z_V21);              // V5 <- (expand) V1(low)
+      z_vstm(Z_V22, Z_V25, 0, Rdst);       // store next 32 bytes
+      add2reg(Rdst, min_vcnt*2);
+
+      z_brct(Rix, VectorLoop);
+
+    bind(VectorDone);
+  }
+
+  const int  min_cnt     =  8;             // Minimum #characters required to use unrolled scalar loop.
+                                           // Otherwise just do nothing in unrolled scalar mode.
+                                           // Must be multiple of 8.
+  {
+    const int  log_min_cnt = exact_log2(min_cnt);
+    Label      UnrolledLoop, UnrolledDone;
+
+
+    if (VM_Version::has_DistinctOpnds()) {
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to process in unrolled loop
+    } else {
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
+    }
+    z_sra(Rix, log_min_cnt);               // unrolled loop count
+    z_brz(UnrolledDone);
+
+    clear_reg(Z_R0);
+    clear_reg(Z_R1);
+
+    bind(UnrolledLoop);
+      z_icmh(Z_R0, 5, 0, Rsrc);
+      z_icmh(Z_R1, 5, 4, Rsrc);
+      z_icm(Z_R0,  5, 2, Rsrc);
+      z_icm(Z_R1,  5, 6, Rsrc);
+      add2reg(Rsrc, min_cnt);
+
+      z_stmg(Z_R0, Z_R1, 0, Rdst);
+
+      add2reg(Rdst, min_cnt*2);
+      z_brct(Rix, UnrolledLoop);
+
+    bind(UnrolledDone);
+    z_lgfr(Z_R0, Rcnt);                    // # chars left over after unrolled loop.
+    z_nilf(Z_R0, min_cnt-1);
+    z_brnz(ScalarShortcut);                // if zero, there is nothing left to do for scalar loop.
+                                           // Rix == 0 in all cases.
+    z_sgfr(Z_R0, Rcnt);                    // negative # characters the ptrs have been advanced previously.
+    z_agr(Rdst, Z_R0);                     // restore ptr, double the element count for Rdst restore.
+    z_agr(Rdst, Z_R0);
+    z_agr(Rsrc, Z_R0);                     // restore ptr.
+    z_bru(AllDone);
+  }
+
+  {
+    bind(ScalarShortcut);
+    // Z_R0 must contain remaining # characters as 64-bit signed int here.
+    //      register contents is preserved over scalar processing (for register fixup).
+
+#if 0  // Sacrifice shortcuts for code compactness
+    {
+      Label      ScalarDefault;
+      z_chi(Rcnt, 2);
+      z_brh(ScalarDefault);
+      z_llc(Z_R0,  0, Z_R0, Rsrc);     // 6 bytes
+      z_sth(Z_R0,  0, Z_R0, Rdst);     // 4 bytes
+      z_brl(AllDone);
+      z_llc(Z_R0,  1, Z_R0, Rsrc);     // 6 bytes
+      z_sth(Z_R0,  2, Z_R0, Rdst);     // 4 bytes
+      z_bru(AllDone);
+      bind(ScalarDefault);
+    }
+#endif
+
+    Label   CodeTable;
+    // Some comments on Rix calculation:
+    //  - Rcnt is small, therefore no bits shifted out of low word (sll(g) instructions).
+    //  - high word of both Rix and Rcnt may contain garbage
+    //  - the final lngfr takes care of that garbage, extending the sign to high word
+    z_sllg(Rix, Z_R0, 2);                // calculate 10*Rix = (4*Rix + Rix)*2
+    z_ar(Rix, Z_R0);
+    z_larl(Z_R1, CodeTable);
+    z_sll(Rix, 1);
+    z_lngfr(Rix, Rix);      // ix range: [0..7], after inversion & mult: [-(7*12)..(0*12)].
+    z_bc(Assembler::bcondAlways, 0, Rix, Z_R1);
+
+    z_llc(Z_R1,  6, Z_R0, Rsrc);  // 6 bytes
+    z_sth(Z_R1, 12, Z_R0, Rdst);  // 4 bytes
+
+    z_llc(Z_R1,  5, Z_R0, Rsrc);
+    z_sth(Z_R1, 10, Z_R0, Rdst);
+
+    z_llc(Z_R1,  4, Z_R0, Rsrc);
+    z_sth(Z_R1,  8, Z_R0, Rdst);
+
+    z_llc(Z_R1,  3, Z_R0, Rsrc);
+    z_sth(Z_R1,  6, Z_R0, Rdst);
+
+    z_llc(Z_R1,  2, Z_R0, Rsrc);
+    z_sth(Z_R1,  4, Z_R0, Rdst);
+
+    z_llc(Z_R1,  1, Z_R0, Rsrc);
+    z_sth(Z_R1,  2, Z_R0, Rdst);
+
+    z_llc(Z_R1,  0, Z_R0, Rsrc);
+    z_sth(Z_R1,  0, Z_R0, Rdst);
+    bind(CodeTable);
+
+    z_chi(Rcnt, 8);                        // no fixup for small strings. Rdst, Rsrc were not modified.
+    z_brl(AllDone);
+
+    z_sgfr(Z_R0, Rcnt);                    // # characters the ptrs have been advanced previously.
+    z_agr(Rdst, Z_R0);                     // restore ptr, double the element count for Rdst restore.
+    z_agr(Rdst, Z_R0);
+    z_agr(Rsrc, Z_R0);                     // restore ptr.
+  }
+  bind(AllDone);
 
   BLOCK_COMMENT("} string_inflate");
-
+  return offset() - block_start;
+}
+
+// Inflate byte[] to char[], length known at compile time.
+//   Restores: src, dst
+//   Kills:    tmp, Z_R0, Z_R1.
+// Note:
+//   len is signed int. Counts # characters, not bytes.
+unsigned int MacroAssembler::string_inflate_const(Register src, Register dst, Register tmp, int len) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, tmp);
+
+  BLOCK_COMMENT("string_inflate_const {");
+  int block_start = offset();
+
+  Register   Rix  = tmp;   // loop index
+  Register   Rsrc = src;   // addr(src array)
+  Register   Rdst = dst;   // addr(dst array)
+  Label      ScalarShortcut, AllDone;
+  int        nprocessed = 0;
+  int        src_off    = 0;  // compensate for saved (optimized away) ptr advancement.
+  int        dst_off    = 0;  // compensate for saved (optimized away) ptr advancement.
+  bool       restore_inputs = false;
+  bool       workreg_clear  = false;
+
+  if ((len >= 32) && VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    const int  iterations   = (len - nprocessed) >> log_min_vcnt;
+    nprocessed             += iterations << log_min_vcnt;
+    Label      VectorLoop;
+
+    if (iterations == 1) {
+      z_vlm(Z_V20, Z_V21, 0+src_off, Rsrc);  // get next 32 characters (single-byte)
+      z_vuplhb(Z_V22, Z_V20);                // V2 <- (expand) V0(high)
+      z_vupllb(Z_V23, Z_V20);                // V3 <- (expand) V0(low)
+      z_vuplhb(Z_V24, Z_V21);                // V4 <- (expand) V1(high)
+      z_vupllb(Z_V25, Z_V21);                // V5 <- (expand) V1(low)
+      z_vstm(Z_V22, Z_V25, 0+dst_off, Rdst); // store next 32 bytes
+
+      src_off += min_vcnt;
+      dst_off += min_vcnt*2;
+    } else {
+      restore_inputs = true;
+
+      z_lgfi(Rix, len>>log_min_vcnt);
+      bind(VectorLoop);
+        z_vlm(Z_V20, Z_V21, 0, Rsrc);        // get next 32 characters (single-byte)
+        add2reg(Rsrc, min_vcnt);
+
+        z_vuplhb(Z_V22, Z_V20);              // V2 <- (expand) V0(high)
+        z_vupllb(Z_V23, Z_V20);              // V3 <- (expand) V0(low)
+        z_vuplhb(Z_V24, Z_V21);              // V4 <- (expand) V1(high)
+        z_vupllb(Z_V25, Z_V21);              // V5 <- (expand) V1(low)
+        z_vstm(Z_V22, Z_V25, 0, Rdst);       // store next 32 bytes
+        add2reg(Rdst, min_vcnt*2);
+
+        z_brct(Rix, VectorLoop);
+    }
+  }
+
+  if (((len-nprocessed) >= 16) && VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 16;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    const int  iterations   = (len - nprocessed) >> log_min_vcnt;
+    nprocessed             += iterations << log_min_vcnt;
+    assert(iterations == 1, "must be!");
+
+    z_vl(Z_V20, 0+src_off, Z_R0, Rsrc);    // get next 16 characters (single-byte)
+    z_vuplhb(Z_V22, Z_V20);                // V2 <- (expand) V0(high)
+    z_vupllb(Z_V23, Z_V20);                // V3 <- (expand) V0(low)
+    z_vstm(Z_V22, Z_V23, 0+dst_off, Rdst); // store next 32 bytes
+
+    src_off += min_vcnt;
+    dst_off += min_vcnt*2;
+  }
+
+  if ((len-nprocessed) > 8) {
+    const int  min_cnt     =  8;           // Minimum #characters required to use unrolled scalar loop.
+                                           // Otherwise just do nothing in unrolled scalar mode.
+                                           // Must be multiple of 8.
+    const int  log_min_cnt = exact_log2(min_cnt);
+    const int  iterations  = (len - nprocessed) >> log_min_cnt;
+    nprocessed     += iterations << log_min_cnt;
+
+    //---<  avoid loop overhead/ptr increment for small # iterations  >---
+    if (iterations <= 2) {
+      clear_reg(Z_R0);
+      clear_reg(Z_R1);
+      workreg_clear = true;
+
+      z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+      z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+      z_icm(Z_R0,  5, 2+src_off, Rsrc);
+      z_icm(Z_R1,  5, 6+src_off, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+
+      src_off += min_cnt;
+      dst_off += min_cnt*2;
+    }
+
+    if (iterations == 2) {
+      z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+      z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+      z_icm(Z_R0,  5, 2+src_off, Rsrc);
+      z_icm(Z_R1,  5, 6+src_off, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+
+      src_off += min_cnt;
+      dst_off += min_cnt*2;
+    }
+
+    if (iterations > 2) {
+      Label      UnrolledLoop;
+      restore_inputs  = true;
+
+      clear_reg(Z_R0);
+      clear_reg(Z_R1);
+      workreg_clear = true;
+
+      z_lgfi(Rix, iterations);
+      bind(UnrolledLoop);
+        z_icmh(Z_R0, 5, 0, Rsrc);
+        z_icmh(Z_R1, 5, 4, Rsrc);
+        z_icm(Z_R0,  5, 2, Rsrc);
+        z_icm(Z_R1,  5, 6, Rsrc);
+        add2reg(Rsrc, min_cnt);
+
+        z_stmg(Z_R0, Z_R1, 0, Rdst);
+        add2reg(Rdst, min_cnt*2);
+
+        z_brct(Rix, UnrolledLoop);
+    }
+  }
+
+  if ((len-nprocessed) > 0) {
+    switch (len-nprocessed) {
+      case 8:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+        z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+        z_icm(Z_R0,  5, 2+src_off, Rsrc);
+        z_icm(Z_R1,  5, 6+src_off, Rsrc);
+        z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+        break;
+      case 7:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        clear_reg(Rix);
+        z_icm(Z_R0,  5, 0+src_off, Rsrc);
+        z_icm(Z_R1,  5, 2+src_off, Rsrc);
+        z_icm(Rix,   5, 4+src_off, Rsrc);
+        z_stm(Z_R0,  Z_R1, 0+dst_off, Rdst);
+        z_llc(Z_R0,  6+src_off, Z_R0, Rsrc);
+        z_st(Rix,    8+dst_off, Z_R0, Rdst);
+        z_sth(Z_R0, 12+dst_off, Z_R0, Rdst);
+        break;
+      case 6:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        clear_reg(Rix);
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_icm(Rix,  5, 4+src_off, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        z_st(Rix,   8+dst_off, Z_R0, Rdst);
+        break;
+      case 5:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_llc(Rix,  4+src_off, Z_R0, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        z_sth(Rix,  8+dst_off, Z_R0, Rdst);
+        break;
+      case 4:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        break;
+      case 3:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+        }
+        z_llc(Z_R1, 2+src_off, Z_R0, Rsrc);
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_sth(Z_R1, 4+dst_off, Z_R0, Rdst);
+        z_st(Z_R0,  0+dst_off, Rdst);
+        break;
+      case 2:
+        z_llc(Z_R0, 0+src_off, Z_R0, Rsrc);
+        z_llc(Z_R1, 1+src_off, Z_R0, Rsrc);
+        z_sth(Z_R0, 0+dst_off, Z_R0, Rdst);
+        z_sth(Z_R1, 2+dst_off, Z_R0, Rdst);
+        break;
+      case 1:
+        z_llc(Z_R0, 0+src_off, Z_R0, Rsrc);
+        z_sth(Z_R0, 0+dst_off, Z_R0, Rdst);
+        break;
+      default:
+        guarantee(false, "Impossible");
+        break;
+    }
+    src_off   +=  len-nprocessed;
+    dst_off   += (len-nprocessed)*2;
+    nprocessed = len;
+  }
+
+  //---< restore modified input registers  >---
+  if ((nprocessed > 0) && restore_inputs) {
+    z_agfi(Rsrc, -(nprocessed-src_off));
+    if (nprocessed < 1000000000) { // avoid int overflow
+      z_agfi(Rdst, -(nprocessed*2-dst_off));
+    } else {
+      z_agfi(Rdst, -(nprocessed-dst_off));
+      z_agfi(Rdst, -nprocessed);
+    }
+  }
+
+  BLOCK_COMMENT("} string_inflate_const");
   return offset() - block_start;
 }
 
--- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -198,6 +198,9 @@
   // Test a bit in a register. Result is reflected in CC.
   void testbit(Register r, unsigned int bitPos);
 
+  void prefetch_read(Address a);
+  void prefetch_update(Address a);
+
   // Clear a register, i.e. load const zero into reg. Return len (in bytes) of
   // generated instruction(s).
   //   whole_reg: Clear 64 bits if true, 32 bits otherwise.
@@ -836,7 +839,7 @@
   void load_mirror(Register mirror, Register method);
 
   //--------------------------
-  //---  perations on arrays.
+  //---  Operations on arrays.
   //--------------------------
   unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len);
   unsigned int Clear_Array_Const(long cnt, Register base);
@@ -849,20 +852,34 @@
   // Special String Intrinsics Implementation.
   //-------------------------------------------
   // Intrinsics for CompactStrings
-  // Compress char[] to byte[]. odd_reg contains cnt. tmp3 is only needed for precise behavior in failure case. Kills dst.
-  unsigned int string_compress(Register result, Register src, Register dst, Register odd_reg,
-                               Register even_reg, Register tmp, Register tmp2 = noreg);
+  //   Restores: src, dst
+  //   Uses:     cnt
+  //   Kills:    tmp, Z_R0, Z_R1.
+  //   Early clobber: result.
+  //   Boolean precise controls accuracy of result value.
+  unsigned int string_compress(Register result, Register src, Register dst, Register cnt,
+                               Register tmp,    bool precise);
+
+  // Inflate byte[] to char[].
+  unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp);
+
+  // Inflate byte[] to char[].
+  //   Restores: src, dst
+  //   Uses:     cnt
+  //   Kills:    tmp, Z_R0, Z_R1.
+  unsigned int string_inflate(Register src, Register dst, Register cnt, Register tmp);
+
+  // Inflate byte[] to char[], length known at compile time.
+  //   Restores: src, dst
+  //   Kills:    tmp, Z_R0, Z_R1.
+  // Note:
+  //   len is signed int. Counts # characters, not bytes.
+  unsigned int string_inflate_const(Register src, Register dst, Register tmp, int len);
 
   // Kills src.
   unsigned int has_negatives(Register result, Register src, Register cnt,
                              Register odd_reg, Register even_reg, Register tmp);
 
-  // Inflate byte[] to char[].
-  unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp);
-  // Odd_reg contains cnt. Kills src.
-  unsigned int string_inflate(Register src, Register dst, Register odd_reg,
-                              Register even_reg, Register tmp);
-
   unsigned int string_compare(Register str1, Register str2, Register cnt1, Register cnt2,
                               Register odd_reg, Register even_reg, Register result, int ae);
 
--- a/src/hotspot/cpu/s390/s390.ad	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/s390/s390.ad	Thu Dec 07 11:54:55 2017 +0000
@@ -10267,14 +10267,14 @@
 %}
 
 // char[] to byte[] compression
-instruct string_compress(iRegP src, rarg5RegP dst, iRegI result, roddRegI len, revenRegI evenReg, iRegI tmp, flagsReg cr) %{
+instruct string_compress(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set result (StrCompressedCopy src (Binary dst len)));
-  effect(TEMP_DEF result, USE_KILL dst, USE_KILL len, TEMP evenReg, TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "String Compress $src->$dst($len) -> $result" %}
   ins_encode %{
     __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register,
-                       $evenReg$$Register, $tmp$$Register);
+                       $tmp$$Register, false);
   %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10293,13 +10293,25 @@
 //%}
 
 // byte[] to char[] inflation
-instruct string_inflate(Universe dummy, rarg5RegP src, iRegP dst, roddRegI len, revenRegI evenReg, iRegI tmp, flagsReg cr) %{
+instruct string_inflate(Universe dummy, iRegP src, iRegP dst, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set dummy (StrInflatedCopy src (Binary dst len)));
-  effect(USE_KILL src, USE_KILL len, TEMP evenReg, TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "String Inflate $src->$dst($len)" %}
   ins_encode %{
-    __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $evenReg$$Register, $tmp$$Register);
+    __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register);
+  %}
+  ins_pipe(pipe_class_dummy);
+%}
+
+// byte[] to char[] inflation
+instruct string_inflate_const(Universe dummy, iRegP src, iRegP dst, iRegI tmp, immI len, flagsReg cr) %{
+  match(Set dummy (StrInflatedCopy src (Binary dst len)));
+  effect(TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  ins_cost(300);
+  format %{ "String Inflate (constLen) $src->$dst($len)" %}
+  ins_encode %{
+    __ string_inflate_const($src$$Register, $dst$$Register, $tmp$$Register, $len$$constant);
   %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10318,14 +10330,14 @@
 %}
 
 // encode char[] to byte[] in ISO_8859_1
-instruct encode_iso_array(rarg5RegP src, iRegP dst, iRegI result, roddRegI len, revenRegI evenReg, iRegI tmp, iRegI tmp2, flagsReg cr) %{
+instruct encode_iso_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set result (EncodeISOArray src (Binary dst len)));
-  effect(TEMP_DEF result, USE_KILL src, USE_KILL len, TEMP evenReg, TEMP tmp, TEMP tmp2, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "Encode array $src->$dst($len) -> $result" %}
   ins_encode %{
     __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register,
-                       $evenReg$$Register, $tmp$$Register, $tmp2$$Register);
+                       $tmp$$Register, true);
   %}
   ins_pipe(pipe_class_dummy);
 %}
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2884,12 +2884,12 @@
   // ztos
   BTB_BEGIN(is_Bool, bsize, "putfield_or_static:is_Bool");
   __ pop(ztos);
-  if (do_rewrite) {
+  if (!is_static) {
     pop_and_check_object(obj);
   }
   __ z_nilf(Z_tos, 0x1);
   __ z_stc(Z_tos, field);
-  if (!is_static) {
+  if (do_rewrite) {
     patch_bytecode(Bytecodes::_fast_zputfield, bc, Z_ARG5, true, byte_no);
   }
   __ z_bru(Done);
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -398,8 +398,13 @@
   if (o == NULL) {
     __ set(NULL_WORD, reg);
   } else {
+#ifdef ASSERT
+    {
+      ThreadInVMfromNative tiv(JavaThread::current());
+      assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(o)), "should be real oop");
+    }
+#endif
     int oop_index = __ oop_recorder()->find_index(o);
-    assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(o)), "should be real oop");
     RelocationHolder rspec = oop_Relocation::spec(oop_index);
     __ set(NULL_WORD, reg, rspec); // Will be set when the nmethod is created
   }
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -898,7 +898,9 @@
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
           assert_different_registers(addr, count, tmp);
 
-          Label L_loop;
+          Label L_loop, L_done;
+
+          __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
 
           __ sll_ptr(count, LogBytesPerHeapOop, count);
           __ sub(count, BytesPerHeapOop, count);
@@ -914,6 +916,7 @@
           __ subcc(count, 1, count);
           __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
           __ delayed()->add(addr, 1, addr);
+        __ BIND(L_done);
         }
         break;
       case BarrierSet::ModRef:
--- a/src/hotspot/cpu/x86/assembler_x86.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1256,7 +1256,7 @@
 
 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -1266,7 +1266,7 @@
 void Assembler::addsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -1276,7 +1276,7 @@
 
 void Assembler::addss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1285,7 +1285,7 @@
 void Assembler::addss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -1295,7 +1295,7 @@
 void Assembler::aesdec(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDE);
   emit_operand(dst, src);
@@ -1303,7 +1303,7 @@
 
 void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDE);
   emit_int8(0xC0 | encode);
@@ -1312,7 +1312,7 @@
 void Assembler::aesdeclast(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDF);
   emit_operand(dst, src);
@@ -1320,7 +1320,7 @@
 
 void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDF);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1329,7 +1329,7 @@
 void Assembler::aesenc(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDC);
   emit_operand(dst, src);
@@ -1337,7 +1337,7 @@
 
 void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDC);
   emit_int8(0xC0 | encode);
@@ -1346,7 +1346,7 @@
 void Assembler::aesenclast(XMMRegister dst, Address src) {
   assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDD);
   emit_operand(dst, src);
@@ -1354,7 +1354,7 @@
 
 void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_aes(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xDD);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1387,7 +1387,7 @@
 
 void Assembler::andnl(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1396,7 +1396,7 @@
 void Assembler::andnl(Register dst, Register src1, Address src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_operand(dst, src2);
@@ -1424,7 +1424,7 @@
 
 void Assembler::blsil(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1433,7 +1433,7 @@
 void Assembler::blsil(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rbx, src);
@@ -1441,7 +1441,7 @@
 
 void Assembler::blsmskl(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1450,7 +1450,7 @@
 void Assembler::blsmskl(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rdx, src);
@@ -1458,7 +1458,7 @@
 
 void Assembler::blsrl(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1467,7 +1467,7 @@
 void Assembler::blsrl(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rcx, src);
@@ -1753,7 +1753,7 @@
 
 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5A);
@@ -1763,7 +1763,7 @@
 void Assembler::cvtsd2ss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -1817,7 +1817,7 @@
 
 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5A);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -1826,7 +1826,7 @@
 void Assembler::cvtss2sd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5A);
@@ -1870,7 +1870,7 @@
 void Assembler::divsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -1880,7 +1880,7 @@
 
 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -1890,7 +1890,7 @@
 void Assembler::divss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -1899,7 +1899,7 @@
 
 void Assembler::divss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -2105,7 +2105,7 @@
 void Assembler::ldmxcsr( Address src) {
   if (UseAVX > 0 ) {
     InstructionMark im(this);
-    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
     vex_prefix(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
     emit_int8((unsigned char)0xAE);
     emit_operand(as_Register(2), src);
@@ -2784,7 +2784,7 @@
 
 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x10);
@@ -2794,7 +2794,7 @@
 void Assembler::movsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -2805,7 +2805,7 @@
 void Assembler::movsd(Address dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.reset_is_clear_context();
   attributes.set_rex_vex_w_reverted();
@@ -2816,7 +2816,7 @@
 
 void Assembler::movss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x10);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -2825,7 +2825,7 @@
 void Assembler::movss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x10);
@@ -2835,7 +2835,7 @@
 void Assembler::movss(Address dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   attributes.reset_is_clear_context();
   simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
@@ -2931,7 +2931,7 @@
 void Assembler::mulsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -2941,7 +2941,7 @@
 
 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -2951,7 +2951,7 @@
 void Assembler::mulss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -2960,7 +2960,7 @@
 
 void Assembler::mulss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4289,7 +4289,7 @@
 
 void Assembler::pblendw(XMMRegister dst, XMMRegister src, int imm8) {
   assert(VM_Version::supports_sse4_1(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
   emit_int8((unsigned char)0x0E);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4388,7 +4388,7 @@
 
 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x51);
@@ -4398,7 +4398,7 @@
 void Assembler::sqrtsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4408,7 +4408,7 @@
 
 void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x51);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4421,7 +4421,7 @@
 void Assembler::sqrtss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x51);
@@ -4484,7 +4484,7 @@
 
 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4494,7 +4494,7 @@
 void Assembler::subsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4504,7 +4504,7 @@
 
 void Assembler::subss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false , /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true , /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4513,7 +4513,7 @@
 void Assembler::subss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4735,7 +4735,7 @@
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4745,7 +4745,7 @@
 
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -4755,7 +4755,7 @@
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
@@ -4764,7 +4764,7 @@
 
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x58);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4773,7 +4773,7 @@
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4783,7 +4783,7 @@
 
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -4793,7 +4793,7 @@
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
@@ -4802,7 +4802,7 @@
 
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5E);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4810,7 +4810,7 @@
 
 void Assembler::vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
   assert(VM_Version::supports_fma(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xB9);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4818,7 +4818,7 @@
 
 void Assembler::vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
   assert(VM_Version::supports_fma(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xB9);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4827,7 +4827,7 @@
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4837,7 +4837,7 @@
 
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -4847,7 +4847,7 @@
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
@@ -4856,7 +4856,7 @@
 
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x59);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -4865,7 +4865,7 @@
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
   attributes.set_rex_vex_w_reverted();
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
@@ -4875,7 +4875,7 @@
 
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_rex_vex_w_reverted();
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4885,7 +4885,7 @@
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
   vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
@@ -4894,7 +4894,7 @@
 
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
   emit_int8(0x5C);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -5203,6 +5203,24 @@
   emit_operand(dst, src);
 }
 
+void Assembler::vsqrtps(XMMRegister dst, XMMRegister src, int vector_len) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+  int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
+  emit_int8(0x51);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::vsqrtps(XMMRegister dst, Address src, int vector_len) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionMark im(this);
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
+  attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
+  vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
+  emit_int8(0x51);
+  emit_operand(dst, src);
+}
+
 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ false, /* uses_vl */ true);
@@ -5377,7 +5395,7 @@
 void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
   assert(VM_Version::supports_avx() && (vector_len == 0) ||
          VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
-  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8(0x01);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -5436,7 +5454,7 @@
 
 void Assembler::phaddw(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_sse3(), "");
-  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8(0x01);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -6679,7 +6697,7 @@
 
 void Assembler::vzeroupper() {
   if (VM_Version::supports_vzeroupper()) {
-    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+    InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
     (void)vex_prefix_and_encode(0, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
     emit_int8(0x77);
   }
@@ -7442,7 +7460,7 @@
 
 void Assembler::shlxl(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi2(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF7);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -7450,7 +7468,7 @@
 
 void Assembler::shlxq(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi2(), "");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF7);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -7985,7 +8003,7 @@
 
 void Assembler::andnq(Register dst, Register src1, Register src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -7994,7 +8012,7 @@
 void Assembler::andnq(Register dst, Register src1, Address src2) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF2);
   emit_operand(dst, src2);
@@ -8022,7 +8040,7 @@
 
 void Assembler::blsiq(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8031,7 +8049,7 @@
 void Assembler::blsiq(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rbx, src);
@@ -8039,7 +8057,7 @@
 
 void Assembler::blsmskq(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8048,7 +8066,7 @@
 void Assembler::blsmskq(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rdx, src);
@@ -8056,7 +8074,7 @@
 
 void Assembler::blsrq(Register dst, Register src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8065,7 +8083,7 @@
 void Assembler::blsrq(Register dst, Address src) {
   assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
   InstructionMark im(this);
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF3);
   emit_operand(rcx, src);
@@ -8504,7 +8522,7 @@
 
 void Assembler::mulxq(Register dst1, Register dst2, Register src) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes);
   emit_int8((unsigned char)0xF6);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8667,7 +8685,7 @@
 
 void Assembler::rorxq(Register dst, Register src, int imm8) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
   emit_int8((unsigned char)0xF0);
   emit_int8((unsigned char)(0xC0 | encode));
@@ -8676,7 +8694,7 @@
 
 void Assembler::rorxd(Register dst, Register src, int imm8) {
   assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
-  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
+  InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
   int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
   emit_int8((unsigned char)0xF0);
   emit_int8((unsigned char)(0xC0 | encode));
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1919,9 +1919,11 @@
   void vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
   void vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
 
-  // Sqrt Packed Floating-Point Values - Double precision only
+  // Sqrt Packed Floating-Point Values
   void vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len);
   void vsqrtpd(XMMRegister dst, Address src, int vector_len);
+  void vsqrtps(XMMRegister dst, XMMRegister src, int vector_len);
+  void vsqrtps(XMMRegister dst, Address src, int vector_len);
 
   // Bitwise Logical AND of Packed Floating-Point Values
   void andpd(XMMRegister dst, XMMRegister src);
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -6630,6 +6630,13 @@
   }
   // Clear upper bits of YMM registers to avoid SSE <-> AVX transition penalty.
   vzeroupper();
+  // Reset k1 to 0xffff.
+  if (VM_Version::supports_evex()) {
+    push(rcx);
+    movl(rcx, 0xffff);
+    kmovwl(k1, rcx);
+    pop(rcx);
+  }
 
 #ifndef _LP64
   // Either restore the x87 floating pointer control word after returning
--- a/src/hotspot/cpu/x86/nativeInst_x86.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -706,14 +706,11 @@
 inline bool NativeInstruction::is_safepoint_poll() {
 #ifdef AMD64
   if (SafepointMechanism::uses_thread_local_poll()) {
-    // We know that the poll must have a REX_B prefix since we enforce its source to be
-    // a rex-register and the destination to be rax.
     const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
-    const bool is_test_opcode = ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl;
-    const bool is_rax_target = (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
-    if (has_rex_prefix && is_test_opcode && is_rax_target) {
-      return true;
-    }
+    const int test_offset = has_rex_prefix ? 1 : 0;
+    const bool is_test_opcode = ubyte_at(test_offset) == NativeTstRegMem::instruction_code_memXregl;
+    const bool is_rax_target = (ubyte_at(test_offset + 1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
+    return is_test_opcode && is_rax_target;
   }
   // Try decoding a near safepoint first:
   if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -3388,26 +3388,63 @@
   // No exception case
   __ bind(noException);
 
-  Label no_adjust, bail;
+  Label no_adjust, bail, no_prefix, not_special;
   if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
     // If our stashed return pc was modified by the runtime we avoid touching it
     __ cmpptr(rbx, Address(rbp, wordSize));
     __ jccb(Assembler::notEqual, no_adjust);
 
+    // Skip over the poll instruction.
+    // See NativeInstruction::is_safepoint_poll()
+    // Possible encodings:
+    //      85 00       test   %eax,(%rax)
+    //      85 01       test   %eax,(%rcx)
+    //      85 02       test   %eax,(%rdx)
+    //      85 03       test   %eax,(%rbx)
+    //      85 06       test   %eax,(%rsi)
+    //      85 07       test   %eax,(%rdi)
+    //
+    //   41 85 00       test   %eax,(%r8)
+    //   41 85 01       test   %eax,(%r9)
+    //   41 85 02       test   %eax,(%r10)
+    //   41 85 03       test   %eax,(%r11)
+    //   41 85 06       test   %eax,(%r14)
+    //   41 85 07       test   %eax,(%r15)
+    //
+    //      85 04 24    test   %eax,(%rsp)
+    //   41 85 04 24    test   %eax,(%r12)
+    //      85 45 00    test   %eax,0x0(%rbp)
+    //   41 85 45 00    test   %eax,0x0(%r13)
+
+    __ cmpb(Address(rbx, 0), NativeTstRegMem::instruction_rex_b_prefix);
+    __ jcc(Assembler::notEqual, no_prefix);
+    __ addptr(rbx, 1);
+    __ bind(no_prefix);
+#ifdef ASSERT
+    __ movptr(rax, rbx); // remember where 0x85 should be, for verification below
+#endif
+    // r12/r13/rsp/rbp base encoding takes 3 bytes with the following register values:
+    // r12/rsp 0x04
+    // r13/rbp 0x05
+    __ movzbq(rcx, Address(rbx, 1));
+    __ andptr(rcx, 0x07); // looking for 0x04 .. 0x05
+    __ subptr(rcx, 4);    // looking for 0x00 .. 0x01
+    __ cmpptr(rcx, 1);
+    __ jcc(Assembler::above, not_special);
+    __ addptr(rbx, 1);
+    __ bind(not_special);
 #ifdef ASSERT
     // Verify the correct encoding of the poll we're about to skip.
-    // See NativeInstruction::is_safepoint_poll()
-    __ cmpb(Address(rbx, 0), NativeTstRegMem::instruction_rex_b_prefix);
-    __ jcc(Assembler::notEqual, bail);
-    __ cmpb(Address(rbx, 1), NativeTstRegMem::instruction_code_memXregl);
+    __ cmpb(Address(rax, 0), NativeTstRegMem::instruction_code_memXregl);
     __ jcc(Assembler::notEqual, bail);
     // Mask out the modrm bits
-    __ testb(Address(rbx, 2), NativeTstRegMem::modrm_mask);
+    __ testb(Address(rax, 1), NativeTstRegMem::modrm_mask);
     // rax encodes to 0, so if the bits are nonzero it's incorrect
     __ jcc(Assembler::notZero, bail);
 #endif
     // Adjust return pc forward to step over the safepoint poll instruction
-    __ addptr(Address(rbp, wordSize), 3);
+    __ addptr(rbx, 2);
+    __ movptr(Address(rbp, wordSize), rbx);
   }
 
   __ bind(no_adjust);
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1264,9 +1264,12 @@
           CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
-          Label L_loop;
+          Label L_loop, L_done;
           const Register end = count;
 
+          __ testl(count, count);
+          __ jcc(Assembler::zero, L_done); // zero count - nothing to do
+
           __ leaq(end, Address(start, count, TIMES_OOP, 0));  // end == start+count*oop_size
           __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
           __ shrptr(start, CardTableModRefBS::card_shift);
@@ -1280,6 +1283,7 @@
           __ movb(Address(start, count, Address::times_1), 0);
           __ decrement(count);
           __ jcc(Assembler::greaterEqual, L_loop);
+        __ BIND(L_done);
         }
         break;
       default:
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -629,18 +629,26 @@
     _features &= ~CPU_SSE;
 
   // first try initial setting and detect what we can support
+  int use_avx_limit = 0;
   if (UseAVX > 0) {
     if (UseAVX > 2 && supports_evex()) {
-      UseAVX = 3;
+      use_avx_limit = 3;
     } else if (UseAVX > 1 && supports_avx2()) {
-      UseAVX = 2;
+      use_avx_limit = 2;
     } else if (UseAVX > 0 && supports_avx()) {
-      UseAVX = 1;
+      use_avx_limit = 1;
     } else {
-      UseAVX = 0;
+      use_avx_limit = 0;
     }
+  }
+  if (FLAG_IS_DEFAULT(UseAVX)) {
+    FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
+  } else if (UseAVX > use_avx_limit) {
+    warning("UseAVX=%d is not supported on this CPU, setting it to UseAVX=%d", (int) UseAVX, use_avx_limit);
+    FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
   } else if (UseAVX < 0) {
-    UseAVX = 0;
+    warning("UseAVX=%d is not valid, setting it to UseAVX=0", (int) UseAVX);
+    FLAG_SET_DEFAULT(UseAVX, 0);
   }
 
   if (UseAVX < 3) {
@@ -710,16 +718,29 @@
   // UseSSE is set to the smaller of what hardware supports and what
   // the command line requires.  I.e., you cannot set UseSSE to 2 on
   // older Pentiums which do not support it.
-  if (UseSSE > 4) UseSSE=4;
-  if (UseSSE < 0) UseSSE=0;
-  if (!supports_sse4_1()) // Drop to 3 if no SSE4 support
-    UseSSE = MIN2((intx)3,UseSSE);
-  if (!supports_sse3()) // Drop to 2 if no SSE3 support
-    UseSSE = MIN2((intx)2,UseSSE);
-  if (!supports_sse2()) // Drop to 1 if no SSE2 support
-    UseSSE = MIN2((intx)1,UseSSE);
-  if (!supports_sse ()) // Drop to 0 if no SSE  support
-    UseSSE = 0;
+  int use_sse_limit = 0;
+  if (UseSSE > 0) {
+    if (UseSSE > 3 && supports_sse4_1()) {
+      use_sse_limit = 4;
+    } else if (UseSSE > 2 && supports_sse3()) {
+      use_sse_limit = 3;
+    } else if (UseSSE > 1 && supports_sse2()) {
+      use_sse_limit = 2;
+    } else if (UseSSE > 0 && supports_sse()) {
+      use_sse_limit = 1;
+    } else {
+      use_sse_limit = 0;
+    }
+  }
+  if (FLAG_IS_DEFAULT(UseSSE)) {
+    FLAG_SET_DEFAULT(UseSSE, use_sse_limit);
+  } else if (UseSSE > use_sse_limit) {
+    warning("UseSSE=%d is not supported on this CPU, setting it to UseSSE=%d", (int) UseSSE, use_sse_limit);
+    FLAG_SET_DEFAULT(UseSSE, use_sse_limit);
+  } else if (UseSSE < 0) {
+    warning("UseSSE=%d is not valid, setting it to UseSSE=0", (int) UseSSE);
+    FLAG_SET_DEFAULT(UseSSE, 0);
+  }
 
   // Use AES instructions if available.
   if (supports_aes()) {
--- a/src/hotspot/cpu/x86/x86.ad	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/cpu/x86/x86.ad	Thu Dec 07 11:54:55 2017 +0000
@@ -1252,6 +1252,7 @@
         ret_value = false;
       break;
     case Op_SqrtVD:
+    case Op_SqrtVF:
       if (UseAVX < 1) // enabled for AVX only
         ret_value = false;
       break;
@@ -2580,7 +2581,7 @@
 
 instruct sqrtF_reg(regF dst, regF src) %{
   predicate(UseSSE>=1);
-  match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
+  match(Set dst (SqrtF src));
 
   format %{ "sqrtss  $dst, $src" %}
   ins_cost(150);
@@ -2592,7 +2593,7 @@
 
 instruct sqrtF_mem(regF dst, memory src) %{
   predicate(UseSSE>=1);
-  match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
+  match(Set dst (SqrtF (LoadF src)));
 
   format %{ "sqrtss  $dst, $src" %}
   ins_cost(150);
@@ -2604,7 +2605,8 @@
 
 instruct sqrtF_imm(regF dst, immF con) %{
   predicate(UseSSE>=1);
-  match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
+  match(Set dst (SqrtF con));
+
   format %{ "sqrtss  $dst, [$constantaddress]\t# load from constant table: float=$con" %}
   ins_cost(150);
   ins_encode %{
@@ -8388,7 +8390,7 @@
 
 // --------------------------------- Sqrt --------------------------------------
 
-// Floating point vector sqrt - double precision only
+// Floating point vector sqrt
 instruct vsqrt2D_reg(vecX dst, vecX src) %{
   predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
   match(Set dst (SqrtVD src));
@@ -8455,6 +8457,94 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct vsqrt2F_reg(vecD dst, vecD src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed2F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt2F_mem(vecD dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed2F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt4F_reg(vecX dst, vecX src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed4F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt4F_mem(vecX dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed4F" %}
+  ins_encode %{
+    int vector_len = 0;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt8F_reg(vecY dst, vecY src) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed8F" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt8F_mem(vecY dst, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed8F" %}
+  ins_encode %{
+    int vector_len = 1;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt16F_reg(vecZ dst, vecZ src) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+  match(Set dst (SqrtVF src));
+  format %{ "vsqrtps  $dst,$src\t! sqrt packed16F" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsqrt16F_mem(vecZ dst, memory mem) %{
+  predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+  match(Set dst (SqrtVF (LoadVector mem)));
+  format %{ "vsqrtps  $dst,$mem\t! sqrt packed16F" %}
+  ins_encode %{
+    int vector_len = 2;
+    __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
 // ------------------------------ LeftShift -----------------------------------
 
 // Shorts/Chars vector left shift
--- a/src/hotspot/os/aix/osThread_aix.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/aix/osThread_aix.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
 
 // no precompiled headers
 
+#include "memory/allocation.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/os/aix/os_aix.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/aix/os_aix.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2490,6 +2490,22 @@
   return false;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = NULL;
+
+  // Always round to os::vm_page_size(), which may be larger than 4K.
+  bytes = align_up(bytes, os::vm_page_size());
+  result = reserve_mmaped_memory(bytes, requested_addr, 0);
+
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
--- a/src/hotspot/os/bsd/osThread_bsd.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/bsd/osThread_bsd.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "memory/allocation.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/bsd/os_bsd.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2350,6 +2350,17 @@
   return UseHugeTLBFS;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = pd_attempt_reserve_memory_at(bytes, requested_addr);
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
--- a/src/hotspot/os/linux/osContainer_linux.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/linux/osContainer_linux.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -323,7 +323,12 @@
     }
   }
 
-  if (mntinfo != NULL) fclose(mntinfo);
+  fclose(mntinfo);
+
+  if (memory == NULL || cpuset == NULL || cpu == NULL || cpuacct == NULL) {
+    log_debug(os, container)("Required cgroup subsystems not found");
+    return;
+  }
 
   /*
    * Read /proc/self/cgroup and map host mount point to
@@ -383,12 +388,7 @@
     }
   }
 
-  if (cgroup != NULL) fclose(cgroup);
-
-  if (memory == NULL || cpuset == NULL || cpu == NULL) {
-    log_debug(os, container)("Required cgroup subsystems not found");
-    return;
-  }
+  fclose(cgroup);
 
   // We need to update the amount of physical memory now that
   // command line arguments have been processed.
--- a/src/hotspot/os/linux/osThread_linux.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/linux/osThread_linux.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "memory/allocation.inline.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/linux/os_linux.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/linux/os_linux.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -59,6 +59,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timer.hpp"
 #include "semaphore_posix.hpp"
 #include "services/attachListener.hpp"
@@ -129,6 +130,7 @@
 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 
 #define LARGEPAGES_BIT (1 << 6)
+#define DAX_SHARED_BIT (1 << 8)
 ////////////////////////////////////////////////////////////////////////////////
 // global variables
 julong os::Linux::_physical_memory = 0;
@@ -1646,7 +1648,10 @@
         //
         // Dynamic loader will make all stacks executable after
         // this function returns, and will not do that again.
-        assert(Threads::first() == NULL, "no Java threads should exist yet.");
+#ifdef ASSERT
+        ThreadsListHandle tlh;
+        assert(tlh.length() == 0, "no Java threads should exist yet.");
+#endif
       } else {
         warning("You have loaded library %s which might have disabled stack guard. "
                 "The VM will try to fix the stack guard now.\n"
@@ -1874,16 +1879,13 @@
   // may have been queued at the same time.
 
   if (!_stack_is_executable) {
-    JavaThread *jt = Threads::first();
-
-    while (jt) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
       if (!jt->stack_guard_zone_unused() &&     // Stack not yet fully initialized
           jt->stack_guards_enabled()) {         // No pending stack overflow exceptions
         if (!os::guard_memory((char *)jt->stack_end(), jt->stack_guard_zone_size())) {
           warning("Attempt to reguard stack yellow zone failed.");
         }
       }
-      jt = jt->next();
     }
   }
 
@@ -3369,10 +3371,13 @@
 //           effective only if the bit 2 is cleared)
 // - (bit 5) hugetlb private memory
 // - (bit 6) hugetlb shared memory
+// - (bit 7) dax private memory
+// - (bit 8) dax shared memory
 //
-static void set_coredump_filter(void) {
+static void set_coredump_filter(bool largepages, bool dax_shared) {
   FILE *f;
   long cdm;
+  bool filter_changed = false;
 
   if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
     return;
@@ -3385,8 +3390,15 @@
 
   rewind(f);
 
-  if ((cdm & LARGEPAGES_BIT) == 0) {
+  if (largepages && (cdm & LARGEPAGES_BIT) == 0) {
     cdm |= LARGEPAGES_BIT;
+    filter_changed = true;
+  }
+  if (dax_shared && (cdm & DAX_SHARED_BIT) == 0) {
+    cdm |= DAX_SHARED_BIT;
+    filter_changed = true;
+  }
+  if (filter_changed) {
     fprintf(f, "%#lx", cdm);
   }
 
@@ -3525,7 +3537,7 @@
   size_t large_page_size = Linux::setup_large_page_size();
   UseLargePages          = Linux::setup_large_page_type(large_page_size);
 
-  set_coredump_filter();
+  set_coredump_filter(true /*largepages*/, false /*dax_shared*/);
 }
 
 #ifndef SHM_HUGETLB
@@ -3896,6 +3908,17 @@
   return UseTransparentHugePages || UseHugeTLBFS;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = pd_attempt_reserve_memory_at(bytes, requested_addr);
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
@@ -4947,25 +4970,20 @@
         UseNUMA = false;
       }
     }
-    // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
-    // we can make the adaptive lgrp chunk resizing work. If the user specified
-    // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
-    // disable adaptive resizing.
-    if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
-      if (FLAG_IS_DEFAULT(UseNUMA)) {
-        UseNUMA = false;
-      } else {
-        if (FLAG_IS_DEFAULT(UseLargePages) &&
-            FLAG_IS_DEFAULT(UseSHM) &&
-            FLAG_IS_DEFAULT(UseHugeTLBFS)) {
-          UseLargePages = false;
-        } else if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
-          warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
-          UseAdaptiveSizePolicy = false;
-          UseAdaptiveNUMAChunkSizing = false;
-        }
+
+    if (UseParallelGC && UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
+      // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
+      // we can make the adaptive lgrp chunk resizing work. If the user specified both
+      // UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn
+      // and disable adaptive resizing.
+      if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
+        warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, "
+                "disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
+        UseAdaptiveSizePolicy = false;
+        UseAdaptiveNUMAChunkSizing = false;
       }
     }
+
     if (!UseNUMA && ForceNUMA) {
       UseNUMA = true;
     }
@@ -5012,6 +5030,9 @@
   // initialize thread priority policy
   prio_init();
 
+  if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
+    set_coredump_filter(false /*largepages*/, true /*dax_shared*/);
+  }
   return JNI_OK;
 }
 
--- a/src/hotspot/os/posix/os_posix.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/posix/os_posix.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -40,6 +40,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/utsname.h>
 #include <time.h>
@@ -52,6 +53,20 @@
 #endif
 #define IS_VALID_PID(p) (p > 0 && p < MAX_PID)
 
+#ifndef MAP_ANONYMOUS
+  #define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define check_with_errno(check_type, cond, msg)                             \
+  do {                                                                      \
+    int err = errno;                                                        \
+    check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err),   \
+               os::errno_name(err));                                        \
+} while (false)
+
+#define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
+#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
+
 // Check core dump limit and report possible place where core can be found
 void os::check_dump_limit(char* buffer, size_t bufferSize) {
   if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
@@ -145,10 +160,124 @@
   return;
 }
 
+int os::create_file_for_heap(const char* dir) {
+
+  const char name_template[] = "/jvmheap.XXXXXX";
+
+  char *fullname = (char*)os::malloc((strlen(dir) + strlen(name_template) + 1), mtInternal);
+  if (fullname == NULL) {
+    vm_exit_during_initialization(err_msg("Malloc failed during creation of backing file for heap (%s)", os::strerror(errno)));
+    return -1;
+  }
+  (void)strncpy(fullname, dir, strlen(dir)+1);
+  (void)strncat(fullname, name_template, strlen(name_template));
+
+  os::native_path(fullname);
+
+  sigset_t set, oldset;
+  int ret = sigfillset(&set);
+  assert_with_errno(ret == 0, "sigfillset returned error");
+
+  // set the file creation mask.
+  mode_t file_mode = S_IRUSR | S_IWUSR;
+
+  // create a new file.
+  int fd = mkstemp(fullname);
+
+  if (fd < 0) {
+    warning("Could not create file for heap with template %s", fullname);
+    os::free(fullname);
+    return -1;
+  }
+
+  // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted.
+  ret = unlink(fullname);
+  assert_with_errno(ret == 0, "unlink returned error");
+
+  os::free(fullname);
+  return fd;
+}
+
+static char* reserve_mmapped_memory(size_t bytes, char* requested_addr) {
+  char * addr;
+  int flags = MAP_PRIVATE NOT_AIX( | MAP_NORESERVE ) | MAP_ANONYMOUS;
+  if (requested_addr != NULL) {
+    assert((uintptr_t)requested_addr % os::vm_page_size() == 0, "Requested address should be aligned to OS page size");
+    flags |= MAP_FIXED;
+  }
+
+  // Map reserved/uncommitted pages PROT_NONE so we fail early if we
+  // touch an uncommitted page. Otherwise, the read/write might
+  // succeed if we have enough swap space to back the physical page.
+  addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
+                       flags, -1, 0);
+
+  if (addr != MAP_FAILED) {
+    MemTracker::record_virtual_memory_reserve((address)addr, bytes, CALLER_PC);
+    return addr;
+  }
+  return NULL;
+}
+
+static int util_posix_fallocate(int fd, off_t offset, off_t len) {
+#ifdef __APPLE__
+  fstore_t store = { F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, len };
+  // First we try to get a continuous chunk of disk space
+  int ret = fcntl(fd, F_PREALLOCATE, &store);
+  if (ret == -1) {
+    // Maybe we are too fragmented, try to allocate non-continuous range
+    store.fst_flags = F_ALLOCATEALL;
+    ret = fcntl(fd, F_PREALLOCATE, &store);
+  }
+  if(ret != -1) {
+    return ftruncate(fd, len);
+  }
+  return -1;
+#else
+  return posix_fallocate(fd, offset, len);
+#endif
+}
+
+// Map the given address range to the provided file descriptor.
+char* os::map_memory_to_file(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+
+  // allocate space for the file
+  if (util_posix_fallocate(fd, 0, (off_t)size) != 0) {
+    vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory."));
+    return NULL;
+  }
+
+  int prot = PROT_READ | PROT_WRITE;
+  int flags = MAP_SHARED;
+  if (base != NULL) {
+    flags |= MAP_FIXED;
+  }
+  char* addr = (char*)mmap(base, size, prot, flags, fd, 0);
+
+  if (addr == MAP_FAILED) {
+    return NULL;
+  }
+  if (base != NULL && addr != base) {
+    if (!os::release_memory(addr, size)) {
+      warning("Could not release memory on unsuccessful file mapping");
+     }
+    return NULL;
+  }
+  return addr;
+}
+
+char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+  assert(base != NULL, "Base cannot be NULL");
+
+  return map_memory_to_file(base, size, fd);
+}
+
 // Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
 // so on posix, unmap the section at the start and at the end of the chunk that we mapped
 // rather than unmapping and remapping the whole chunk to get requested alignment.
-char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
       "Alignment must be a multiple of allocation granularity (page size)");
   assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
@@ -156,7 +285,20 @@
   size_t extra_size = size + alignment;
   assert(extra_size >= size, "overflow, size is too large to allow alignment");
 
-  char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+  char* extra_base;
+  if (file_desc != -1) {
+    // For file mapping, we do not call os:reserve_memory(extra_size, NULL, alignment, file_desc) because
+    // we need to deal with shrinking of the file space later when we release extra memory after alignment.
+    // We also cannot called os:reserve_memory() with file_desc set to -1 because on aix we might get SHM memory.
+    // So here to call a helper function while reserve memory for us. After we have a aligned base,
+    // we will replace anonymous mapping with file mapping.
+    extra_base = reserve_mmapped_memory(extra_size, NULL);
+    if (extra_base != NULL) {
+      MemTracker::record_virtual_memory_reserve((address)extra_base, extra_size, CALLER_PC);
+    }
+  } else {
+    extra_base = os::reserve_memory(extra_size, NULL, alignment);
+  }
 
   if (extra_base == NULL) {
     return NULL;
@@ -183,6 +325,13 @@
       os::release_memory(extra_base + begin_offset + size, end_offset);
   }
 
+  if (file_desc != -1) {
+    // After we have an aligned address, we can replace anonymous mapping with file mapping
+    if (replace_existing_mapping_with_file_mapping(aligned_base, size, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+    MemTracker::record_virtual_memory_commit((address)aligned_base, size, CALLER_PC);
+  }
   return aligned_base;
 }
 
@@ -478,8 +627,7 @@
 // interrupt support
 
 void os::interrupt(Thread* thread) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
 
@@ -499,12 +647,10 @@
 
   ParkEvent * ev = thread->_ParkEvent ;
   if (ev != NULL) ev->unpark() ;
-
 }
 
 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
 
@@ -1351,16 +1497,6 @@
   }
 }
 
-#define check_with_errno(check_type, cond, msg)                             \
-  do {                                                                      \
-    int err = errno;                                                        \
-    check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err),   \
-               os::errno_name(err));                                        \
-} while (false)
-
-#define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
-#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
-
 // POSIX unamed semaphores are not supported on OS X.
 #ifndef __APPLE__
 
--- a/src/hotspot/os/solaris/os_solaris.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2585,6 +2585,17 @@
   return addr;
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  char* result = pd_attempt_reserve_memory_at(bytes, requested_addr);
+  if (result != NULL) {
+    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+  }
+  return result;
+}
+
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
--- a/src/hotspot/os/windows/os_windows.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os/windows/os_windows.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2904,6 +2904,75 @@
   UseLargePages = success;
 }
 
+int os::create_file_for_heap(const char* dir) {
+
+  const char name_template[] = "/jvmheap.XXXXXX";
+  char *fullname = (char*)os::malloc((strlen(dir) + strlen(name_template) + 1), mtInternal);
+  if (fullname == NULL) {
+    vm_exit_during_initialization(err_msg("Malloc failed during creation of backing file for heap (%s)", os::strerror(errno)));
+    return -1;
+  }
+
+  (void)strncpy(fullname, dir, strlen(dir)+1);
+  (void)strncat(fullname, name_template, strlen(name_template));
+
+  os::native_path(fullname);
+
+  char *path = _mktemp(fullname);
+  if (path == NULL) {
+    warning("_mktemp could not create file name from template %s (%s)", fullname, os::strerror(errno));
+    os::free(fullname);
+    return -1;
+  }
+
+  int fd = _open(path, O_RDWR | O_CREAT | O_TEMPORARY | O_EXCL, S_IWRITE | S_IREAD);
+
+  os::free(fullname);
+  if (fd < 0) {
+    warning("Problem opening file for heap (%s)", os::strerror(errno));
+    return -1;
+  }
+  return fd;
+}
+
+// If 'base' is not NULL, function will return NULL if it cannot get 'base'
+char* os::map_memory_to_file(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+
+  HANDLE fh = (HANDLE)_get_osfhandle(fd);
+#ifdef _LP64
+  HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,
+    (DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), NULL);
+#else
+  HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,
+    0, (DWORD)size, NULL);
+#endif
+  if (fileMapping == NULL) {
+    if (GetLastError() == ERROR_DISK_FULL) {
+      vm_exit_during_initialization(err_msg("Could not allocate sufficient disk space for Java heap"));
+    }
+    else {
+      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+    }
+
+    return NULL;
+  }
+
+  LPVOID addr = MapViewOfFileEx(fileMapping, FILE_MAP_WRITE, 0, 0, size, base);
+
+  CloseHandle(fileMapping);
+
+  return (char*)addr;
+}
+
+char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd) {
+  assert(fd != -1, "File descriptor is not valid");
+  assert(base != NULL, "Base address cannot be NULL");
+
+  release_memory(base, size);
+  return map_memory_to_file(base, size, fd);
+}
+
 // On win32, one cannot release just a part of reserved memory, it's an
 // all or nothing deal.  When we split a reservation, we must break the
 // reservation into two reservations.
@@ -2923,7 +2992,7 @@
 // Multiple threads can race in this code but it's not possible to unmap small sections of
 // virtual space to get requested alignment, like posix-like os's.
 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
-char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
          "Alignment must be a multiple of allocation granularity (page size)");
   assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
@@ -2934,16 +3003,20 @@
   char* aligned_base = NULL;
 
   do {
-    char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+    char* extra_base = os::reserve_memory(extra_size, NULL, alignment, file_desc);
     if (extra_base == NULL) {
       return NULL;
     }
     // Do manual alignment
     aligned_base = align_up(extra_base, alignment);
 
-    os::release_memory(extra_base, extra_size);
-
-    aligned_base = os::reserve_memory(size, aligned_base);
+    if (file_desc != -1) {
+      os::unmap_memory(extra_base, extra_size);
+    } else {
+      os::release_memory(extra_base, extra_size);
+    }
+
+    aligned_base = os::reserve_memory(size, aligned_base, 0, file_desc);
 
   } while (aligned_base == NULL);
 
@@ -2989,6 +3062,11 @@
   return reserve_memory(bytes, requested_addr);
 }
 
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
+  assert(file_desc >= 0, "file_desc is not valid");
+  return map_memory_to_file(requested_addr, bytes, file_desc);
+}
+
 size_t os::large_page_size() {
   return _large_page_size;
 }
@@ -3490,9 +3568,7 @@
 void os::hint_no_preempt() {}
 
 void os::interrupt(Thread* thread) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread ||
-         Threads_lock->owned_by_self(),
-         "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
   osthread->set_interrupted(true);
@@ -3513,8 +3589,7 @@
 
 
 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
-         "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
   // There is no synchronization between the setting of the interrupt
--- a/src/hotspot/os_cpu/linux_zero/atomic_linux_zero.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os_cpu/linux_zero/atomic_linux_zero.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -30,74 +30,6 @@
 
 // Implementation of class atomic
 
-#ifdef M68K
-
-/*
- * __m68k_cmpxchg
- *
- * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
- * Returns newval on success and oldval if no exchange happened.
- * This implementation is processor specific and works on
- * 68020 68030 68040 and 68060.
- *
- * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
- * instruction.
- * Using a kernelhelper would be better for arch complete implementation.
- *
- */
-
-static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
-  int ret;
-  __asm __volatile ("cas%.l %0,%2,%1"
-                   : "=d" (ret), "+m" (*(ptr))
-                   : "d" (newval), "0" (oldval));
-  return ret;
-}
-
-/* Perform an atomic compare and swap: if the current value of `*PTR'
-   is OLDVAL, then write NEWVAL into `*PTR'.  Return the contents of
-   `*PTR' before the operation.*/
-static inline int m68k_compare_and_swap(int newval,
-                                        volatile int *ptr,
-                                        int oldval) {
-  for (;;) {
-      int prev = *ptr;
-      if (prev != oldval)
-        return prev;
-
-      if (__m68k_cmpxchg (prev, newval, ptr) == newval)
-        // Success.
-        return prev;
-
-      // We failed even though prev == oldval.  Try again.
-    }
-}
-
-/* Atomically add an int to memory.  */
-static inline int m68k_add_and_fetch(int add_value, volatile int *ptr) {
-  for (;;) {
-      // Loop until success.
-
-      int prev = *ptr;
-
-      if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
-        return prev + add_value;
-    }
-}
-
-/* Atomically write VALUE into `*PTR' and returns the previous
-   contents of `*PTR'.  */
-static inline int m68k_lock_test_and_set(int newval, volatile int *ptr) {
-  for (;;) {
-      // Loop until success.
-      int prev = *ptr;
-
-      if (__m68k_cmpxchg (prev, newval, ptr) == prev)
-        return prev;
-    }
-}
-#endif // M68K
-
 #ifdef ARM
 
 /*
@@ -176,11 +108,7 @@
 #ifdef ARM
   return add_using_helper<int>(arm_add_and_fetch, add_value, dest);
 #else
-#ifdef M68K
-  return add_using_helper<int>(m68k_add_and_fetch, add_value, dest);
-#else
   return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
 #endif // ARM
 }
 
@@ -201,9 +129,6 @@
 #ifdef ARM
   return xchg_using_helper<int>(arm_lock_test_and_set, exchange_value, dest);
 #else
-#ifdef M68K
-  return xchg_using_helper<int>(m68k_lock_test_and_set, exchange_value, dest);
-#else
   // __sync_lock_test_and_set is a bizarrely named atomic exchange
   // operation.  Note that some platforms only support this with the
   // limitation that the only valid value to store is the immediate
@@ -215,7 +140,6 @@
   // barrier.
   __sync_synchronize();
   return result;
-#endif // M68K
 #endif // ARM
 }
 
@@ -243,11 +167,7 @@
 #ifdef ARM
   return cmpxchg_using_helper<int>(arm_compare_and_swap, exchange_value, dest, compare_value);
 #else
-#ifdef M68K
-  return cmpxchg_using_helper<int>(m68k_compare_and_swap, exchange_value, dest, compare_value);
-#else
   return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
-#endif // M68K
 #endif // ARM
 }
 
--- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -36,12 +36,18 @@
 
   // Atomically copy 64 bits of data
   static void atomic_copy64(const volatile void *src, volatile void *dst) {
-#if defined(PPC32)
+#if defined(PPC32) && !defined(__SPE__)
     double tmp;
     asm volatile ("lfd  %0, %2\n"
                   "stfd %0, %1\n"
                   : "=&f"(tmp), "=Q"(*(volatile double*)dst)
                   : "Q"(*(volatile double*)src));
+#elif defined(PPC32) && defined(__SPE__)
+    long tmp;
+    asm volatile ("evldd  %0, %2\n"
+                  "evstdd %0, %1\n"
+                  : "=&r"(tmp), "=Q"(*(volatile long*)dst)
+                  : "Q"(*(volatile long*)src));
 #elif defined(S390) && !defined(_LP64)
     double tmp;
     asm volatile ("ld  %0, 0(%1)\n"
--- a/src/hotspot/share/adlc/formssel.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/adlc/formssel.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -4034,6 +4034,7 @@
         strcmp(opType,"ModF")==0 ||
         strcmp(opType,"ModI")==0 ||
         strcmp(opType,"SqrtD")==0 ||
+        strcmp(opType,"SqrtF")==0 ||
         strcmp(opType,"TanD")==0 ||
         strcmp(opType,"ConvD2F")==0 ||
         strcmp(opType,"ConvD2I")==0 ||
@@ -4167,7 +4168,7 @@
     "DivVF","DivVD",
     "AbsVF","AbsVD",
     "NegVF","NegVD",
-    "SqrtVD",
+    "SqrtVD","SqrtVF",
     "AndV" ,"XorV" ,"OrV",
     "AddReductionVI", "AddReductionVL",
     "AddReductionVF", "AddReductionVD",
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -167,6 +167,7 @@
   verify_flag(_config->_compactFields, CompactFields, "CompactFields");
   verify_flag(_config->_enableContended, EnableContended, "EnableContended");
   verify_flag(_config->_restrictContended, RestrictContended, "RestrictContended");
+  verify_flag(_config->_threadLocalHandshakes, ThreadLocalHandshakes, "ThreadLocalHandshakes");
 
   if (!TieredCompilation && _config->_tieredAOT) {
     handle_config_error("Shared file %s error: Expected to run with tiered compilation on", _name);
--- a/src/hotspot/share/aot/aotCodeHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/aot/aotCodeHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -92,7 +92,7 @@
 } AOTHeader;
 
 typedef struct {
-  enum { CONFIG_SIZE = 7 * jintSize + 11 };
+  enum { CONFIG_SIZE = 7 * jintSize + 12 };
   // 7 int values
   int _config_size;
   int _narrowOopShift;
@@ -101,7 +101,7 @@
   int _fieldsAllocationStyle;
   int _objectAlignment;
   int _codeSegmentSize;
-  // byte[11] array map to boolean values here
+  // byte[12] array map to boolean values here
   bool _debug_VM;
   bool _useCompressedOops;
   bool _useCompressedClassPointers;
@@ -113,6 +113,7 @@
   bool _enableContended;
   bool _restrictContended;
   bool _omitAssertions;
+  bool _threadLocalHandshakes;
 } AOTConfiguration;
 
 class AOTLib : public CHeapObj<mtCode> {
--- a/src/hotspot/share/aot/aotLoader.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/aot/aotLoader.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -146,15 +146,6 @@
       return;
     }
 
-    const char* home = Arguments::get_java_home();
-    const char* file_separator = os::file_separator();
-
-    for (int i = 0; i < (int) (sizeof(modules) / sizeof(const char*)); i++) {
-      char library[JVM_MAXPATHLEN];
-      jio_snprintf(library, sizeof(library), "%s%slib%slib%s%s%s%s", home, file_separator, file_separator, modules[i], UseCompressedOops ? "-coop" : "", UseG1GC ? "" : "-nong1", os::dll_file_extension());
-      load_library(library, false);
-    }
-
     // Scan the AOTLibrary option.
     if (AOTLibrary != NULL) {
       const int len = (int)strlen(AOTLibrary);
@@ -172,6 +163,16 @@
         }
       }
     }
+
+    // Load well-know AOT libraries from Java installation directory.
+    const char* home = Arguments::get_java_home();
+    const char* file_separator = os::file_separator();
+
+    for (int i = 0; i < (int) (sizeof(modules) / sizeof(const char*)); i++) {
+      char library[JVM_MAXPATHLEN];
+      jio_snprintf(library, sizeof(library), "%s%slib%slib%s%s%s%s", home, file_separator, file_separator, modules[i], UseCompressedOops ? "-coop" : "", UseG1GC ? "" : "-nong1", os::dll_file_extension());
+      load_library(library, false);
+    }
   }
 }
 
@@ -239,6 +240,21 @@
 }
 
 void AOTLoader::load_library(const char* name, bool exit_on_error) {
+  // Skip library if a library with the same name is already loaded.
+  const int file_separator = *os::file_separator();
+  const char* start = strrchr(name, file_separator);
+  const char* new_name = (start == NULL) ? name : (start + 1);
+  FOR_ALL_AOT_LIBRARIES(lib) {
+    const char* lib_name = (*lib)->name();
+    start = strrchr(lib_name, file_separator);
+    const char* old_name = (start == NULL) ? lib_name : (start + 1);
+    if (strcmp(old_name, new_name) == 0) {
+      if (PrintAOT) {
+        warning("AOT library %s is already loaded as %s.", name, lib_name);
+      }
+      return;
+    }
+  }
   char ebuf[1024];
   void* handle = os::dll_load(name, ebuf, sizeof ebuf);
   if (handle == NULL) {
--- a/src/hotspot/share/c1/c1_LIR.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/c1/c1_LIR.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -196,8 +196,8 @@
   //     data       opr-type opr-kind
   // +--------------+-------+-------+
   // [max...........|7 6 5 4|3 2 1 0]
-  //                             ^
-  //                    is_pointer bit
+  //                               ^
+  //                         is_pointer bit
   //
   // lowest bit cleared, means it is a structure pointer
   // we need  4 bits to represent types
--- a/src/hotspot/share/classfile/classFileParser.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -86,7 +86,7 @@
 
 #define JAVA_CLASSFILE_MAGIC              0xCAFEBABE
 #define JAVA_MIN_SUPPORTED_VERSION        45
-#define JAVA_MAX_SUPPORTED_VERSION        53
+#define JAVA_MAX_SUPPORTED_VERSION        54
 #define JAVA_MAX_SUPPORTED_MINOR_VERSION  0
 
 // Used for two backward compatibility reasons:
@@ -108,6 +108,8 @@
 
 #define JAVA_9_VERSION                    53
 
+#define JAVA_10_VERSION                   54
+
 void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
   assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
          "Unexpected bad constant pool entry");
--- a/src/hotspot/share/classfile/classListParser.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/classListParser.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,13 +23,32 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
+#include "jimage.hpp"
 #include "classfile/classListParser.hpp"
-#include "runtime/os.hpp"
-#include "runtime/java.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/fieldType.hpp"
+#include "runtime/javaCalls.hpp"
+#include "utilities/defaultStream.hpp"
+#include "utilities/hashtable.inline.hpp"
+#include "utilities/macros.hpp"
+
+ClassListParser* ClassListParser::_instance = NULL;
 
 ClassListParser::ClassListParser(const char* file) {
+  assert(_instance == NULL, "must be singleton");
+  _instance = this;
   _classlist_file = file;
   _file = fopen(file, "r");
+  _line_no = 0;
+  _interfaces = new (ResourceObj::C_HEAP, mtClass) GrowableArray<int>(10, true);
+
   if (_file == NULL) {
     char errmsg[JVM_MAXPATHLEN];
     os::lasterror(errmsg, JVM_MAXPATHLEN);
@@ -41,6 +60,7 @@
   if (_file) {
     fclose(_file);
   }
+  _instance = NULL;
 }
 
 bool ClassListParser::parse_one_line() {
@@ -48,10 +68,10 @@
     if (fgets(_line, sizeof(_line), _file) == NULL) {
       return false;
     }
-    int line_len = (int)strlen(_line);
-    if (line_len > _max_allowed_line_len) {
-      tty->print_cr("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
-      vm_exit_during_initialization("Loading classlist failed");
+    ++ _line_no;
+    _line_len = (int)strlen(_line);
+    if (_line_len > _max_allowed_line_len) {
+      error("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
     }
     if (*_line == '#') { // comment
       continue;
@@ -59,8 +79,380 @@
     break;
   }
 
-  // Remove trailing \r\n
-  _line[strcspn(_line, "\r\n")] = 0;
+  _id = _unspecified;
+  _super = _unspecified;
+  _interfaces->clear();
+  _source = NULL;
+  _interfaces_specified = false;
+
+  {
+    int len = (int)strlen(_line);
+    int i;
+    // Replace \t\r\n with ' '
+    for (i=0; i<len; i++) {
+      if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n') {
+        _line[i] = ' ';
+      }
+    }
+
+    // Remove trailing newline/space
+    while (len > 0) {
+      if (_line[len-1] == ' ') {
+        _line[len-1] = '\0';
+        len --;
+      } else {
+        break;
+      }
+    }
+    _line_len = len;
+    _class_name = _line;
+  }
+
+  if ((_token = strchr(_line, ' ')) == NULL) {
+    // No optional arguments are specified.
+    return true;
+  }
+
+  // Mark the end of the name, and go to the next input char
+  *_token++ = '\0';
+
+  while (*_token) {
+    skip_whitespaces();
+
+    if (parse_int_option("id:", &_id)) {
+      continue;
+    } else if (parse_int_option("super:", &_super)) {
+      check_already_loaded("Super class", _super);
+      continue;
+    } else if (skip_token("interfaces:")) {
+      int i;
+      while (try_parse_int(&i)) {
+        check_already_loaded("Interface", i);
+        _interfaces->append(i);
+      }
+    } else if (skip_token("source:")) {
+      skip_whitespaces();
+      _source = _token;
+      char* s = strchr(_token, ' ');
+      if (s == NULL) {
+        break; // end of input line
+      } else {
+        *s = '\0'; // mark the end of _source
+        _token = s+1;
+      }
+    } else {
+      error("Unknown input");
+    }
+  }
+
+  // if src is specified
+  //     id super interfaces must all be specified
+  //     loader may be specified
+  // else
+  //     # the class is loaded from classpath
+  //     id may be specified
+  //     super, interfaces, loader must not be specified
   return true;
 }
 
+void ClassListParser::skip_whitespaces() {
+  while (*_token == ' ' || *_token == '\t') {
+    _token ++;
+  }
+}
+
+void ClassListParser::skip_non_whitespaces() {
+  while (*_token && *_token != ' ' && *_token != '\t') {
+    _token ++;
+  }
+}
+
+void ClassListParser::parse_int(int* value) {
+  skip_whitespaces();
+  if (sscanf(_token, "%i", value) == 1) {
+    skip_non_whitespaces();
+    if (*value < 0) {
+      error("Error: negative integers not allowed (%d)", *value);
+    }
+  } else {
+    error("Error: expected integer");
+  }
+}
+
+bool ClassListParser::try_parse_int(int* value) {
+  skip_whitespaces();
+  if (sscanf(_token, "%i", value) == 1) {
+    skip_non_whitespaces();
+    return true;
+  }
+  return false;
+}
+
+bool ClassListParser::skip_token(const char* option_name) {
+  size_t len = strlen(option_name);
+  if (strncmp(_token, option_name, len) == 0) {
+    _token += len;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool ClassListParser::parse_int_option(const char* option_name, int* value) {
+  if (skip_token(option_name)) {
+    if (*value != _unspecified) {
+      error("%s specified twice", option_name);
+    } else {
+      parse_int(value);
+      return true;
+    }
+  }
+  return false;
+}
+
+void ClassListParser::print_specified_interfaces() {
+  const int n = _interfaces->length();
+  jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
+  for (int i=0; i<n; i++) {
+    InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
+    jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
+  }
+  jio_fprintf(defaultStream::error_stream(), "}\n");
+}
+
+void ClassListParser::print_actual_interfaces(InstanceKlass *ik) {
+  int n = ik->local_interfaces()->length();
+  jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
+  for (int i = 0; i < n; i++) {
+    InstanceKlass* e = InstanceKlass::cast(ik->local_interfaces()->at(i));
+    jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
+  }
+  jio_fprintf(defaultStream::error_stream(), "}\n");
+}
+
+void ClassListParser::error(const char *msg, ...) {
+  va_list ap;
+  va_start(ap, msg);
+  int error_index = _token - _line;
+  if (error_index >= _line_len) {
+    error_index = _line_len - 1;
+  }
+  if (error_index < 0) {
+    error_index = 0;
+  }
+
+  jio_fprintf(defaultStream::error_stream(),
+              "An error has occurred while processing class list file %s %d:%d.\n",
+              _classlist_file, _line_no, (error_index + 1));
+  jio_vfprintf(defaultStream::error_stream(), msg, ap);
+
+  if (_line_len <= 0) {
+    jio_fprintf(defaultStream::error_stream(), "\n");
+  } else {
+    jio_fprintf(defaultStream::error_stream(), ":\n");
+    for (int i=0; i<_line_len; i++) {
+      char c = _line[i];
+      if (c == '\0') {
+        jio_fprintf(defaultStream::error_stream(), "%s", " ");
+      } else {
+        jio_fprintf(defaultStream::error_stream(), "%c", c);
+      }
+    }
+    jio_fprintf(defaultStream::error_stream(), "\n");
+    for (int i=0; i<error_index; i++) {
+      jio_fprintf(defaultStream::error_stream(), "%s", " ");
+    }
+    jio_fprintf(defaultStream::error_stream(), "^\n");
+  }
+
+  vm_exit_during_initialization("class list format error.", NULL);
+  va_end(ap);
+}
+
+// This function is used for loading classes for customized class loaders
+// during archive dumping.
+InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
+#if !(defined(_LP64) && (defined(LINUX)|| defined(SOLARIS) || defined(AIX)))
+  // The only supported platforms are: (1) Linux/64-bit; (2) Solaris/64-bit; (3) AIX/64-bit
+  //
+  // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
+  // method in test/lib/jdk/test/lib/Platform.java.
+  error("AppCDS custom class loaders not supported on this platform");
+#endif
+
+  assert(UseAppCDS, "must be");
+  if (!is_super_specified()) {
+    error("If source location is specified, super class must be also specified");
+  }
+  if (!is_id_specified()) {
+    error("If source location is specified, id must be also specified");
+  }
+  InstanceKlass* k = ClassLoaderExt::load_class(class_name, _source, THREAD);
+
+  if (strncmp(_class_name, "java/", 5) == 0) {
+    log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
+          _class_name, _source);
+    return NULL;
+  }
+
+  if (k != NULL) {
+    if (k->local_interfaces()->length() != _interfaces->length()) {
+      print_specified_interfaces();
+      print_actual_interfaces(k);
+      error("The number of interfaces (%d) specified in class list does not match the class file (%d)",
+            _interfaces->length(), k->local_interfaces()->length());
+    }
+
+    if (!SystemDictionaryShared::add_non_builtin_klass(class_name, ClassLoaderData::the_null_class_loader_data(),
+                                                       k, THREAD)) {
+      error("Duplicated class %s", _class_name);
+    }
+
+    // This tells JVM_FindLoadedClass to not find this class.
+    k->set_shared_classpath_index(UNREGISTERED_INDEX);
+  }
+
+  return k;
+}
+
+InstanceKlass* ClassListParser::load_current_class(TRAPS) {
+  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name, THREAD);
+  guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
+
+  InstanceKlass *klass = NULL;
+  if (!is_loading_from_source()) {
+    if (is_super_specified()) {
+      error("If source location is not specified, super class must not be specified");
+    }
+    if (are_interfaces_specified()) {
+      error("If source location is not specified, interface(s) must not be specified");
+    }
+
+    bool non_array = !FieldType::is_array(class_name_symbol);
+
+    Handle s = java_lang_String::create_from_symbol(class_name_symbol, CHECK_0);
+    // Translate to external class name format, i.e., convert '/' chars to '.'
+    Handle string = java_lang_String::externalize_classname(s, CHECK_0);
+    JavaValue result(T_OBJECT);
+    InstanceKlass* spec_klass =  non_array ?
+      SystemDictionary::ClassLoader_klass() : SystemDictionary::Class_klass();
+    Symbol* method_name = non_array ?
+      vmSymbols::loadClass_name() : vmSymbols::forName_name();
+    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
+
+    if (non_array) {
+      JavaCalls::call_virtual(&result,
+                              loader, //SystemDictionary::java_system_loader(),
+                              spec_klass,
+                              method_name, //vmSymbols::loadClass_name(),
+                              vmSymbols::string_class_signature(),
+                              string,
+                              THREAD);
+    } else {
+      JavaCalls::call_static(&result,
+                             spec_klass,
+                             method_name,
+                             vmSymbols::string_class_signature(),
+                             string,
+                             CHECK_NULL);
+    }
+    assert(result.get_type() == T_OBJECT, "just checking");
+    oop obj = (oop) result.get_jobject();
+    if (!HAS_PENDING_EXCEPTION && (obj != NULL)) {
+      if (non_array) {
+        klass = InstanceKlass::cast(java_lang_Class::as_Klass(obj));
+      } else {
+        klass = static_cast<InstanceKlass*>(java_lang_Class::array_klass_acquire(obj));
+      }
+    } else { // load classes in bootclasspath/a
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+      }
+
+      if (non_array) {
+        Klass* k = SystemDictionary::resolve_or_null(class_name_symbol, CHECK_NULL);
+        if (k != NULL) {
+          klass = InstanceKlass::cast(k);
+        } else {
+          if (!HAS_PENDING_EXCEPTION) {
+            THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
+          }
+        }
+      }
+    }
+  } else {
+    // If "source:" tag is specified, all super class and super interfaces must be specified in the
+    // class list file.
+    if (UseAppCDS) {
+      klass = load_class_from_source(class_name_symbol, CHECK_NULL);
+    }
+  }
+
+  if (klass != NULL && is_id_specified()) {
+    int id = this->id();
+    SystemDictionaryShared::update_shared_entry(klass, id);
+    InstanceKlass* old = table()->lookup(id);
+    if (old != NULL && old != klass) {
+      error("Duplicated ID %d for class %s", id, _class_name);
+    }
+    table()->add(id, klass);
+  }
+
+  return klass;
+}
+
+bool ClassListParser::is_loading_from_source() {
+  return (_source != NULL);
+}
+
+InstanceKlass* ClassListParser::lookup_class_by_id(int id) {
+  InstanceKlass* klass = table()->lookup(id);
+  if (klass == NULL) {
+    error("Class ID %d has not been defined", id);
+  }
+  return klass;
+}
+
+
+InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) {
+  if (!is_loading_from_source()) {
+    return NULL;
+  }
+
+  InstanceKlass* k = lookup_class_by_id(super());
+  if (super_name != k->name()) {
+    error("The specified super class %s (id %d) does not match actual super class %s",
+          k->name()->as_klass_external_name(), super(),
+          super_name->as_klass_external_name());
+  }
+  return k;
+}
+
+InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) {
+  if (!is_loading_from_source()) {
+    return NULL;
+  }
+
+  const int n = _interfaces->length();
+  if (n == 0) {
+    error("Class %s implements the interface %s, but no interface has been specified in the input line",
+          _class_name, interface_name->as_klass_external_name());
+    ShouldNotReachHere();
+  }
+
+  int i;
+  for (i=0; i<n; i++) {
+    InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
+    if (interface_name == k->name()) {
+      return k;
+    }
+  }
+
+  // interface_name is not specified by the "interfaces:" keyword.
+  print_specified_interfaces();
+  error("The interface %s implemented by class %s does not match any of the specified interface IDs",
+        interface_name->as_klass_external_name(), _class_name);
+  ShouldNotReachHere();
+  return NULL;
+}
+
--- a/src/hotspot/share/classfile/classListParser.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/classListParser.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -27,30 +27,122 @@
 
 #include "utilities/exceptions.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/hashtable.hpp"
+
+class CDSClassInfo;
+
+// Look up from ID -> InstanceKlass*
+class ID2KlassTable : public Hashtable<InstanceKlass*, mtClass> {
+public:
+  ID2KlassTable() : Hashtable<InstanceKlass*, mtClass>(1987, sizeof(HashtableEntry<InstanceKlass*, mtClass>)) { }
+  void add(int id, InstanceKlass* klass) {
+    unsigned int hash = (unsigned int)id;
+    HashtableEntry<InstanceKlass*, mtClass>* entry = new_entry(hash, klass);
+    add_entry(hash_to_index(hash), entry);
+  }
+
+  InstanceKlass* lookup(int id) {
+    unsigned int hash = (unsigned int)id;
+    int index = hash_to_index(id);
+    for (HashtableEntry<InstanceKlass*, mtClass>* e = bucket(index); e != NULL; e = e->next()) {
+      if (e->hash() == hash) {
+        return e->literal();
+      }
+    }
+    return NULL;
+  }
+};
 
 class ClassListParser : public StackObj {
   enum {
+    _unspecified      = -999,
+
     // Max number of bytes allowed per line in the classlist.
-    // Theoretically Java class names could be 65535 bytes in length. In reality,
+    // Theoretically Java class names could be 65535 bytes in length. Also, an input line
+    // could have a very long path name up to JVM_MAXPATHLEN bytes in length. In reality,
     // 4K bytes is more than enough.
     _max_allowed_line_len = 4096,
     _line_buf_extra       = 10, // for detecting input too long
     _line_buf_size        = _max_allowed_line_len + _line_buf_extra
   };
 
+  static ClassListParser* _instance; // the singleton.
   const char* _classlist_file;
   FILE* _file;
-  char  _line[_line_buf_size];  // The buffer that holds the current line.
+
+  ID2KlassTable _id2klass_table;
 
+  // The following field contains information from the *current* line being
+  // parsed.
+  char                _line[_line_buf_size];  // The buffer that holds the current line. Some characters in
+                                              // the buffer may be overwritten by '\0' during parsing.
+  int                 _line_len;              // Original length of the input line.
+  int                 _line_no;               // Line number for current line being parsed
+  const char*         _class_name;
+  int                 _id;
+  int                 _super;
+  GrowableArray<int>* _interfaces;
+  bool                _interfaces_specified;
+  const char*         _source;
+
+  bool parse_int_option(const char* option_name, int* value);
+  InstanceKlass* load_class_from_source(Symbol* class_name, TRAPS);
+  ID2KlassTable *table() {
+    return &_id2klass_table;
+  }
+  InstanceKlass* lookup_class_by_id(int id);
+  void print_specified_interfaces();
+  void print_actual_interfaces(InstanceKlass *ik);
 public:
   ClassListParser(const char* file);
   ~ClassListParser();
+
+  static ClassListParser* instance() {
+    return _instance;
+  }
   bool parse_one_line();
+  char* _token;
+  void error(const char* msg, ...);
+  void parse_int(int* value);
+  bool try_parse_int(int* value);
+  bool skip_token(const char* option_name);
+  void skip_whitespaces();
+  void skip_non_whitespaces();
+
+  bool is_id_specified() {
+    return _id != _unspecified;
+  }
+  bool is_super_specified() {
+    return _super != _unspecified;
+  }
+  bool are_interfaces_specified() {
+    return _interfaces->length() > 0;
+  }
+  int id() {
+    assert(is_id_specified(), "do not query unspecified id");
+    return _id;
+  }
+  int super() {
+    assert(is_super_specified(), "do not query unspecified super");
+    return _super;
+  }
+  void check_already_loaded(const char* which, int id) {
+    if (_id2klass_table.lookup(id) == NULL) {
+      error("%s id %d is not yet loaded", which, id);
+    }
+  }
 
   const char* current_class_name() {
-    return _line;
+    return _class_name;
   }
+
+  InstanceKlass* load_current_class(TRAPS);
+
+  bool is_loading_from_source();
+
+  // Look up the super or interface of the current class being loaded
+  // (in this->load_current_class()).
+  InstanceKlass* lookup_super_for_current_class(Symbol* super_name);
+  InstanceKlass* lookup_interface_for_current_class(Symbol* interface_name);
 };
-
-
-#endif // SHARE_VM_MEMORY_CLASSLISTPARSER_HPP
+#endif
--- a/src/hotspot/share/classfile/classLoader.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/classLoader.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #define SHARE_VM_CLASSFILE_CLASSLOADER_HPP
 
 #include "jimage.hpp"
+#include "runtime/handles.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/perfData.hpp"
 #include "utilities/exceptions.hpp"
@@ -42,6 +43,7 @@
 class JImageFile;
 class ClassFileStream;
 class PackageEntry;
+template <typename T> class GrowableArray;
 
 class ClassPathEntry : public CHeapObj<mtClass> {
 private:
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,14 +23,329 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classFileParser.hpp"
+#include "classfile/classFileStream.hpp"
 #include "classfile/classListParser.hpp"
+#include "classfile/classLoader.hpp"
 #include "classfile/classLoaderExt.hpp"
-#include "classfile/symbolTable.hpp"
-#include "classfile/systemDictionary.hpp"
+#include "classfile/classLoaderData.inline.hpp"
+#include "classfile/klassFactory.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/sharedPathsMiscInfo.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/filemap.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/symbol.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/java.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/os.hpp"
+#include "services/threadService.hpp"
+#include "utilities/stringUtils.hpp"
+
+jshort ClassLoaderExt::_app_paths_start_index = ClassLoaderExt::max_classpath_index;
+bool ClassLoaderExt::_has_app_classes = false;
+bool ClassLoaderExt::_has_platform_classes = false;
+
+void ClassLoaderExt::setup_app_search_path() {
+  assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
+  _app_paths_start_index = ClassLoader::num_boot_classpath_entries();
+  char* app_class_path = os::strdup(Arguments::get_appclasspath());
+
+  if (strcmp(app_class_path, ".") == 0) {
+    // This doesn't make any sense, even for AppCDS, so let's skip it. We
+    // don't want to throw an error here because -cp "." is usually assigned
+    // by the launcher when classpath is not specified.
+    trace_class_path("app loader class path (skipped)=", app_class_path);
+  } else {
+    trace_class_path("app loader class path=", app_class_path);
+    shared_paths_misc_info()->add_app_classpath(app_class_path);
+    ClassLoader::setup_app_search_path(app_class_path);
+  }
+}
+
+char* ClassLoaderExt::read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS) {
+  const char* name = "META-INF/MANIFEST.MF";
+  char* manifest;
+  jint size;
+
+  assert(entry->is_jar_file(), "must be");
+  manifest = (char*) ((ClassPathZipEntry*)entry )->open_entry(name, &size, true, CHECK_NULL);
+
+  if (manifest == NULL) { // No Manifest
+    *manifest_size = 0;
+    return NULL;
+  }
 
 
+  if (clean_text) {
+    // See http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest
+    // (1): replace all CR/LF and CR with LF
+    StringUtils::replace_no_expand(manifest, "\r\n", "\n");
+
+    // (2) remove all new-line continuation (remove all "\n " substrings)
+    StringUtils::replace_no_expand(manifest, "\n ", "");
+  }
+
+  *manifest_size = (jint)strlen(manifest);
+  return manifest;
+}
+
+char* ClassLoaderExt::get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size) {
+  const char* tag = "Class-Path: ";
+  const int tag_len = (int)strlen(tag);
+  char* found = NULL;
+  char* line_start = manifest;
+  char* end = manifest + manifest_size;
+
+  assert(*end == 0, "must be nul-terminated");
+
+  while (line_start < end) {
+    char* line_end = strchr(line_start, '\n');
+    if (line_end == NULL) {
+      // JAR spec require the manifest file to be terminated by a new line.
+      break;
+    }
+    if (strncmp(tag, line_start, tag_len) == 0) {
+      if (found != NULL) {
+        // Same behavior as jdk/src/share/classes/java/util/jar/Attributes.java
+        // If duplicated entries are found, the last one is used.
+        tty->print_cr("Warning: Duplicate name in Manifest: %s.\n"
+                      "Ensure that the manifest does not have duplicate entries, and\n"
+                      "that blank lines separate individual sections in both your\n"
+                      "manifest and in the META-INF/MANIFEST.MF entry in the jar file:\n%s\n", tag, jar_path);
+      }
+      found = line_start + tag_len;
+      assert(found <= line_end, "sanity");
+      *line_end = '\0';
+    }
+    line_start = line_end + 1;
+  }
+  return found;
+}
+
+void ClassLoaderExt::process_jar_manifest(ClassPathEntry* entry,
+                                          bool check_for_duplicates) {
+  Thread* THREAD = Thread::current();
+  ResourceMark rm(THREAD);
+  jint manifest_size;
+  char* manifest = read_manifest(entry, &manifest_size, CHECK);
+
+  if (manifest == NULL) {
+    return;
+  }
+
+  if (strstr(manifest, "Extension-List:") != NULL) {
+    tty->print_cr("-Xshare:dump does not support Extension-List in JAR manifest: %s", entry->name());
+    vm_exit(1);
+  }
+
+  char* cp_attr = get_class_path_attr(entry->name(), manifest, manifest_size);
+
+  if (cp_attr != NULL && strlen(cp_attr) > 0) {
+    trace_class_path("found Class-Path: ", cp_attr);
+
+    char sep = os::file_separator()[0];
+    const char* dir_name = entry->name();
+    const char* dir_tail = strrchr(dir_name, sep);
+    int dir_len;
+    if (dir_tail == NULL) {
+      dir_len = 0;
+    } else {
+      dir_len = dir_tail - dir_name + 1;
+    }
+
+    // Split the cp_attr by spaces, and add each file
+    char* file_start = cp_attr;
+    char* end = file_start + strlen(file_start);
+
+    while (file_start < end) {
+      char* file_end = strchr(file_start, ' ');
+      if (file_end != NULL) {
+        *file_end = 0;
+        file_end += 1;
+      } else {
+        file_end = end;
+      }
+
+      int name_len = (int)strlen(file_start);
+      if (name_len > 0) {
+        ResourceMark rm(THREAD);
+        char* libname = NEW_RESOURCE_ARRAY(char, dir_len + name_len + 1);
+        *libname = 0;
+        strncat(libname, dir_name, dir_len);
+        strncat(libname, file_start, name_len);
+        trace_class_path("library = ", libname);
+        ClassLoader::update_class_path_entry_list(libname, true, false);
+      }
+
+      file_start = file_end;
+    }
+  }
+}
+
+void ClassLoaderExt::setup_search_paths() {
+  if (UseAppCDS) {
+    shared_paths_misc_info()->record_app_offset();
+    ClassLoaderExt::setup_app_search_path();
+  }
+}
+
+Thread* ClassLoaderExt::Context::_dump_thread = NULL;
+
+bool ClassLoaderExt::check(ClassLoaderExt::Context *context,
+                           const ClassFileStream* stream,
+                           const int classpath_index) {
+  if (stream != NULL) {
+    // Ignore any App classes from signed JAR file during CDS archiving
+    // dumping
+    if (DumpSharedSpaces &&
+        SharedClassUtil::is_classpath_entry_signed(classpath_index) &&
+        classpath_index >= _app_paths_start_index) {
+      tty->print_cr("Preload Warning: Skipping %s from signed JAR",
+                    context->class_name());
+      return false;
+    }
+    if (classpath_index >= _app_paths_start_index) {
+      _has_app_classes = true;
+      _has_platform_classes = true;
+    }
+  }
+
+  return true;
+}
+
+void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
+                                   Symbol* class_name,
+                                   const s2 classpath_index,
+                                   InstanceKlass* result,
+                                   TRAPS) {
+  assert(DumpSharedSpaces, "Sanity");
+
+  // We need to remember where the class comes from during dumping.
+  oop loader = result->class_loader();
+  s2 classloader_type = ClassLoader::BOOT_LOADER;
+  if (SystemDictionary::is_system_class_loader(loader)) {
+    classloader_type = ClassLoader::APP_LOADER;
+    ClassLoaderExt::set_has_app_classes();
+  } else if (SystemDictionary::is_platform_class_loader(loader)) {
+    classloader_type = ClassLoader::PLATFORM_LOADER;
+    ClassLoaderExt::set_has_platform_classes();
+  }
+  result->set_shared_classpath_index(classpath_index);
+  result->set_class_loader_type(classloader_type);
+}
+
+void ClassLoaderExt::finalize_shared_paths_misc_info() {
+  if (UseAppCDS) {
+    if (!_has_app_classes) {
+      shared_paths_misc_info()->pop_app();
+    }
+  }
+}
+
+// Load the class of the given name from the location given by path. The path is specified by
+// the "source:" in the class list file (see classListParser.cpp), and can be a directory or
+// a JAR file.
+InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS) {
+
+  assert(name != NULL, "invariant");
+  assert(DumpSharedSpaces && UseAppCDS, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
+  ResourceMark rm(THREAD);
+  const char* class_name = name->as_C_string();
+
+  const char* file_name = file_name_for_class_name(class_name,
+                                                   name->utf8_length());
+  assert(file_name != NULL, "invariant");
+
+  // Lookup stream for parsing .class file
+  ClassFileStream* stream = NULL;
+  ClassPathEntry* e = find_classpath_entry_from_cache(path, CHECK_NULL);
+  if (e == NULL) {
+    return NULL;
+  }
+  {
+    PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
+                               ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
+                               PerfClassTraceTime::CLASS_LOAD);
+    stream = e->open_stream(file_name, CHECK_NULL);
+  }
+
+  if (NULL == stream) {
+    tty->print_cr("Preload Warning: Cannot find %s", class_name);
+    return NULL;
+  }
+
+  assert(stream != NULL, "invariant");
+  stream->set_verify(true);
+
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  Handle protection_domain;
+
+  InstanceKlass* result = KlassFactory::create_from_stream(stream,
+                                                           name,
+                                                           loader_data,
+                                                           protection_domain,
+                                                           NULL, // host_klass
+                                                           NULL, // cp_patches
+                                                           THREAD);
+
+  if (HAS_PENDING_EXCEPTION) {
+    tty->print_cr("Preload Error: Failed to load %s", class_name);
+    return NULL;
+  }
+  result->set_shared_classpath_index(UNREGISTERED_INDEX);
+  SystemDictionaryShared::set_shared_class_misc_info(result, stream);
+  return result;
+}
+
+struct CachedClassPathEntry {
+  const char* _path;
+  ClassPathEntry* _entry;
+};
+
+static GrowableArray<CachedClassPathEntry>* cached_path_entries = NULL;
+
+ClassPathEntry* ClassLoaderExt::find_classpath_entry_from_cache(const char* path, TRAPS) {
+  // This is called from dump time so it's single threaded and there's no need for a lock.
+  assert(DumpSharedSpaces && UseAppCDS, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
+  if (cached_path_entries == NULL) {
+    cached_path_entries = new (ResourceObj::C_HEAP, mtClass) GrowableArray<CachedClassPathEntry>(20, /*c heap*/ true);
+  }
+  CachedClassPathEntry ccpe;
+  for (int i=0; i<cached_path_entries->length(); i++) {
+    ccpe = cached_path_entries->at(i);
+    if (strcmp(ccpe._path, path) == 0) {
+      if (i != 0) {
+        // Put recent entries at the beginning to speed up searches.
+        cached_path_entries->remove_at(i);
+        cached_path_entries->insert_before(0, ccpe);
+      }
+      return ccpe._entry;
+    }
+  }
+
+  struct stat st;
+  if (os::stat(path, &st) != 0) {
+    // File or directory not found
+    return NULL;
+  }
+  ClassPathEntry* new_entry = NULL;
+
+  new_entry = create_class_path_entry(path, &st, false, false, CHECK_NULL);
+  if (new_entry == NULL) {
+    return NULL;
+  }
+  ccpe._path = strdup(path);
+  ccpe._entry = new_entry;
+  cached_path_entries->insert_before(0, ccpe);
+  return new_entry;
+}
+
 Klass* ClassLoaderExt::load_one_class(ClassListParser* parser, TRAPS) {
-  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(parser->current_class_name(), THREAD);
-  guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
-  return SystemDictionary::resolve_or_null(class_name_symbol, THREAD);
+  return parser->load_current_class(THREAD);
 }
--- a/src/hotspot/share/classfile/classLoaderExt.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,65 +26,152 @@
 #define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
 
 #include "classfile/classLoader.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "oops/instanceKlass.hpp"
-#include "runtime/handles.hpp"
+#include "utilities/macros.hpp"
 
-class ClassListParser;
+CDS_ONLY(class SharedPathsMiscInfoExt;)
+CDS_ONLY(class ClassListParser;)
 
 class ClassLoaderExt: public ClassLoader { // AllStatic
 public:
-
+  enum SomeConstants {
+    max_classpath_index = 0x7fff
+  };
+  // ClassLoaderExt::Context --
+  //
+  // This is used by DumpSharedSpaces only - it enforces the same classloader
+  // delegation model as would be in run-time. I.e.,
+  // + classes defined by the NULL class loader cannot load classes in the PLATFORM or APP paths.
+  // + classes defined by the PLATFORM class loader cannot load classes in the APP paths.
   class Context {
+    static Thread* _dump_thread;
+    const char* _class_name;
     const char* _file_name;
   public:
+    const char* class_name() {
+      return _class_name;
+    }
+    const char* file_name() {
+      return _file_name;
+    }
+
     Context(const char* class_name, const char* file_name, TRAPS) {
+      _class_name = class_name;
       _file_name = file_name;
+#if INCLUDE_CDS
+      if (!DumpSharedSpaces && !UseSharedSpaces) {
+        // Must not modify _app_paths_start_index if we're not using CDS.
+        assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
+      }
+#endif
     }
 
     bool check(const ClassFileStream* stream, const int classpath_index) {
-      return true;
+      CDS_ONLY(return ClassLoaderExt::check(this, stream, classpath_index);)
+      NOT_CDS(return true;)
     }
 
     bool should_verify(int classpath_index) {
-      return false;
+      CDS_ONLY(return (classpath_index >= _app_paths_start_index);)
+      NOT_CDS(return false;)
     }
 
     void record_result(Symbol* class_name,
                        const s2 classpath_index,
-                       InstanceKlass* result, TRAPS) {
+                       InstanceKlass* result,
+                       TRAPS) {
 #if INCLUDE_CDS
-      assert(DumpSharedSpaces, "Sanity");
-      oop loader = result->class_loader();
-      s2 classloader_type = ClassLoader::BOOT_LOADER;
-      if (SystemDictionary::is_system_class_loader(loader)) {
-        classloader_type = ClassLoader::APP_LOADER;
-        ClassLoaderExt::set_has_app_classes();
-      } else if (SystemDictionary::is_platform_class_loader(loader)) {
-        classloader_type = ClassLoader::PLATFORM_LOADER;
-        ClassLoaderExt::set_has_platform_classes();
+      ClassLoaderExt::record_result(this, class_name, classpath_index, result, THREAD);
+#endif
+    }
+
+    ~Context() {
+#if INCLUDE_CDS
+      if (!DumpSharedSpaces && !UseSharedSpaces) {
+        // Must not modify app_paths_start_index if we're not using CDS.
+        assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
       }
-      result->set_shared_classpath_index(classpath_index);
-      result->set_class_loader_type(classloader_type);
 #endif
     }
-  };
+  }; // end ClassLoaderExt::Context
 
+private:
+#if INCLUDE_CDS
+  static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
+  static void setup_app_search_path(); // Only when -Xshare:dump
+  static SharedPathsMiscInfoExt* shared_paths_misc_info() {
+    return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
+  }
+  static jshort _app_paths_start_index; // index of first app JAR in shared classpath entry table
+  static bool _has_app_classes;
+  static bool _has_platform_classes;
+#endif
+
+public:
+  CDS_ONLY(static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates);)
+
+  // Called by JVMTI code to add boot classpath
   static void append_boot_classpath(ClassPathEntry* new_entry) {
+#if INCLUDE_CDS
+    if (UseAppCDS) {
+      warning("UseAppCDS is disabled because bootstrap classpath has been appended");
+      UseAppCDS = false;
+    }
+#endif
     ClassLoader::add_to_boot_append_entries(new_entry);
   }
-  static void setup_search_paths() {}
-  static bool is_boot_classpath(int classpath_index) {
-   return true;
- }
-  static Klass* load_one_class(ClassListParser* parser, TRAPS);
+
+  static void setup_search_paths() NOT_CDS_RETURN;
+
 #if INCLUDE_CDS
-  static void set_has_app_classes() {}
-  static void set_has_platform_classes() {}
+private:
+  static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS);
+  static ClassPathEntry* find_classpath_entry_from_cache(const char* path, TRAPS);
+
+public:
   static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
-    return NULL;
+    // Remove all the new-line continuations (which wrap long lines at 72 characters, see
+    // http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest), so
+    // that the manifest is easier to parse.
+    return read_manifest(entry, manifest_size, true, THREAD);
+  }
+  static char* read_raw_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
+    // Do not remove new-line continuations, so we can easily pass it as an argument to
+    // java.util.jar.Manifest.getManifest() at run-time.
+    return read_manifest(entry, manifest_size, false, THREAD);
+  }
+
+  static void finalize_shared_paths_misc_info();
+
+  static jshort app_paths_start_index() { return _app_paths_start_index; }
+
+  static void init_paths_start_index(jshort app_start) {
+    _app_paths_start_index = app_start;
+  }
+
+  static bool is_boot_classpath(int classpath_index) {
+    return classpath_index < _app_paths_start_index;
   }
-  static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates) {}
+
+  static bool has_platform_or_app_classes() {
+    return _has_app_classes || _has_platform_classes;
+  }
+
+  static bool check(class ClassLoaderExt::Context *context,
+                    const ClassFileStream* stream,
+                    const int classpath_index);
+
+  static void record_result(class ClassLoaderExt::Context *context,
+                            Symbol* class_name,
+                            const s2 classpath_index,
+                            InstanceKlass* result, TRAPS);
+  static InstanceKlass* load_class(Symbol* h_name, const char* path, TRAPS);
+  static Klass* load_one_class(ClassListParser* parser, TRAPS);
+  static void set_has_app_classes() {
+    _has_app_classes = true;
+  }
+  static void set_has_platform_classes() {
+    _has_platform_classes = true;
+  }
 #endif
 };
 
--- a/src/hotspot/share/classfile/klassFactory.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/klassFactory.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
 #define SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
 
 class ClassFileStream;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/classfile/sharedClassUtil.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/classLoader.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/dictionary.hpp"
+#include "classfile/javaClasses.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "memory/filemap.hpp"
+#include "memory/metadataFactory.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/java.hpp"
+#include "runtime/os.hpp"
+
+class ManifestStream: public ResourceObj {
+  private:
+  u1*   _buffer_start; // Buffer bottom
+  u1*   _buffer_end;   // Buffer top (one past last element)
+  u1*   _current;      // Current buffer position
+
+ public:
+  // Constructor
+  ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
+                                           _current(buffer) {
+    _buffer_end = buffer + length;
+  }
+
+  static bool is_attr(u1* attr, const char* name) {
+    return strncmp((const char*)attr, name, strlen(name)) == 0;
+  }
+
+  static char* copy_attr(u1* value, size_t len) {
+    char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+    strncpy(buf, (char*)value, len);
+    buf[len] = 0;
+    return buf;
+  }
+
+  // The return value indicates if the JAR is signed or not
+  bool check_is_signed() {
+    u1* attr = _current;
+    bool isSigned = false;
+    while (_current < _buffer_end) {
+      if (*_current == '\n') {
+        *_current = '\0';
+        u1* value = (u1*)strchr((char*)attr, ':');
+        if (value != NULL) {
+          assert(*(value+1) == ' ', "Unrecognized format" );
+          if (strstr((char*)attr, "-Digest") != NULL) {
+            isSigned = true;
+            break;
+          }
+        }
+        *_current = '\n'; // restore
+        attr = _current + 1;
+      }
+      _current ++;
+    }
+    return isSigned;
+  }
+};
+
+void SharedPathsMiscInfoExt::print_path(outputStream* out, int type, const char* path) {
+  switch(type) {
+  case APP:
+    ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
+    break;
+  default:
+    SharedPathsMiscInfo::print_path(out, type, path);
+  }
+}
+
+bool SharedPathsMiscInfoExt::check(jint type, const char* path) {
+
+  switch (type) {
+  case APP:
+    {
+      // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
+      size_t len = strlen(path);
+      const char *appcp = Arguments::get_appclasspath();
+      assert(appcp != NULL, "NULL app classpath");
+      size_t appcp_len = strlen(appcp);
+      if (appcp_len < len) {
+        return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
+      }
+      ResourceMark rm;
+      char* tmp_path;
+      if (len == appcp_len) {
+        tmp_path = (char*)appcp;
+      } else {
+        tmp_path = NEW_RESOURCE_ARRAY(char, len + 1);
+        strncpy(tmp_path, appcp, len);
+        tmp_path[len] = 0;
+      }
+      if (os::file_name_strcmp(path, tmp_path) != 0) {
+        return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
+      }
+      if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
+        return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
+      }
+    }
+    break;
+  default:
+    return SharedPathsMiscInfo::check(type, path);
+  }
+
+  return true;
+}
+
+void SharedClassUtil::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* e, TRAPS) {
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)e;
+  ResourceMark rm(THREAD);
+  jint manifest_size;
+  bool isSigned;
+
+  if (cpe->is_jar_file()) {
+    char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
+    if (manifest != NULL) {
+      ManifestStream* stream = new ManifestStream((u1*)manifest,
+                                                  manifest_size);
+      isSigned = stream->check_is_signed();
+      if (isSigned) {
+        ent->_is_signed = true;
+      } else {
+        // Copy the manifest into the shared archive
+        manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
+        Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+                                                        manifest_size,
+                                                        THREAD);
+        char* p = (char*)(buf->data());
+        memcpy(p, manifest, manifest_size);
+        ent->set_manifest(buf);
+        ent->_is_signed = false;
+      }
+    }
+  }
+}
+
+void SharedClassUtil::initialize(TRAPS) {
+  if (UseSharedSpaces) {
+    int size = FileMapInfo::get_number_of_share_classpaths();
+    if (size > 0) {
+      SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
+      if (!DumpSharedSpaces) {
+        FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
+        ClassLoaderExt::init_paths_start_index(header->_app_paths_start_index);
+      }
+    }
+  }
+
+  if (DumpSharedSpaces) {
+    if (SharedArchiveConfigFile) {
+      read_extra_data(SharedArchiveConfigFile, THREAD);
+    }
+  }
+}
+
+void SharedClassUtil::read_extra_data(const char* filename, TRAPS) {
+  HashtableTextDump reader(filename);
+  reader.check_version("VERSION: 1.0");
+
+  while (reader.remain() > 0) {
+    int utf8_length;
+    int prefix_type = reader.scan_prefix(&utf8_length);
+    ResourceMark rm(THREAD);
+    char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
+    reader.get_utf8(utf8_buffer, utf8_length);
+
+    if (prefix_type == HashtableTextDump::SymbolPrefix) {
+      SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
+    } else{
+      assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
+      utf8_buffer[utf8_length] = '\0';
+      oop s = StringTable::intern(utf8_buffer, THREAD);
+    }
+  }
+}
+
+bool SharedClassUtil::is_classpath_entry_signed(int classpath_index) {
+  assert(classpath_index >= 0, "Sanity");
+  SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)
+    FileMapInfo::shared_classpath(classpath_index);
+  return ent->_is_signed;
+}
+
+void FileMapHeaderExt::populate(FileMapInfo* mapinfo, size_t alignment) {
+  FileMapInfo::FileMapHeader::populate(mapinfo, alignment);
+
+  ClassLoaderExt::finalize_shared_paths_misc_info();
+  _app_paths_start_index = ClassLoaderExt::app_paths_start_index();
+
+  _verify_local = BytecodeVerificationLocal;
+  _verify_remote = BytecodeVerificationRemote;
+  _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
+}
+
+bool FileMapHeaderExt::validate() {
+  if (UseAppCDS) {
+    const char* prop = Arguments::get_property("java.system.class.loader");
+    if (prop != NULL) {
+      warning("UseAppCDS is disabled because the java.system.class.loader property is specified (value = \"%s\"). "
+              "To enable UseAppCDS, this property must be not be set", prop);
+      UseAppCDS = false;
+    }
+  }
+
+  if (!FileMapInfo::FileMapHeader::validate()) {
+    return false;
+  }
+
+  // For backwards compatibility, we don't check the verification setting
+  // if the archive only contains system classes.
+  if (_has_platform_or_app_classes &&
+      ((!_verify_local && BytecodeVerificationLocal) ||
+       (!_verify_remote && BytecodeVerificationRemote))) {
+    FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
+                  "verification setting than the current setting.");
+    return false;
+  }
+
+  return true;
+}
--- a/src/hotspot/share/classfile/sharedClassUtil.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/sharedClassUtil.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,37 +27,108 @@
 
 #include "classfile/sharedPathsMiscInfo.hpp"
 #include "memory/filemap.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/dictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "oops/klass.hpp"
+
+class FileMapHeaderExt: public FileMapInfo::FileMapHeader {
+public:
+  jshort _app_paths_start_index;    // Index of first app classpath entry
+  bool   _verify_local;             // BytecodeVerificationLocal setting
+  bool   _verify_remote;            // BytecodeVerificationRemote setting
+  bool   _has_platform_or_app_classes;          // Archive contains app classes
+
+  FileMapHeaderExt() {
+    _has_platform_or_app_classes = true;
+  }
+  virtual void populate(FileMapInfo* mapinfo, size_t alignment);
+  virtual bool validate();
+};
+
+// In addition to SharedPathsMiscInfo, the following information is also stored
+//
+//
+// + The value of Arguments::get_appclasspath() used during dumping.
+//
+class SharedPathsMiscInfoExt : public SharedPathsMiscInfo {
+private:
+  int   _app_offset;
+public:
+  enum {
+    APP       = 5
+  };
+
+  virtual const char* type_name(int type) {
+    switch (type) {
+    case APP:     return "APP";
+    default:      return SharedPathsMiscInfo::type_name(type);
+    }
+  }
+
+  virtual void print_path(outputStream* out, int type, const char* path);
+
+  SharedPathsMiscInfoExt() : SharedPathsMiscInfo() {
+    _app_offset = 0;
+  }
+  SharedPathsMiscInfoExt(char* buf, int size) : SharedPathsMiscInfo(buf, size) {
+    _app_offset = 0;
+  }
+
+  virtual bool check(jint type, const char* path);
+
+  void add_app_classpath(const char* path) {
+    add_path(path, APP);
+  }
+
+  void record_app_offset() {
+    _app_offset = get_used_bytes();
+  }
+  void pop_app() {
+    _cur_ptr = _buf_start + _app_offset;
+    write_jint(0);
+  }
+};
+
+class SharedClassPathEntryExt: public SharedClassPathEntry {
+public:
+  //Maniest attributes
+  bool _is_signed;
+  void set_manifest(Array<u1>* manifest) {
+    _manifest = manifest;
+  }
+};
 
 class SharedClassUtil : AllStatic {
 public:
-
   static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
-    return new SharedPathsMiscInfo();
+    return new SharedPathsMiscInfoExt();
   }
 
   static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
-    return new SharedPathsMiscInfo(buf, size);
+    return new SharedPathsMiscInfoExt(buf, size);
   }
 
   static FileMapInfo::FileMapHeader* allocate_file_map_header() {
-    return new FileMapInfo::FileMapHeader();
+    return new FileMapHeaderExt();
   }
 
   static size_t file_map_header_size() {
-    return sizeof(FileMapInfo::FileMapHeader);
+    return sizeof(FileMapHeaderExt);
   }
 
   static size_t shared_class_path_entry_size() {
-    return sizeof(SharedClassPathEntry);
+    return sizeof(SharedClassPathEntryExt);
   }
 
-  static void update_shared_classpath(ClassPathEntry *cpe,
-                                      SharedClassPathEntry* ent, TRAPS) {}
-  static void initialize(TRAPS) {}
+  static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
+  static void initialize(TRAPS);
 
-  inline static bool is_shared_boot_class(Klass* klass) {
-    return (klass->_shared_class_path_index >= 0);
-  }
+private:
+  static void read_extra_data(const char* filename, TRAPS);
+
+public:
+  static bool is_classpath_entry_signed(int classpath_index);
 };
 
 #endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,18 @@
 #include "runtime/arguments.hpp"
 #include "utilities/ostream.hpp"
 
+SharedPathsMiscInfo::SharedPathsMiscInfo() {
+  _buf_size = INITIAL_BUF_SIZE;
+  _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
+  _allocated = true;
+}
+
+SharedPathsMiscInfo::~SharedPathsMiscInfo() {
+  if (_allocated) {
+    FREE_C_HEAP_ARRAY(char, _buf_start);
+  }
+}
+
 void SharedPathsMiscInfo::add_path(const char* path, int type) {
   log_info(class, path)("type=%s ", type_name(type));
   ClassLoader::trace_class_path("add misc shared path ", path);
@@ -127,7 +139,8 @@
 bool SharedPathsMiscInfo::check(jint type, const char* path) {
   switch (type) {
   case BOOT:
-    if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
+    // In the future we should perform the check based on the content of the mapped archive.
+    if (UseAppCDS && os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
       return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
     }
     break;
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -74,11 +74,7 @@
     INITIAL_BUF_SIZE = 128
   };
   // This constructor is used when creating the misc information (during dump)
-  SharedPathsMiscInfo() {
-    _buf_size = INITIAL_BUF_SIZE;
-    _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
-    _allocated = true;
-  }
+  SharedPathsMiscInfo();
   // This constructor is used when validating the misc info (during run time)
   SharedPathsMiscInfo(char *buff, int size) {
     _cur_ptr = _buf_start = buff;
@@ -86,11 +82,8 @@
     _buf_size = size;
     _allocated = false;
   }
-  ~SharedPathsMiscInfo() {
-    if (_allocated) {
-      FREE_C_HEAP_ARRAY(char, _buf_start);
-    }
-  }
+  ~SharedPathsMiscInfo();
+
   int get_used_bytes() {
     return _cur_ptr - _buf_start;
   }
--- a/src/hotspot/share/classfile/stringTable.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/stringTable.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_CLASSFILE_STRINGTABLE_HPP
 #define SHARE_VM_CLASSFILE_STRINGTABLE_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "utilities/hashtable.hpp"
 
 template <class T, class N> class CompactHashtable;
--- a/src/hotspot/share/classfile/symbolTable.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/symbolTable.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "oops/symbol.hpp"
 #include "utilities/hashtable.hpp"
 
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1087,7 +1087,7 @@
 #if INCLUDE_CDS
   ResourceMark rm(THREAD);
   if (DumpSharedSpaces && !class_loader.is_null() &&
-      !ArgumentsExt::using_AppCDS() && strcmp(class_name->as_C_string(), "Unnamed") != 0) {
+      !UseAppCDS && strcmp(class_name->as_C_string(), "Unnamed") != 0) {
     // If AppCDS is not enabled, don't define the class at dump time (except for the "Unnamed"
     // class, which is used by MethodHandles).
     THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/classFileStream.hpp"
+#include "classfile/classListParser.hpp"
+#include "classfile/classLoader.hpp"
+#include "classfile/classLoaderData.inline.hpp"
+#include "classfile/classLoaderExt.hpp"
+#include "classfile/compactHashtable.inline.hpp"
+#include "classfile/dictionary.hpp"
+#include "classfile/javaClasses.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
+#include "classfile/verificationType.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.hpp"
+#include "memory/filemap.hpp"
+#include "memory/metadataFactory.hpp"
+#include "memory/metaspaceClosure.hpp"
+#include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/klass.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/java.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "utilities/hashtable.inline.hpp"
+#include "utilities/stringUtils.hpp"
+
+
+objArrayOop SystemDictionaryShared::_shared_protection_domains  =  NULL;
+objArrayOop SystemDictionaryShared::_shared_jar_urls            =  NULL;
+objArrayOop SystemDictionaryShared::_shared_jar_manifests       =  NULL;
+
+static Mutex* SharedDictionary_lock = NULL;
+
+void SystemDictionaryShared::initialize(TRAPS) {
+  if (_java_system_loader != NULL) {
+    SharedDictionary_lock = new Mutex(Mutex::leaf, "SharedDictionary_lock", true);
+
+    // These classes need to be initialized before calling get_shared_jar_manifest(), etc.
+    SystemDictionary::ByteArrayInputStream_klass()->initialize(CHECK);
+    SystemDictionary::File_klass()->initialize(CHECK);
+    SystemDictionary::Jar_Manifest_klass()->initialize(CHECK);
+    SystemDictionary::CodeSource_klass()->initialize(CHECK);
+  }
+}
+
+oop SystemDictionaryShared::shared_protection_domain(int index) {
+  return _shared_protection_domains->obj_at(index);
+}
+
+oop SystemDictionaryShared::shared_jar_url(int index) {
+  return _shared_jar_urls->obj_at(index);
+}
+
+oop SystemDictionaryShared::shared_jar_manifest(int index) {
+  return _shared_jar_manifests->obj_at(index);
+}
+
+
+Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TRAPS) {
+  Handle empty;
+  Handle manifest ;
+  if (shared_jar_manifest(shared_path_index) == NULL) {
+    SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_classpath(shared_path_index);
+    long size = ent->manifest_size();
+    if (size <= 0) {
+      return empty; // No manifest - return NULL handle
+    }
+
+    // ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+    InstanceKlass* bais_klass = SystemDictionary::ByteArrayInputStream_klass();
+    Handle bais = bais_klass->allocate_instance_handle(CHECK_(empty));
+    {
+      const char* src = ent->manifest();
+      assert(src != NULL, "No Manifest data");
+      typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_(empty));
+      typeArrayHandle bufhandle(THREAD, buf);
+      char* dst = (char*)(buf->byte_at_addr(0));
+      memcpy(dst, src, (size_t)size);
+
+      JavaValue result(T_VOID);
+      JavaCalls::call_special(&result, bais, bais_klass,
+                              vmSymbols::object_initializer_name(),
+                              vmSymbols::byte_array_void_signature(),
+                              bufhandle, CHECK_(empty));
+    }
+
+    // manifest = new Manifest(bais)
+    InstanceKlass* manifest_klass = SystemDictionary::Jar_Manifest_klass();
+    manifest = manifest_klass->allocate_instance_handle(CHECK_(empty));
+    {
+      JavaValue result(T_VOID);
+      JavaCalls::call_special(&result, manifest, manifest_klass,
+                              vmSymbols::object_initializer_name(),
+                              vmSymbols::input_stream_void_signature(),
+                              bais, CHECK_(empty));
+    }
+    atomic_set_shared_jar_manifest(shared_path_index, manifest());
+  }
+
+  manifest = Handle(THREAD, shared_jar_manifest(shared_path_index));
+  assert(manifest.not_null(), "sanity");
+  return manifest;
+}
+
+Handle SystemDictionaryShared::get_shared_jar_url(int shared_path_index, TRAPS) {
+  Handle url_h;
+  if (shared_jar_url(shared_path_index) == NULL) {
+    JavaValue result(T_OBJECT);
+    const char* path = FileMapInfo::shared_classpath_name(shared_path_index);
+    Handle path_string = java_lang_String::create_from_str(path, CHECK_(url_h));
+    Klass* classLoaders_klass =
+        SystemDictionary::jdk_internal_loader_ClassLoaders_klass();
+        JavaCalls::call_static(&result, classLoaders_klass,
+                               vmSymbols::toFileURL_name(),
+                               vmSymbols::toFileURL_signature(),
+                               path_string, CHECK_(url_h));
+
+    atomic_set_shared_jar_url(shared_path_index, (oop)result.get_jobject());
+  }
+
+  url_h = Handle(THREAD, shared_jar_url(shared_path_index));
+  assert(url_h.not_null(), "sanity");
+  return url_h;
+}
+
+Handle SystemDictionaryShared::get_package_name(Symbol* class_name, TRAPS) {
+  ResourceMark rm(THREAD);
+  Handle pkgname_string;
+  char* pkgname = (char*) ClassLoader::package_from_name((const char*) class_name->as_C_string());
+  if (pkgname != NULL) { // Package prefix found
+    StringUtils::replace_no_expand(pkgname, "/", ".");
+    pkgname_string = java_lang_String::create_from_str(pkgname,
+                                                       CHECK_(pkgname_string));
+  }
+  return pkgname_string;
+}
+
+// Define Package for shared app classes from JAR file and also checks for
+// package sealing (all done in Java code)
+// See http://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html
+void SystemDictionaryShared::define_shared_package(Symbol*  class_name,
+                                                   Handle class_loader,
+                                                   Handle manifest,
+                                                   Handle url,
+                                                   TRAPS) {
+  assert(class_loader == _java_system_loader, "unexpected class loader");
+  // get_package_name() returns a NULL handle if the class is in unnamed package
+  Handle pkgname_string = get_package_name(class_name, CHECK);
+  if (pkgname_string.not_null()) {
+    Klass* app_classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args(3);
+    args.set_receiver(class_loader);
+    args.push_oop(pkgname_string);
+    args.push_oop(manifest);
+    args.push_oop(url);
+    JavaCalls::call_virtual(&result, app_classLoader_klass,
+                            vmSymbols::defineOrCheckPackage_name(),
+                            vmSymbols::defineOrCheckPackage_signature(),
+                            &args,
+                            CHECK);
+  }
+}
+
+// Define Package for shared app/platform classes from named module
+void SystemDictionaryShared::define_shared_package(Symbol* class_name,
+                                                   Handle class_loader,
+                                                   ModuleEntry* mod_entry,
+                                                   TRAPS) {
+  assert(mod_entry != NULL, "module_entry should not be NULL");
+  Handle module_handle(THREAD, mod_entry->module());
+
+  Handle pkg_name = get_package_name(class_name, CHECK);
+  assert(pkg_name.not_null(), "Package should not be null for class in named module");
+
+  Klass* classLoader_klass;
+  if (SystemDictionary::is_system_class_loader(class_loader())) {
+    classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
+  } else {
+    assert(SystemDictionary::is_platform_class_loader(class_loader()), "unexpected classloader");
+    classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
+  }
+
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args(2);
+  args.set_receiver(class_loader);
+  args.push_oop(pkg_name);
+  args.push_oop(module_handle);
+  JavaCalls::call_virtual(&result, classLoader_klass,
+                          vmSymbols::definePackage_name(),
+                          vmSymbols::definePackage_signature(),
+                          &args,
+                          CHECK);
+}
+
+// Get the ProtectionDomain associated with the CodeSource from the classloader.
+Handle SystemDictionaryShared::get_protection_domain_from_classloader(Handle class_loader,
+                                                                      Handle url, TRAPS) {
+  // CodeSource cs = new CodeSource(url, null);
+  InstanceKlass* cs_klass = SystemDictionary::CodeSource_klass();
+  Handle cs = cs_klass->allocate_instance_handle(CHECK_NH);
+  JavaValue void_result(T_VOID);
+  JavaCalls::call_special(&void_result, cs, cs_klass,
+                          vmSymbols::object_initializer_name(),
+                          vmSymbols::url_code_signer_array_void_signature(),
+                          url, Handle(), CHECK_NH);
+
+  // protection_domain = SecureClassLoader.getProtectionDomain(cs);
+  Klass* secureClassLoader_klass = SystemDictionary::SecureClassLoader_klass();
+  JavaValue obj_result(T_OBJECT);
+  JavaCalls::call_virtual(&obj_result, class_loader, secureClassLoader_klass,
+                          vmSymbols::getProtectionDomain_name(),
+                          vmSymbols::getProtectionDomain_signature(),
+                          cs, CHECK_NH);
+  return Handle(THREAD, (oop)obj_result.get_jobject());
+}
+
+// Returns the ProtectionDomain associated with the JAR file identified by the url.
+Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader,
+                                                            int shared_path_index,
+                                                            Handle url,
+                                                            TRAPS) {
+  Handle protection_domain;
+  if (shared_protection_domain(shared_path_index) == NULL) {
+    Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD);
+    atomic_set_shared_protection_domain(shared_path_index, pd());
+  }
+
+  // Acquire from the cache because if another thread beats the current one to
+  // set the shared protection_domain and the atomic_set fails, the current thread
+  // needs to get the updated protection_domain from the cache.
+  protection_domain = Handle(THREAD, shared_protection_domain(shared_path_index));
+  assert(protection_domain.not_null(), "sanity");
+  return protection_domain;
+}
+
+// Returns the ProtectionDomain associated with the moduleEntry.
+Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader,
+                                                            ModuleEntry* mod, TRAPS) {
+  ClassLoaderData *loader_data = mod->loader_data();
+  Handle protection_domain;
+  if (mod->shared_protection_domain() == NULL) {
+    Symbol* location = mod->location();
+    if (location != NULL) {
+      Handle url_string = java_lang_String::create_from_symbol(
+                                 location, CHECK_(protection_domain));
+      JavaValue result(T_OBJECT);
+      Klass* classLoaders_klass =
+        SystemDictionary::jdk_internal_loader_ClassLoaders_klass();
+        JavaCalls::call_static(&result, classLoaders_klass, vmSymbols::toFileURL_name(),
+                               vmSymbols::toFileURL_signature(),
+                               url_string, CHECK_(protection_domain));
+      Handle url = Handle(THREAD, (oop)result.get_jobject());
+
+      Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD);
+      mod->set_shared_protection_domain(loader_data, pd);
+    }
+  }
+
+  protection_domain = Handle(THREAD, mod->shared_protection_domain());
+  assert(protection_domain.not_null(), "sanity");
+  return protection_domain;
+}
+
+// Initializes the java.lang.Package and java.security.ProtectionDomain objects associated with
+// the given InstanceKlass.
+// Returns the ProtectionDomain for the InstanceKlass.
+Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS) {
+  Handle pd;
+
+  if (ik != NULL) {
+    int index = ik->shared_classpath_index();
+    assert(index >= 0, "Sanity");
+    SharedClassPathEntryExt* ent =
+            (SharedClassPathEntryExt*)FileMapInfo::shared_classpath(index);
+    Symbol* class_name = ik->name();
+
+    if (ent->is_modules_image()) {
+      // For shared app/platform classes originated from the run-time image:
+      //   The ProtectionDomains are cached in the corresponding ModuleEntries
+      //   for fast access by the VM.
+      ResourceMark rm;
+      ClassLoaderData *loader_data =
+                ClassLoaderData::class_loader_data(class_loader());
+      PackageEntryTable* pkgEntryTable = loader_data->packages();
+      TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_(pd));
+      if (pkg_name != NULL) {
+        PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name);
+        if (pkg_entry != NULL) {
+          ModuleEntry* mod_entry = pkg_entry->module();
+          pd = get_shared_protection_domain(class_loader, mod_entry, THREAD);
+          define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd));
+        }
+      }
+    } else {
+      // For shared app/platform classes originated from JAR files on the class path:
+      //   Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length
+      //   as the shared classpath table in the shared archive (see
+      //   FileMap::_classpath_entry_table in filemap.hpp for details).
+      //
+      //   If a shared InstanceKlass k is loaded from the class path, let
+      //
+      //     index = k->shared_classpath_index():
+      //
+      //   FileMap::_classpath_entry_table[index] identifies the JAR file that contains k.
+      //
+      //   k's protection domain is:
+      //
+      //     ProtectionDomain pd = _shared_protection_domains[index];
+      //
+      //   and k's Package is initialized using
+      //
+      //     manifest = _shared_jar_manifests[index];
+      //     url = _shared_jar_urls[index];
+      //     define_shared_package(class_name, class_loader, manifest, url, CHECK_(pd));
+      //
+      //   Note that if an element of these 3 _shared_xxx arrays is NULL, it will be initialized by
+      //   the corresponding SystemDictionaryShared::get_shared_xxx() function.
+      Handle manifest = get_shared_jar_manifest(index, CHECK_(pd));
+      Handle url = get_shared_jar_url(index, CHECK_(pd));
+      define_shared_package(class_name, class_loader, manifest, url, CHECK_(pd));
+      pd = get_shared_protection_domain(class_loader, index, url, CHECK_(pd));
+    }
+  }
+  return pd;
+}
+
+// Currently AppCDS only archives classes from the run-time image, the
+// -Xbootclasspath/a path, and the class path. The following rules need to be
+// revised when AppCDS is changed to archive classes from other code sources
+// in the future, for example the module path (specified by -p).
+//
+// Check if a shared class can be loaded by the specific classloader. Following
+// are the "visible" archived classes for different classloaders.
+//
+// NULL classloader:
+//   - see SystemDictionary::is_shared_class_visible()
+// Platform classloader:
+//   - Module class from "modules" jimage. ModuleEntry must be defined in the
+//     classloader.
+// App Classloader:
+//   - Module class from "modules" jimage. ModuleEntry must be defined in the
+//     classloader.
+//   - Class from -cp. The class must have no PackageEntry defined in any of the
+//     boot/platform/app classloader, or must be in the unnamed module defined in the
+//     AppClassLoader.
+bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
+                                                     InstanceKlass* ik,
+                                                     Handle class_loader,
+                                                     const char* pkg_string,
+                                                     Symbol* pkg_name,
+                                                     PackageEntry* pkg_entry,
+                                                     ModuleEntry* mod_entry,
+                                                     TRAPS) {
+  assert(class_loader.not_null(), "Class loader should not be NULL");
+  assert(Universe::is_module_initialized(), "Module system is not initialized");
+
+  int path_index = ik->shared_classpath_index();
+  SharedClassPathEntry* ent =
+            (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
+
+  if (SystemDictionary::is_platform_class_loader(class_loader())) {
+    assert(ent != NULL, "shared class for PlatformClassLoader should have valid SharedClassPathEntry");
+    // The PlatformClassLoader can only load archived class originated from the
+    // run-time image. The class' PackageEntry/ModuleEntry must be
+    // defined by the PlatformClassLoader.
+    if (mod_entry != NULL) {
+      // PackageEntry/ModuleEntry is found in the classloader. Check if the
+      // ModuleEntry's location agrees with the archived class' origination.
+      if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) {
+        return true; // Module class from the "modules" jimage
+      }
+    }
+  } else if (SystemDictionary::is_system_class_loader(class_loader())) {
+    assert(ent != NULL, "shared class for system loader should have valid SharedClassPathEntry");
+    if (pkg_string == NULL) {
+      // The archived class is in the unnamed package. Currently, the boot image
+      // does not contain any class in the unnamed package.
+      assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath");
+      if (path_index >= ClassLoaderExt::app_paths_start_index()) {
+        return true;
+      }
+    } else {
+      // Check if this is from a PackageEntry/ModuleEntry defined in the AppClassloader.
+      if (pkg_entry == NULL) {
+        // It's not guaranteed that the class is from the classpath if the
+        // PackageEntry cannot be found from the AppClassloader. Need to check
+        // the boot and platform classloader as well.
+        if (get_package_entry(pkg_name, ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader())) == NULL &&
+            get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) {
+          // The PackageEntry is not defined in any of the boot/platform/app classloaders.
+          // The archived class must from -cp path and not from the run-time image.
+          if (!ent->is_modules_image() && path_index >= ClassLoaderExt::app_paths_start_index()) {
+            return true;
+          }
+        }
+      } else if (mod_entry != NULL) {
+        // The package/module is defined in the AppClassLoader. Currently we only
+        // support archiving application module class from the run-time image.
+        // Packages from the -cp path are in the unnamed_module.
+        if ((ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) ||
+            (pkg_entry->in_unnamed_module() && path_index >= ClassLoaderExt::app_paths_start_index())) {
+          DEBUG_ONLY( \
+            ClassLoaderData* loader_data = class_loader_data(class_loader); \
+            if (pkg_entry->in_unnamed_module()) \
+              assert(mod_entry == loader_data->unnamed_module(), "the unnamed module is not defined in the classloader");)
+
+          return true;
+        }
+      }
+    }
+  } else {
+    // TEMP: if a shared class can be found by a custom loader, consider it visible now.
+    // FIXME: is this actually correct?
+    return true;
+  }
+  return false;
+}
+
+// The following stack shows how this code is reached:
+//
+//   [0] SystemDictionaryShared::find_or_load_shared_class()
+//   [1] JVM_FindLoadedClass
+//   [2] java.lang.ClassLoader.findLoadedClass0()
+//   [3] java.lang.ClassLoader.findLoadedClass()
+//   [4] java.lang.ClassLoader.loadClass()
+//   [5] jdk.internal.loader.ClassLoaders$AppClassLoader_klass.loadClass()
+//
+// Because AppCDS supports only the PlatformClassLoader and AppClassLoader, we make the following
+// assumptions (based on the JDK 8.0 source code):
+//
+// [a] these two loaders use the default implementation of
+//     ClassLoader.loadClass(String name, boolean resolve), which
+// [b] calls findLoadedClass(name), immediately followed by parent.loadClass(),
+//     immediately followed by findClass(name).
+// [c] If the requested class is a shared class of the current class loader, parent.loadClass()
+//     always returns null, and
+// [d] if AppCDS is not enabled, the class would be loaded by findClass() by decoding it from a
+//     JAR file and then parsed.
+//
+// Given these assumptions, we intercept the findLoadedClass() call to invoke
+// SystemDictionaryShared::find_or_load_shared_class() to load the shared class from
+// the archive. The reasons are:
+//
+// + Because AppCDS is a commercial feature, we want to hide the implementation. There
+//   is currently no easy way to hide Java code, so we did it with native code.
+// + Start-up is improved because we avoid decoding the JAR file, and avoid delegating
+//   to the parent (since we know the parent will not find this class).
+//
+// NOTE: there's a lot of assumption about the Java code. If any of that change, this
+// needs to be redesigned.
+//
+// An alternative is to modify the Java code of AppClassLoader.loadClass().
+//
+InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
+                 Symbol* name, Handle class_loader, TRAPS) {
+  if (DumpSharedSpaces) {
+    return NULL;
+  }
+
+  InstanceKlass* k = NULL;
+  if (shared_dictionary() != NULL &&
+      UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader()) ||
+                    SystemDictionary::is_platform_class_loader(class_loader()))) {
+
+    // Fix for 4474172; see evaluation for more details
+    class_loader = Handle(
+      THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
+    ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
+    Dictionary* dictionary = loader_data->dictionary();
+
+    unsigned int d_hash = dictionary->compute_hash(name);
+
+    bool DoObjectLock = true;
+    if (is_parallelCapable(class_loader)) {
+      DoObjectLock = false;
+    }
+
+    // Make sure we are synchronized on the class loader before we proceed
+    //
+    // Note: currently, find_or_load_shared_class is called only from
+    // JVM_FindLoadedClass and used for PlatformClassLoader and AppClassLoader,
+    // which are parallel-capable loaders, so this lock is NOT taken.
+    Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
+    check_loader_lock_contention(lockObject, THREAD);
+    ObjectLocker ol(lockObject, THREAD, DoObjectLock);
+
+    {
+      MutexLocker mu(SystemDictionary_lock, THREAD);
+      Klass* check = find_class(d_hash, name, dictionary);
+      if (check != NULL) {
+        return InstanceKlass::cast(check);
+      }
+    }
+
+    k = load_shared_class_for_builtin_loader(name, class_loader, THREAD);
+    if (k != NULL) {
+      define_instance_class(k, CHECK_NULL);
+    }
+  }
+
+  return k;
+}
+
+InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
+                 Symbol* class_name, Handle class_loader, TRAPS) {
+  assert(UseAppCDS && shared_dictionary() != NULL, "already checked");
+  Klass* k = shared_dictionary()->find_class_for_builtin_loader(class_name);
+
+  if (k != NULL) {
+    InstanceKlass* ik = InstanceKlass::cast(k);
+    if ((ik->is_shared_app_class() &&
+         SystemDictionary::is_system_class_loader(class_loader()))  ||
+        (ik->is_shared_platform_class() &&
+         SystemDictionary::is_platform_class_loader(class_loader()))) {
+      Handle protection_domain =
+        SystemDictionaryShared::init_security_info(class_loader, ik, CHECK_NULL);
+      return load_shared_class(ik, class_loader, protection_domain, THREAD);
+    }
+  }
+
+  return NULL;
+}
+
+void SystemDictionaryShared::oops_do(OopClosure* f) {
+  f->do_oop((oop*)&_shared_protection_domains);
+  f->do_oop((oop*)&_shared_jar_urls);
+  f->do_oop((oop*)&_shared_jar_manifests);
+}
+
+void SystemDictionaryShared::allocate_shared_protection_domain_array(int size, TRAPS) {
+  if (_shared_protection_domains == NULL) {
+    _shared_protection_domains = oopFactory::new_objArray(
+        SystemDictionary::ProtectionDomain_klass(), size, CHECK);
+  }
+}
+
+void SystemDictionaryShared::allocate_shared_jar_url_array(int size, TRAPS) {
+  if (_shared_jar_urls == NULL) {
+    _shared_jar_urls = oopFactory::new_objArray(
+        SystemDictionary::URL_klass(), size, CHECK);
+  }
+}
+
+void SystemDictionaryShared::allocate_shared_jar_manifest_array(int size, TRAPS) {
+  if (_shared_jar_manifests == NULL) {
+    _shared_jar_manifests = oopFactory::new_objArray(
+        SystemDictionary::Jar_Manifest_klass(), size, CHECK);
+  }
+}
+
+void SystemDictionaryShared::allocate_shared_data_arrays(int size, TRAPS) {
+  allocate_shared_protection_domain_array(size, CHECK);
+  allocate_shared_jar_url_array(size, CHECK);
+  allocate_shared_jar_manifest_array(size, CHECK);
+}
+
+
+InstanceKlass* SystemDictionaryShared::lookup_from_stream(const Symbol* class_name,
+                                                          Handle class_loader,
+                                                          Handle protection_domain,
+                                                          const ClassFileStream* cfs,
+                                                          TRAPS) {
+  if (!UseAppCDS || shared_dictionary() == NULL) {
+    return NULL;
+  }
+  if (class_name == NULL) {  // don't do this for anonymous classes
+    return NULL;
+  }
+  if (class_loader.is_null() ||
+      SystemDictionary::is_system_class_loader(class_loader()) ||
+      SystemDictionary::is_platform_class_loader(class_loader())) {
+    // This function is called for loading only UNREGISTERED classes.
+    // Do nothing for the BUILTIN loaders.
+    return NULL;
+  }
+
+  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+  Klass* k;
+
+  { // UNREGISTERED loader
+    if (!shared_dictionary()->class_exists_for_unregistered_loader(class_name)) {
+      // No classes of this name for unregistered loaders.
+      return NULL;
+    }
+
+    int clsfile_size  = cfs->length();
+    int clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length());
+
+    k = shared_dictionary()->find_class_for_unregistered_loader(class_name,
+                                                                clsfile_size, clsfile_crc32);
+  }
+
+  if (k == NULL) { // not archived
+    return NULL;
+  }
+
+  return acquire_class_for_current_thread(InstanceKlass::cast(k), class_loader,
+                                          protection_domain, THREAD);
+}
+
+InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread(
+                   InstanceKlass *ik,
+                   Handle class_loader,
+                   Handle protection_domain,
+                   TRAPS) {
+  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+
+  {
+    MutexLocker mu(SharedDictionary_lock, THREAD);
+    if (ik->class_loader_data() != NULL) {
+      //    ik is already loaded (by this loader or by a different loader)
+      // or ik is being loaded by a different thread (by this loader or by a different loader)
+      return NULL;
+    }
+
+    // No other thread has acquired this yet, so give it to *this thread*
+    ik->set_class_loader_data(loader_data);
+  }
+
+  // No longer holding SharedDictionary_lock
+  // No need to lock, as <ik> can be held only by a single thread.
+  loader_data->add_class(ik);
+
+  // Load and check super/interfaces, restore unsharable info
+  InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain, THREAD);
+  if (shared_klass == NULL || HAS_PENDING_EXCEPTION) {
+    // TODO: clean up <ik> so it can be used again
+    return NULL;
+  }
+
+  return shared_klass;
+}
+
+bool SystemDictionaryShared::add_non_builtin_klass(Symbol* name, ClassLoaderData* loader_data,
+                                                   InstanceKlass* k,
+                                                   TRAPS) {
+  assert(DumpSharedSpaces, "only when dumping");
+  assert(UseAppCDS && boot_loader_dictionary() != NULL, "must be");
+
+  if (boot_loader_dictionary()->add_non_builtin_klass(name, loader_data, k)) {
+    MutexLocker mu_r(Compile_lock, THREAD); // not really necessary, but add_to_hierarchy asserts this.
+    add_to_hierarchy(k, CHECK_0);
+    return true;
+  }
+  return false;
+}
+
+// This function is called to resolve the super/interfaces of shared classes for
+// non-built-in loaders. E.g., ChildClass in the below example
+// where "super:" (and optionally "interface:") have been specified.
+//
+// java/lang/Object id: 0
+// Interface   id: 2 super: 0 source: cust.jar
+// ChildClass  id: 4 super: 0 interfaces: 2 source: cust.jar
+Klass* SystemDictionaryShared::dump_time_resolve_super_or_fail(
+    Symbol* child_name, Symbol* class_name, Handle class_loader,
+    Handle protection_domain, bool is_superclass, TRAPS) {
+
+  assert(DumpSharedSpaces, "only when dumping");
+
+  ClassListParser* parser = ClassListParser::instance();
+  if (parser == NULL) {
+    // We're still loading the well-known classes, before the ClassListParser is created.
+    return NULL;
+  }
+  if (child_name->equals(parser->current_class_name())) {
+    // When this function is called, all the numbered super and interface types
+    // must have already been loaded. Hence this function is never recursively called.
+    if (is_superclass) {
+      return parser->lookup_super_for_current_class(class_name);
+    } else {
+      return parser->lookup_interface_for_current_class(class_name);
+    }
+  } else {
+    // The VM is not trying to resolve a super type of parser->current_class_name().
+    // Instead, it's resolving an error class (because parser->current_class_name() has
+    // failed parsing or verification). Don't do anything here.
+    return NULL;
+  }
+}
+
+struct SharedMiscInfo {
+  Klass* _klass;
+  int _clsfile_size;
+  int _clsfile_crc32;
+};
+
+static GrowableArray<SharedMiscInfo>* misc_info_array = NULL;
+
+void SystemDictionaryShared::set_shared_class_misc_info(Klass* k, ClassFileStream* cfs) {
+  assert(DumpSharedSpaces, "only when dumping");
+  int clsfile_size  = cfs->length();
+  int clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length());
+
+  if (misc_info_array == NULL) {
+    misc_info_array = new (ResourceObj::C_HEAP, mtClass) GrowableArray<SharedMiscInfo>(20, /*c heap*/ true);
+  }
+
+  SharedMiscInfo misc_info;
+  DEBUG_ONLY({
+      for (int i=0; i<misc_info_array->length(); i++) {
+        misc_info = misc_info_array->at(i);
+        assert(misc_info._klass != k, "cannot call set_shared_class_misc_info twice for the same class");
+      }
+    });
+
+  misc_info._klass = k;
+  misc_info._clsfile_size = clsfile_size;
+  misc_info._clsfile_crc32 = clsfile_crc32;
+
+  misc_info_array->append(misc_info);
+}
+
+void SystemDictionaryShared::init_shared_dictionary_entry(Klass* k, DictionaryEntry* ent) {
+  SharedDictionaryEntry* entry = (SharedDictionaryEntry*)ent;
+  entry->_id = -1;
+  entry->_clsfile_size = -1;
+  entry->_clsfile_crc32 = -1;
+  entry->_verifier_constraints = NULL;
+  entry->_verifier_constraint_flags = NULL;
+
+  if (misc_info_array != NULL) {
+    for (int i=0; i<misc_info_array->length(); i++) {
+      SharedMiscInfo misc_info = misc_info_array->at(i);
+      if (misc_info._klass == k) {
+        entry->_clsfile_size = misc_info._clsfile_size;
+        entry->_clsfile_crc32 = misc_info._clsfile_crc32;
+        misc_info_array->remove_at(i);
+        return;
+      }
+    }
+  }
+}
+
+bool SystemDictionaryShared::add_verification_constraint(Klass* k, Symbol* name,
+         Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
+  assert(DumpSharedSpaces, "called at dump time only");
+
+  // Skip anonymous classes, which are not archived as they are not in
+  // dictionary (see assert_no_anonymoys_classes_in_dictionaries() in
+  // VM_PopulateDumpSharedSpace::doit()).
+  if (k->class_loader_data()->is_anonymous()) {
+    return true; // anonymous classes are not archived, skip
+  }
+
+  SharedDictionaryEntry* entry = ((SharedDictionary*)(k->class_loader_data()->dictionary()))->find_entry_for(k);
+  ResourceMark rm;
+  // Lambda classes are not archived and will be regenerated at runtime.
+  if (entry == NULL && strstr(k->name()->as_C_string(), "Lambda$") != NULL) {
+    return true;
+  }
+  assert(entry != NULL, "class should be in dictionary before being verified");
+  entry->add_verification_constraint(name, from_name, from_field_is_protected,
+                                     from_is_array, from_is_object);
+  if (entry->is_builtin()) {
+    // For builtin class loaders, we can try to complete the verification check at dump time,
+    // because we can resolve all the constraint classes.
+    return false;
+  } else {
+    // For non-builtin class loaders, we cannot complete the verification check at dump time,
+    // because at dump time we don't know how to resolve classes for such loaders.
+    return true;
+  }
+}
+
+void SystemDictionaryShared::finalize_verification_constraints() {
+  boot_loader_dictionary()->finalize_verification_constraints();
+}
+
+void SystemDictionaryShared::check_verification_constraints(InstanceKlass* klass,
+                                                             TRAPS) {
+  assert(!DumpSharedSpaces && UseSharedSpaces, "called at run time with CDS enabled only");
+  SharedDictionaryEntry* entry = shared_dictionary()->find_entry_for(klass);
+  assert(entry != NULL, "call this only for shared classes");
+  entry->check_verification_constraints(klass, THREAD);
+}
+
+SharedDictionaryEntry* SharedDictionary::find_entry_for(Klass* klass) {
+  Symbol* class_name = klass->name();
+  unsigned int hash = compute_hash(class_name);
+  int index = hash_to_index(hash);
+
+  for (SharedDictionaryEntry* entry = bucket(index);
+                              entry != NULL;
+                              entry = entry->next()) {
+    if (entry->hash() == hash && entry->literal() == klass) {
+      return entry;
+    }
+  }
+
+  return NULL;
+}
+
+void SharedDictionary::finalize_verification_constraints() {
+  int bytes = 0, count = 0;
+  for (int index = 0; index < table_size(); index++) {
+    for (SharedDictionaryEntry *probe = bucket(index);
+                                probe != NULL;
+                               probe = probe->next()) {
+      int n = probe->finalize_verification_constraints();
+      if (n > 0) {
+        bytes += n;
+        count ++;
+      }
+    }
+  }
+  if (log_is_enabled(Info, cds, verification)) {
+    double avg = 0;
+    if (count > 0) {
+      avg = double(bytes) / double(count);
+    }
+    log_info(cds, verification)("Recorded verification constraints for %d classes = %d bytes (avg = %.2f bytes) ", count, bytes, avg);
+  }
+}
+
+void SharedDictionaryEntry::add_verification_constraint(Symbol* name,
+         Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
+  if (_verifier_constraints == NULL) {
+    _verifier_constraints = new(ResourceObj::C_HEAP, mtClass) GrowableArray<Symbol*>(8, true, mtClass);
+  }
+  if (_verifier_constraint_flags == NULL) {
+    _verifier_constraint_flags = new(ResourceObj::C_HEAP, mtClass) GrowableArray<char>(4, true, mtClass);
+  }
+  GrowableArray<Symbol*>* vc_array = (GrowableArray<Symbol*>*)_verifier_constraints;
+  for (int i=0; i<vc_array->length(); i+= 2) {
+    if (name      == vc_array->at(i) &&
+        from_name == vc_array->at(i+1)) {
+      return;
+    }
+  }
+  vc_array->append(name);
+  vc_array->append(from_name);
+
+  GrowableArray<char>* vcflags_array = (GrowableArray<char>*)_verifier_constraint_flags;
+  char c = 0;
+  c |= from_field_is_protected ? FROM_FIELD_IS_PROTECTED : 0;
+  c |= from_is_array           ? FROM_IS_ARRAY           : 0;
+  c |= from_is_object          ? FROM_IS_OBJECT          : 0;
+  vcflags_array->append(c);
+
+  if (log_is_enabled(Trace, cds, verification)) {
+    ResourceMark rm;
+    log_trace(cds, verification)("add_verification_constraint: %s: %s must be subclass of %s",
+                                 instance_klass()->external_name(), from_name->as_klass_external_name(),
+                                 name->as_klass_external_name());
+  }
+}
+
+int SharedDictionaryEntry::finalize_verification_constraints() {
+  assert(DumpSharedSpaces, "called at dump time only");
+  Thread* THREAD = Thread::current();
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  GrowableArray<Symbol*>* vc_array = (GrowableArray<Symbol*>*)_verifier_constraints;
+  GrowableArray<char>* vcflags_array = (GrowableArray<char>*)_verifier_constraint_flags;
+
+  if (vc_array != NULL) {
+    if (log_is_enabled(Trace, cds, verification)) {
+      ResourceMark rm;
+      log_trace(cds, verification)("finalize_verification_constraint: %s",
+                                   literal()->external_name());
+    }
+
+    // Copy the constraints from C_HEAP-alloced GrowableArrays to Metaspace-alloced
+    // Arrays
+    int size = 0;
+    {
+      // FIXME: change this to be done after relocation, so we can use symbol offset??
+      int length = vc_array->length();
+      Array<Symbol*>* out = MetadataFactory::new_array<Symbol*>(loader_data, length, 0, THREAD);
+      assert(out != NULL, "Dump time allocation failure would have aborted VM");
+      for (int i=0; i<length; i++) {
+        out->at_put(i, vc_array->at(i));
+      }
+      _verifier_constraints = out;
+      size += out->size() * BytesPerWord;
+      delete vc_array;
+    }
+    {
+      int length = vcflags_array->length();
+      Array<char>* out = MetadataFactory::new_array<char>(loader_data, length, 0, THREAD);
+      assert(out != NULL, "Dump time allocation failure would have aborted VM");
+      for (int i=0; i<length; i++) {
+        out->at_put(i, vcflags_array->at(i));
+      }
+      _verifier_constraint_flags = out;
+      size += out->size() * BytesPerWord;
+      delete vcflags_array;
+    }
+
+    return size;
+  }
+  return 0;
+}
+
+void SharedDictionaryEntry::check_verification_constraints(InstanceKlass* klass, TRAPS) {
+  Array<Symbol*>* vc_array = (Array<Symbol*>*)_verifier_constraints;
+  Array<char>* vcflags_array = (Array<char>*)_verifier_constraint_flags;
+
+  if (vc_array != NULL) {
+    int length = vc_array->length();
+    for (int i=0; i<length; i+=2) {
+      Symbol* name      = vc_array->at(i);
+      Symbol* from_name = vc_array->at(i+1);
+      char c = vcflags_array->at(i/2);
+
+      bool from_field_is_protected = (c & FROM_FIELD_IS_PROTECTED) ? true : false;
+      bool from_is_array           = (c & FROM_IS_ARRAY)           ? true : false;
+      bool from_is_object          = (c & FROM_IS_OBJECT)          ? true : false;
+
+      bool ok = VerificationType::resolve_and_check_assignability(klass, name,
+         from_name, from_field_is_protected, from_is_array, from_is_object, CHECK);
+      if (!ok) {
+        ResourceMark rm(THREAD);
+        stringStream ss;
+
+        ss.print_cr("Bad type on operand stack");
+        ss.print_cr("Exception Details:");
+        ss.print_cr("  Location:\n    %s", klass->name()->as_C_string());
+        ss.print_cr("  Reason:\n    Type '%s' is not assignable to '%s'",
+                    from_name->as_quoted_ascii(), name->as_quoted_ascii());
+        THROW_MSG(vmSymbols::java_lang_VerifyError(), ss.as_string());
+      }
+    }
+  }
+}
+
+void SharedDictionaryEntry::metaspace_pointers_do(MetaspaceClosure* it) {
+  it->push((Array<Symbol*>**)&_verifier_constraints);
+  it->push((Array<char>**)&_verifier_constraint_flags);
+}
+
+bool SharedDictionary::add_non_builtin_klass(const Symbol* class_name,
+                                             ClassLoaderData* loader_data,
+                                             InstanceKlass* klass) {
+
+  assert(DumpSharedSpaces, "supported only when dumping");
+  assert(klass != NULL, "adding NULL klass");
+  assert(klass->name() == class_name, "sanity check on name");
+  assert(klass->shared_classpath_index() < 0,
+         "the shared classpath index should not be set for shared class loaded by the custom loaders");
+
+  // Add an entry for a non-builtin class.
+  // For a shared class for custom class loaders, SystemDictionary::resolve_or_null will
+  // not find this class, because is_builtin() is false.
+  unsigned int hash = compute_hash(class_name);
+  int index = hash_to_index(hash);
+
+  for (SharedDictionaryEntry* entry = bucket(index);
+                              entry != NULL;
+                              entry = entry->next()) {
+    if (entry->hash() == hash) {
+      Klass* klass = (Klass*)entry->literal();
+      if (klass->name() == class_name && klass->class_loader_data() == loader_data) {
+        // There is already a class defined with the same name
+        return false;
+      }
+    }
+  }
+
+  assert(Dictionary::entry_size() >= sizeof(SharedDictionaryEntry), "must be big enough");
+  SharedDictionaryEntry* entry = (SharedDictionaryEntry*)new_entry(hash, klass);
+  add_entry(index, entry);
+
+  assert(entry->is_unregistered(), "sanity");
+  assert(!entry->is_builtin(), "sanity");
+  return true;
+}
+
+
+//-----------------
+// SharedDictionary
+//-----------------
+
+
+Klass* SharedDictionary::find_class_for_builtin_loader(const Symbol* name) const {
+  SharedDictionaryEntry* entry = get_entry_for_builtin_loader(name);
+  return entry != NULL ? entry->instance_klass() : (Klass*)NULL;
+}
+
+Klass* SharedDictionary::find_class_for_unregistered_loader(const Symbol* name,
+                                                            int clsfile_size,
+                                                            int clsfile_crc32) const {
+
+  const SharedDictionaryEntry* entry = get_entry_for_unregistered_loader(name,
+                                                                         clsfile_size,
+                                                                         clsfile_crc32);
+  return entry != NULL ? entry->instance_klass() : (Klass*)NULL;
+}
+
+void SharedDictionary::update_entry(Klass* klass, int id) {
+  assert(DumpSharedSpaces, "supported only when dumping");
+  Symbol* class_name = klass->name();
+  unsigned int hash = compute_hash(class_name);
+  int index = hash_to_index(hash);
+
+  for (SharedDictionaryEntry* entry = bucket(index);
+                              entry != NULL;
+                              entry = entry->next()) {
+    if (entry->hash() == hash && entry->literal() == klass) {
+      entry->_id = id;
+      return;
+    }
+  }
+
+  ShouldNotReachHere();
+}
+
+SharedDictionaryEntry* SharedDictionary::get_entry_for_builtin_loader(const Symbol* class_name) const {
+  assert(!DumpSharedSpaces, "supported only when at runtime");
+  unsigned int hash = compute_hash(class_name);
+  const int index = hash_to_index(hash);
+
+  for (SharedDictionaryEntry* entry = bucket(index);
+                              entry != NULL;
+                              entry = entry->next()) {
+    if (entry->hash() == hash && entry->equals(class_name)) {
+      if (entry->is_builtin()) {
+        return entry;
+      }
+    }
+  }
+  return NULL;
+}
+
+SharedDictionaryEntry* SharedDictionary::get_entry_for_unregistered_loader(const Symbol* class_name,
+                                                                           int clsfile_size,
+                                                                           int clsfile_crc32) const {
+  assert(!DumpSharedSpaces, "supported only when at runtime");
+  unsigned int hash = compute_hash(class_name);
+  int index = hash_to_index(hash);
+
+  for (SharedDictionaryEntry* entry = bucket(index);
+                              entry != NULL;
+                              entry = entry->next()) {
+    if (entry->hash() == hash && entry->equals(class_name)) {
+      if (entry->is_unregistered()) {
+        if (clsfile_size == -1) {
+          // We're called from class_exists_for_unregistered_loader. At run time, we want to
+          // compute the CRC of a ClassFileStream only if there is an UNREGISTERED class
+          // with the matching name.
+          return entry;
+        } else {
+          // We're called from find_class_for_unregistered_loader
+          if (entry->_clsfile_size && clsfile_crc32 == entry->_clsfile_crc32) {
+            return entry;
+          }
+        }
+
+        // There can be only 1 class with this name for unregistered loaders.
+        return NULL;
+      }
+    }
+  }
+  return NULL;
+}
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,75 +25,362 @@
 #ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
 #define SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
 
+#include "oops/klass.hpp"
+#include "classfile/dictionary.hpp"
 #include "classfile/systemDictionary.hpp"
-#include "classfile/dictionary.hpp"
+#include "memory/filemap.hpp"
+
+
+/*===============================================================================
+
+    Handling of the classes in the AppCDS archive
+
+    To ensure safety and to simplify the implementation, archived classes are
+    "segregated" into several types. The following rules describe how they
+    are stored and looked up.
+
+[1] Category of archived classes
+
+    There are 3 disjoint groups of classes stored in the AppCDS archive. They are
+    categorized as by their SharedDictionaryEntry::loader_type()
+
+    BUILTIN:              These classes may be defined ONLY by the BOOT/PLATFORM/APP
+                          loaders.
+
+    UNREGISTERED:         These classes may be defined ONLY by a ClassLoader
+                          instance that's not listed above (using fingerprint matching)
+
+[2] How classes from different categories are specified in the classlist:
+
+    Starting from JDK9, each class in the classlist may be specified with
+    these keywords: "id", "super", "interfaces", "loader" and "source".
+
+
+    BUILTIN               Only the "id" keyword may be (optionally) specified. All other
+                          keywords are forbidden.
+
+                          The named class is looked up from the jimage and from
+                          Xbootclasspath/a and CLASSPATH.
+
+    UNREGISTERED:         The "id", "super", and "source" keywords must all be
+                          specified.
+
+                          The "interfaces" keyword must be specified if the class implements
+                          one or more local interfaces. The "interfaces" keyword must not be
+                          specified if the class does not implement local interfaces.
+
+                          The named class is looked up from the location specified in the
+                          "source" keyword.
+
+    Example classlist:
+
+    # BUILTIN
+    java/lang/Object id: 0
+    java/lang/Cloneable id: 1
+    java/lang/String
+
+    # UNREGISTERED
+    Bar id: 3 super: 0 interfaces: 1 source: /foo.jar
+
+
+[3] Identifying the loader_type of archived classes in the shared dictionary
+
+    Each archived Klass* C is associated with a SharedDictionaryEntry* E
+
+    BUILTIN:              (C->shared_classpath_index() >= 0)
+    UNREGISTERED:         (C->shared_classpath_index() <  0)
+
+[4] Lookup of archived classes at run time:
+
+    (a) BUILTIN loaders:
+
+        Search the shared directory for a BUILTIN class with a matching name.
+
+    (b) UNREGISTERED loaders:
+
+        The search originates with SystemDictionaryShared::lookup_from_stream().
+
+        Search the shared directory for a UNREGISTERED class with a matching
+        (name, clsfile_len, clsfile_crc32) tuple.
+
+===============================================================================*/
+#define UNREGISTERED_INDEX -9999
 
 class ClassFileStream;
 
-class SystemDictionaryShared: public SystemDictionary {
+// Archived classes need extra information not needed by traditionally loaded classes.
+// To keep footprint small, we add these in the dictionary entry instead of the InstanceKlass.
+class SharedDictionaryEntry : public DictionaryEntry {
+
+public:
+  enum LoaderType {
+    LT_BUILTIN,
+    LT_UNREGISTERED
+  };
+
+  enum {
+    FROM_FIELD_IS_PROTECTED = 1 << 0,
+    FROM_IS_ARRAY           = 1 << 1,
+    FROM_IS_OBJECT          = 1 << 2
+  };
+
+  int             _id;
+  int             _clsfile_size;
+  int             _clsfile_crc32;
+  void*           _verifier_constraints; // FIXME - use a union here to avoid type casting??
+  void*           _verifier_constraint_flags;
+
+  // See "Identifying the loader_type of archived classes" comments above.
+  LoaderType loader_type() const {
+    Klass* k = (Klass*)literal();
+
+    if ((k->shared_classpath_index() != UNREGISTERED_INDEX)) {
+      return LT_BUILTIN;
+    } else {
+      return LT_UNREGISTERED;
+    }
+  }
+
+  SharedDictionaryEntry* next() {
+    return (SharedDictionaryEntry*)(DictionaryEntry::next());
+  }
+
+  bool is_builtin() const {
+    return loader_type() == LT_BUILTIN;
+  }
+  bool is_unregistered() const {
+    return loader_type() == LT_UNREGISTERED;
+  }
+
+  void add_verification_constraint(Symbol* name,
+         Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object);
+  int finalize_verification_constraints();
+  void check_verification_constraints(InstanceKlass* klass, TRAPS);
+  void metaspace_pointers_do(MetaspaceClosure* it) NOT_CDS_RETURN;
+};
+
+class SharedDictionary : public Dictionary {
+  SharedDictionaryEntry* get_entry_for_builtin_loader(const Symbol* name) const;
+  SharedDictionaryEntry* get_entry_for_unregistered_loader(const Symbol* name,
+                                                           int clsfile_size,
+                                                           int clsfile_crc32) const;
+
+  // Convenience functions
+  SharedDictionaryEntry* bucket(int index) const {
+    return (SharedDictionaryEntry*)(Dictionary::bucket(index));
+  }
+
 public:
-  static void initialize(TRAPS) {}
+  SharedDictionaryEntry* find_entry_for(Klass* klass);
+  void finalize_verification_constraints();
+
+  bool add_non_builtin_klass(const Symbol* class_name,
+                             ClassLoaderData* loader_data,
+                             InstanceKlass* obj);
+
+  void update_entry(Klass* klass, int id);
+
+  Klass* find_class_for_builtin_loader(const Symbol* name) const;
+  Klass* find_class_for_unregistered_loader(const Symbol* name,
+                                            int clsfile_size,
+                                            int clsfile_crc32) const;
+  bool class_exists_for_unregistered_loader(const Symbol* name) {
+    return (get_entry_for_unregistered_loader(name, -1, -1) != NULL);
+  }
+};
+
+class SystemDictionaryShared: public SystemDictionary {
+private:
+  // These _shared_xxxs arrays are used to initialize the java.lang.Package and
+  // java.security.ProtectionDomain objects associated with each shared class.
+  //
+  // See SystemDictionaryShared::init_security_info for more info.
+  static objArrayOop _shared_protection_domains;
+  static objArrayOop _shared_jar_urls;
+  static objArrayOop _shared_jar_manifests;
+
+  static InstanceKlass* load_shared_class_for_builtin_loader(
+                                               Symbol* class_name,
+                                               Handle class_loader,
+                                               TRAPS);
+  static Handle get_package_name(Symbol*  class_name, TRAPS);
+
+
+  // Package handling:
+  //
+  // 1. For named modules in the runtime image
+  //    BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces
+  //                  to get packages in named modules for shared classes.
+  //                  Package for non-shared classes in named module is also
+  //                  handled using JVM_GetSystemPackage(s).
+  //
+  //    APP  classes: VM calls ClassLoaders.AppClassLoader::definePackage(String, Module)
+  //                  to define package for shared app classes from named
+  //                  modules.
+  //
+  //    PLATFORM  classes: VM calls ClassLoaders.PlatformClassLoader::definePackage(String, Module)
+  //                  to define package for shared platform classes from named
+  //                  modules.
+  //
+  // 2. For unnamed modules
+  //    BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces to
+  //                  get packages for shared boot classes in unnamed modules.
+  //
+  //    APP  classes: VM calls ClassLoaders.AppClassLoader::defineOrCheckPackage()
+  //                  with with the manifest and url from archived data.
+  //
+  //    PLATFORM  classes: No package is defined.
+  //
+  // The following two define_shared_package() functions are used to define
+  // package for shared APP and PLATFORM classes.
+  static void define_shared_package(Symbol*  class_name,
+                                    Handle class_loader,
+                                    Handle manifest,
+                                    Handle url,
+                                    TRAPS);
+  static void define_shared_package(Symbol* class_name,
+                                    Handle class_loader,
+                                    ModuleEntry* mod_entry,
+                                    TRAPS);
+
+  static Handle get_shared_jar_manifest(int shared_path_index, TRAPS);
+  static Handle get_shared_jar_url(int shared_path_index, TRAPS);
+  static Handle get_protection_domain_from_classloader(Handle class_loader,
+                                                       Handle url, TRAPS);
+  static Handle get_shared_protection_domain(Handle class_loader,
+                                             int shared_path_index,
+                                             Handle url,
+                                             TRAPS);
+  static Handle get_shared_protection_domain(Handle class_loader,
+                                             ModuleEntry* mod, TRAPS);
+  static Handle init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS);
+
+  static void atomic_set_array_index(objArrayOop array, int index, oop o) {
+    // Benign race condition:  array.obj_at(index) may already be filled in.
+    // The important thing here is that all threads pick up the same result.
+    // It doesn't matter which racing thread wins, as long as only one
+    // result is used by all threads, and all future queries.
+    array->atomic_compare_exchange_oop(index, o, NULL);
+  }
+
+  static oop shared_protection_domain(int index);
+  static void atomic_set_shared_protection_domain(int index, oop pd) {
+    atomic_set_array_index(_shared_protection_domains, index, pd);
+  }
+  static void allocate_shared_protection_domain_array(int size, TRAPS);
+  static oop shared_jar_url(int index);
+  static void atomic_set_shared_jar_url(int index, oop url) {
+    atomic_set_array_index(_shared_jar_urls, index, url);
+  }
+  static void allocate_shared_jar_url_array(int size, TRAPS);
+  static oop shared_jar_manifest(int index);
+  static void atomic_set_shared_jar_manifest(int index, oop man) {
+    atomic_set_array_index(_shared_jar_manifests, index, man);
+  }
+  static void allocate_shared_jar_manifest_array(int size, TRAPS);
+  static InstanceKlass* acquire_class_for_current_thread(
+                                 InstanceKlass *ik,
+                                 Handle class_loader,
+                                 Handle protection_domain,
+                                 TRAPS);
+
+public:
+  static void initialize(TRAPS);
+
+  // Called by PLATFORM/APP loader only
   static InstanceKlass* find_or_load_shared_class(Symbol* class_name,
-                                                  Handle class_loader,
-                                                  TRAPS) {
-    return NULL;
+                                               Handle class_loader,
+                                               TRAPS);
+
+
+  static void allocate_shared_data_arrays(int size, TRAPS);
+  static void oops_do(OopClosure* f);
+  static void roots_oops_do(OopClosure* f) {
+    oops_do(f);
   }
-  static void roots_oops_do(OopClosure* blk) {}
-  static void oops_do(OopClosure* f) {}
+
+  // Check if sharing is supported for the class loader.
   static bool is_sharing_possible(ClassLoaderData* loader_data) {
     oop class_loader = loader_data->class_loader();
-    return (class_loader == NULL);
+    return (class_loader == NULL ||
+            (UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader) ||
+                           SystemDictionary::is_platform_class_loader(class_loader)))
+            );
   }
-  static bool is_shared_class_visible_for_classloader(
-                                      InstanceKlass* ik,
-                                      Handle class_loader,
-                                      const char* pkg_string,
-                                      Symbol* pkg_name,
-                                      PackageEntry* pkg_entry,
-                                      ModuleEntry* mod_entry,
-                                      TRAPS) {
-    return false;
+  static bool is_shared_class_visible_for_classloader(InstanceKlass* ik,
+                                                      Handle class_loader,
+                                                      const char* pkg_string,
+                                                      Symbol* pkg_name,
+                                                      PackageEntry* pkg_entry,
+                                                      ModuleEntry* mod_entry,
+                                                      TRAPS);
+  static PackageEntry* get_package_entry(Symbol* pkg,
+                                         ClassLoaderData *loader_data) {
+    if (loader_data != NULL) {
+      PackageEntryTable* pkgEntryTable = loader_data->packages();
+      return pkgEntryTable->lookup_only(pkg);
+    }
+    return NULL;
   }
 
+  static bool add_non_builtin_klass(Symbol* class_name, ClassLoaderData* loader_data,
+                                    InstanceKlass* k, TRAPS);
   static Klass* dump_time_resolve_super_or_fail(Symbol* child_name,
                                                 Symbol* class_name,
                                                 Handle class_loader,
                                                 Handle protection_domain,
                                                 bool is_superclass,
-                                                TRAPS) {
-    return NULL;
-  }
+                                                TRAPS);
 
   static size_t dictionary_entry_size() {
-    return sizeof(DictionaryEntry);
+    return (DumpSharedSpaces) ? sizeof(SharedDictionaryEntry) : sizeof(DictionaryEntry);
+  }
+  static void init_shared_dictionary_entry(Klass* k, DictionaryEntry* entry) NOT_CDS_RETURN;
+  static bool is_builtin(DictionaryEntry* ent) {
+    // Can't use virtual function is_builtin because DictionaryEntry doesn't initialize
+    // vtable because it's not constructed properly.
+    SharedDictionaryEntry* entry = (SharedDictionaryEntry*)ent;
+    return entry->is_builtin();
   }
 
-  static void init_shared_dictionary_entry(Klass* k, DictionaryEntry* entry) {}
-  static bool is_builtin(DictionaryEntry* entry) { return true; }
+  // For convenient access to the SharedDictionaryEntry's of the archived classes.
+  static SharedDictionary* shared_dictionary() {
+    assert(!DumpSharedSpaces, "not for dumping");
+    return (SharedDictionary*)SystemDictionary::shared_dictionary();
+  }
+
+  static SharedDictionary* boot_loader_dictionary() {
+    return (SharedDictionary*)ClassLoaderData::the_null_class_loader_data()->dictionary();
+  }
 
-  static InstanceKlass* lookup_from_stream(Symbol* class_name,
+  static void update_shared_entry(Klass* klass, int id) {
+    assert(DumpSharedSpaces, "sanity");
+    assert((SharedDictionary*)(klass->class_loader_data()->dictionary()) != NULL, "sanity");
+    ((SharedDictionary*)(klass->class_loader_data()->dictionary()))->update_entry(klass, id);
+  }
+
+  static void set_shared_class_misc_info(Klass* k, ClassFileStream* cfs);
+
+  static InstanceKlass* lookup_from_stream(const Symbol* class_name,
                                            Handle class_loader,
                                            Handle protection_domain,
                                            const ClassFileStream* st,
-                                           TRAPS) {
-    return NULL;
-  }
-
-  // The (non-application) CDS implementation supports only classes in the boot
-  // class loader, which ensures that the verification constraints are the same
-  // during archive creation time and runtime. Thus we can do the constraint checks
-  // entirely during archive creation time.
+                                           TRAPS);
+  // "verification_constraints" are a set of checks performed by
+  // VerificationType::is_reference_assignable_from when verifying a shared class during
+  // dump time.
+  //
+  // With AppCDS, it is possible to override archived classes by calling
+  // ClassLoader.defineClass() directly. SystemDictionary::load_shared_class() already
+  // ensures that you cannot load a shared class if its super type(s) are changed. However,
+  // we need an additional check to ensure that the verification_constraints did not change
+  // between dump time and runtime.
   static bool add_verification_constraint(Klass* k, Symbol* name,
                   Symbol* from_name, bool from_field_is_protected,
-                  bool from_is_array, bool from_is_object) {return false;}
-  static void finalize_verification_constraints() {}
+                  bool from_is_array, bool from_is_object) NOT_CDS_RETURN_(false);
+  static void finalize_verification_constraints() NOT_CDS_RETURN;
   static void check_verification_constraints(InstanceKlass* klass,
-                                              TRAPS) {}
-};
-
-class SharedDictionaryEntry : public DictionaryEntry {
-public:
-  void metaspace_pointers_do(MetaspaceClosure* it) {}
+                                              TRAPS) NOT_CDS_RETURN;
 };
 
 #endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
--- a/src/hotspot/share/classfile/systemDictionary_ext.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/systemDictionary_ext.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017 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
@@ -25,6 +25,17 @@
 #ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
 #define SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
 
+#if INCLUDE_CDS
+
+#define WK_KLASSES_DO_EXT(do_klass) \
+  /* well-known classes */                                                                                            \
+  do_klass(jdk_internal_loader_ClassLoaders_klass,         jdk_internal_loader_ClassLoaders,            Pre )         \
+  /*end*/
+
+#else
+
 #define WK_KLASSES_DO_EXT(do_klass)
 
+#endif // INCLUDE_CDS
+
 #endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,7 +26,6 @@
 #define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
 
 #include "classfile/moduleEntry.hpp"
-#include "classfile/vmSymbols_ext.hpp"
 #include "oops/symbol.hpp"
 #include "memory/iterator.hpp"
 #include "trace/traceMacros.hpp"
@@ -673,8 +672,12 @@
   /* trace signatures */                                                                                          \
   TRACE_TEMPLATES(template)                                                                                       \
                                                                                                                   \
-  /* extensions */                                                                                                \
-  VM_SYMBOLS_DO_EXT(template, do_alias)                                                                           \
+  /* cds */                                                                                                       \
+  template(jdk_internal_loader_ClassLoaders,       "jdk/internal/loader/ClassLoaders")                            \
+  template(jdk_vm_cds_SharedClassInfo,             "jdk/vm/cds/SharedClassInfo")                                  \
+  template(url_void_signature,                     "(Ljava/net/URL;)V")                                           \
+  template(toFileURL_name,                         "toFileURL")                                                   \
+  template(toFileURL_signature,                    "(Ljava/lang/String;)Ljava/net/URL;")                          \
                                                                                                                   \
   /*end*/
 
--- a/src/hotspot/share/classfile/vmSymbols_ext.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- *
- */
-
-#ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_EXT_HPP
-#define SHARE_VM_CLASSFILE_VMSYMBOLS_EXT_HPP
-
-#define VM_SYMBOLS_DO_EXT(template, do_alias)
-
-#endif // SHARE_VM_CLASSFILE_VMSYMBOLS_EXT_HPP
-
--- a/src/hotspot/share/code/codeCache.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/codeCache.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -259,12 +259,12 @@
   }
 
   // We do not need the profiled CodeHeap, use all space for the non-profiled CodeHeap
-  if(!heap_available(CodeBlobType::MethodProfiled)) {
+  if (!heap_available(CodeBlobType::MethodProfiled)) {
     non_profiled_size += profiled_size;
     profiled_size = 0;
   }
   // We do not need the non-profiled CodeHeap, use all space for the non-nmethod CodeHeap
-  if(!heap_available(CodeBlobType::MethodNonProfiled)) {
+  if (!heap_available(CodeBlobType::MethodNonProfiled)) {
     non_nmethod_size += non_profiled_size;
     non_profiled_size = 0;
   }
@@ -282,10 +282,11 @@
   FLAG_SET_ERGO(uintx, ProfiledCodeHeapSize, profiled_size);
   FLAG_SET_ERGO(uintx, NonProfiledCodeHeapSize, non_profiled_size);
 
-  // Align CodeHeaps
-  size_t alignment = heap_alignment();
+  // If large page support is enabled, align code heaps according to large
+  // page size to make sure that code cache is covered by large pages.
+  const size_t alignment = MAX2(page_size(false), (size_t) os::vm_allocation_granularity());
   non_nmethod_size = align_up(non_nmethod_size, alignment);
-  profiled_size   = align_down(profiled_size, alignment);
+  profiled_size    = align_down(profiled_size, alignment);
 
   // Reserve one continuous chunk of memory for CodeHeaps and split it into
   // parts for the individual heaps. The memory layout looks like this:
@@ -308,37 +309,29 @@
   add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", CodeBlobType::MethodNonProfiled);
 }
 
-size_t CodeCache::heap_alignment() {
-  // If large page support is enabled, align code heaps according to large
-  // page size to make sure that code cache is covered by large pages.
-  const size_t page_size = os::can_execute_large_page_memory() ?
-             os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8) :
-             os::vm_page_size();
-  return MAX2(page_size, (size_t) os::vm_allocation_granularity());
+size_t CodeCache::page_size(bool aligned) {
+  if (os::can_execute_large_page_memory()) {
+    return aligned ? os::page_size_for_region_aligned(ReservedCodeCacheSize, 8) :
+                     os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8);
+  } else {
+    return os::vm_page_size();
+  }
 }
 
 ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
-  // Determine alignment
-  const size_t page_size = os::can_execute_large_page_memory() ?
-          MIN2(os::page_size_for_region_aligned(InitialCodeCacheSize, 8),
-               os::page_size_for_region_aligned(size, 8)) :
-          os::vm_page_size();
-  const size_t granularity = os::vm_allocation_granularity();
-  const size_t r_align = MAX2(page_size, granularity);
-  const size_t r_size = align_up(size, r_align);
-  const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 :
-    MAX2(page_size, granularity);
-
-  ReservedCodeSpace rs(r_size, rs_align, rs_align > 0);
-
+  // Align and reserve space for code cache
+  const size_t rs_ps = page_size();
+  const size_t rs_align = MAX2(rs_ps, (size_t) os::vm_allocation_granularity());
+  const size_t rs_size = align_up(size, rs_align);
+  ReservedCodeSpace rs(rs_size, rs_align, rs_ps > (size_t) os::vm_page_size());
   if (!rs.is_reserved()) {
-    vm_exit_during_initialization("Could not reserve enough space for code cache");
+    vm_exit_during_initialization(err_msg("Could not reserve enough space for code cache (" SIZE_FORMAT "K)",
+                                          rs_size/K));
   }
 
   // Initialize bounds
   _low_bound = (address)rs.base();
   _high_bound = _low_bound + rs.size();
-
   return rs;
 }
 
@@ -415,7 +408,8 @@
   size_t size_initial = MIN2(InitialCodeCacheSize, rs.size());
   size_initial = align_up(size_initial, os::vm_page_size());
   if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) {
-    vm_exit_during_initialization("Could not reserve enough space for code cache");
+    vm_exit_during_initialization(err_msg("Could not reserve enough space in %s (" SIZE_FORMAT "K)",
+                                          heap->name(), size_initial/K));
   }
 
   // Register the CodeHeap
--- a/src/hotspot/share/code/codeCache.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/codeCache.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -107,7 +107,7 @@
   static CodeHeap* get_code_heap(int code_blob_type);         // Returns the CodeHeap for the given CodeBlobType
   // Returns the name of the VM option to set the size of the corresponding CodeHeap
   static const char* get_code_heap_flag_name(int code_blob_type);
-  static size_t heap_alignment();                             // Returns the alignment of the CodeHeaps in bytes
+  static size_t page_size(bool aligned = true);               // Returns the page size used by the CodeCache
   static ReservedCodeSpace reserve_heap_memory(size_t size);  // Reserves one continuous chunk of memory for the CodeHeaps
 
   // Iteration
--- a/src/hotspot/share/code/debugInfo.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/debugInfo.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,8 @@
 #include "code/nmethod.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/thread.hpp"
 
 // Constructors
 
@@ -209,14 +211,24 @@
 // ConstantOopWriteValue
 
 void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
-  assert(JNIHandles::resolve(value()) == NULL ||
-         Universe::heap()->is_in_reserved(JNIHandles::resolve(value())),
-         "Should be in heap");
+#ifdef ASSERT
+  {
+    // cannot use ThreadInVMfromNative here since in case of JVMCI compiler,
+    // thread is already in VM state.
+    ThreadInVMfromUnknown tiv;
+    assert(JNIHandles::resolve(value()) == NULL ||
+           Universe::heap()->is_in_reserved(JNIHandles::resolve(value())),
+           "Should be in heap");
+ }
+#endif
   stream->write_int(CONSTANT_OOP_CODE);
   stream->write_handle(value());
 }
 
 void ConstantOopWriteValue::print_on(outputStream* st) const {
+  // using ThreadInVMfromUnknown here since in case of JVMCI compiler,
+  // thread is already in VM state.
+  ThreadInVMfromUnknown tiv;
   JNIHandles::resolve(value())->print_value_on(st);
 }
 
--- a/src/hotspot/share/code/nmethod.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/nmethod.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -438,14 +438,14 @@
                                             basic_lock_sp_offset, oop_maps);
     NOT_PRODUCT(if (nm != NULL)  native_nmethod_stats.note_native_nmethod(nm));
   }
-  // verify nmethod
-  debug_only(if (nm) nm->verify();) // might block
 
   if (nm != NULL) {
+    // verify nmethod
+    debug_only(nm->verify();) // might block
+
     nm->log_new_nmethod();
+    nm->make_in_use();
   }
-
-  nm->make_in_use();
   return nm;
 }
 
--- a/src/hotspot/share/code/nmethod.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/nmethod.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -124,7 +124,7 @@
   bool _unload_reported;
 
   // Protected by Patching_lock
-  volatile char _state;             // {not_installed, in_use, not_entrant, zombie, unloaded}
+  volatile signed char _state;               // {not_installed, in_use, not_entrant, zombie, unloaded}
 
 #ifdef ASSERT
   bool _oops_are_stale;  // indicates that it's no longer safe to access oops section
--- a/src/hotspot/share/code/stubs.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/stubs.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -78,7 +78,6 @@
   _queue_begin     = 0;
   _queue_end       = 0;
   _number_of_stubs = 0;
-  register_queue(this);
 }
 
 
@@ -205,36 +204,6 @@
 }
 
 
-enum { StubQueueLimit = 10 };  // there are only a few in the world
-static StubQueue* registered_stub_queues[StubQueueLimit];
-
-void StubQueue::register_queue(StubQueue* sq) {
-  for (int i = 0; i < StubQueueLimit; i++) {
-    if (registered_stub_queues[i] == NULL) {
-      registered_stub_queues[i] = sq;
-      return;
-    }
-  }
-  ShouldNotReachHere();
-}
-
-
-void StubQueue::queues_do(void f(StubQueue* sq)) {
-  for (int i = 0; i < StubQueueLimit; i++) {
-    if (registered_stub_queues[i] != NULL) {
-      f(registered_stub_queues[i]);
-    }
-  }
-}
-
-
-void StubQueue::stubs_do(void f(Stub* s)) {
-  debug_only(verify();)
-  MutexLockerEx lock(_mutex);
-  for (Stub* s = first(); s != NULL; s = next(s)) f(s);
-}
-
-
 void StubQueue::verify() {
   // verify only if initialized
   if (_stub_buffer == NULL) return;
--- a/src/hotspot/share/code/stubs.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/code/stubs.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -172,8 +172,6 @@
   void  stub_verify(Stub* s)                     { _stub_interface->verify(s); }
   void  stub_print(Stub* s)                      { _stub_interface->print(s); }
 
-  static void register_queue(StubQueue*);
-
  public:
   StubQueue(StubInterface* stub_interface, int buffer_size, Mutex* lock,
             const char* name);
@@ -204,8 +202,6 @@
   void deallocate_unused_tail();                 // deallocate the unused tail of the underlying CodeBlob
                                                  // only used from TemplateInterpreter::initialize()
   // Iteration
-  static void queues_do(void f(StubQueue* s));   // call f with each StubQueue
-  void  stubs_do(void f(Stub* s));               // call f with all stubs
   Stub* first() const                            { return number_of_stubs() > 0 ? stub_at(_queue_begin) : NULL; }
   Stub* next(Stub* s) const                      { int i = index_of(s) + stub_size(s);
                                                    // Only wrap around in the non-contiguous case (see stubss.cpp)
@@ -213,9 +209,6 @@
                                                    return (i == _queue_end) ? NULL : stub_at(i);
                                                  }
 
-  address stub_code_begin(Stub* s) const         { return _stub_interface->code_begin(s); }
-  address stub_code_end(Stub* s) const           { return _stub_interface->code_end(s);   }
-
   // Debugging/printing
   void  verify();                                // verifies the stub queue
   void  print();                                 // prints information about the stub queue
--- a/src/hotspot/share/compiler/compileTask.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/compiler/compileTask.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,10 +25,10 @@
 #ifndef SHARE_VM_COMPILER_COMPILETASK_HPP
 #define SHARE_VM_COMPILER_COMPILETASK_HPP
 
+#include "ci/ciMethod.hpp"
 #include "code/nmethod.hpp"
-#include "ci/ciMethod.hpp"
 #include "compiler/compileLog.hpp"
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "utilities/xmlstream.hpp"
 
 // CompileTask
--- a/src/hotspot/share/compiler/methodMatcher.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/compiler/methodMatcher.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_COMPILER_METHODMATCHER_HPP
 #define SHARE_VM_COMPILER_METHODMATCHER_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/handles.inline.hpp"
 #include "memory/resourceArea.hpp"
 
--- a/src/hotspot/share/compiler/oopMap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/compiler/oopMap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 #include "code/compressedStream.hpp"
 #include "code/vmreg.hpp"
 #include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
 #include "utilities/growableArray.hpp"
 
 // Interface for generating the frame map for compiled code.  A frame map
@@ -42,6 +43,7 @@
 class frame;
 class RegisterMap;
 class DerivedPointerEntry;
+class OopClosure;
 
 class OopMapValue: public StackObj {
   friend class VMStructs;
--- a/src/hotspot/share/gc/cms/allocationStats.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/allocationStats.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -30,3 +30,20 @@
 // Technically this should be derived from machine speed, and
 // ideally it would be dynamically adjusted.
 float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000;
+
+void AllocationStats::initialize(bool split_birth)   {
+  AdaptivePaddedAverage* dummy =
+    new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight,
+                                                       CMS_FLSPadding);
+  _desired = 0;
+  _coal_desired = 0;
+  _surplus = 0;
+  _bfr_surp = 0;
+  _prev_sweep = 0;
+  _before_sweep = 0;
+  _coal_births = 0;
+  _coal_deaths = 0;
+  _split_births = (split_birth ? 1 : 0);
+  _split_deaths = 0;
+  _returned_bytes = 0;
+}
--- a/src/hotspot/share/gc/cms/allocationStats.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/allocationStats.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -64,22 +64,7 @@
   ssize_t     _split_deaths;     // loss from splitting
   size_t      _returned_bytes;   // number of bytes returned to list.
  public:
-  void initialize(bool split_birth = false) {
-    AdaptivePaddedAverage* dummy =
-      new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight,
-                                                         CMS_FLSPadding);
-    _desired = 0;
-    _coal_desired = 0;
-    _surplus = 0;
-    _bfr_surp = 0;
-    _prev_sweep = 0;
-    _before_sweep = 0;
-    _coal_births = 0;
-    _coal_deaths = 0;
-    _split_births = (split_birth ? 1 : 0);
-    _split_deaths = 0;
-    _returned_bytes = 0;
-  }
+  void initialize(bool split_birth = false);
 
   AllocationStats() {
     initialize();
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -71,6 +71,6 @@
 }
 
 void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
-  // initialize the policy counters - 2 collectors, 3 generations
-  _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3);
+  // initialize the policy counters - 2 collectors, 2 generations
+  _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 2);
 }
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,17 +23,48 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/cms/compactibleFreeListSpace.hpp"
+#include "gc/cms/concurrentMarkSweepGeneration.hpp"
 #include "gc/cms/concurrentMarkSweepThread.hpp"
 #include "gc/cms/cmsHeap.hpp"
+#include "gc/cms/parNewGeneration.hpp"
 #include "gc/cms/vmCMSOperations.hpp"
+#include "gc/shared/genMemoryPools.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/memoryManager.hpp"
 #include "utilities/stack.inline.hpp"
 
-CMSHeap::CMSHeap(GenCollectorPolicy *policy) : GenCollectedHeap(policy) {
+class CompactibleFreeListSpacePool : public CollectedMemoryPool {
+private:
+  CompactibleFreeListSpace* _space;
+public:
+  CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
+                               const char* name,
+                               size_t max_size,
+                               bool support_usage_threshold) :
+    CollectedMemoryPool(name, space->capacity(), max_size, support_usage_threshold),
+    _space(space) {
+  }
+
+  MemoryUsage get_memory_usage() {
+    size_t max_heap_size   = (available_for_allocation() ? max_size() : 0);
+    size_t used      = used_in_bytes();
+    size_t committed = _space->capacity();
+
+    return MemoryUsage(initial_size(), used, committed, max_heap_size);
+  }
+
+  size_t used_in_bytes() {
+    return _space->used();
+  }
+};
+
+CMSHeap::CMSHeap(GenCollectorPolicy *policy) :
+  GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
   _workers = new WorkGang("GC Thread", ParallelGCThreads,
                           /* are_GC_task_threads */true,
                           /* are_ConcurrentGC_threads */false);
@@ -54,6 +85,38 @@
   return JNI_OK;
 }
 
+void CMSHeap::initialize_serviceability() {
+  _young_manager = new GCMemoryManager("ParNew", "end of minor GC");
+  _old_manager = new GCMemoryManager("ConcurrentMarkSweep", "end of major GC");
+
+  ParNewGeneration* young = (ParNewGeneration*) young_gen();
+  _eden_pool = new ContiguousSpacePool(young->eden(),
+                                       "Par Eden Space",
+                                       young->max_eden_size(),
+                                       false);
+
+  _survivor_pool = new SurvivorContiguousSpacePool(young,
+                                                   "Par Survivor Space",
+                                                   young->max_survivor_size(),
+                                                   false);
+
+  ConcurrentMarkSweepGeneration* old = (ConcurrentMarkSweepGeneration*) old_gen();
+  _old_pool = new CompactibleFreeListSpacePool(old->cmsSpace(),
+                                               "CMS Old Gen",
+                                               old->reserved().byte_size(),
+                                               true);
+
+  _young_manager->add_pool(_eden_pool);
+  _young_manager->add_pool(_survivor_pool);
+  young->set_gc_manager(_young_manager);
+
+  _old_manager->add_pool(_eden_pool);
+  _old_manager->add_pool(_survivor_pool);
+  _old_manager->add_pool(_old_pool);
+  old ->set_gc_manager(_old_manager);
+
+}
+
 void CMSHeap::check_gen_kinds() {
   assert(young_gen()->kind() == Generation::ParNew,
          "Wrong youngest generation type");
@@ -183,3 +246,18 @@
   GenCollectedHeap::gc_epilogue(full);
   always_do_update_barrier = true;
 };
+
+GrowableArray<GCMemoryManager*> CMSHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(_young_manager);
+  memory_managers.append(_old_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> CMSHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -29,9 +29,12 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
+#include "utilities/growableArray.hpp"
 
 class CLDClosure;
 class GenCollectorPolicy;
+class GCMemoryManager;
+class MemoryPool;
 class OopsInGenClosure;
 class outputStream;
 class StrongRootsScope;
@@ -80,6 +83,9 @@
   void safepoint_synchronize_begin();
   void safepoint_synchronize_end();
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   // If "young_gen_as_roots" is false, younger generations are
   // not scanned as roots; in this case, the caller must be arranging to
   // scan the younger generations itself.  (For example, a generation might
@@ -92,12 +98,19 @@
                          OopsInGenClosure* root_closure,
                          CLDClosure* cld_closure);
 
+  GCMemoryManager* old_manager() const { return _old_manager; }
+
 private:
   WorkGang* _workers;
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
 
   virtual void gc_prologue(bool full);
   virtual void gc_epilogue(bool full);
 
+  virtual void initialize_serviceability();
+
   // Accessor for memory state verification support
   NOT_PRODUCT(
     virtual size_t skip_header_HeapWords() { return CMSCollector::skip_header_HeapWords(); }
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -8116,42 +8116,42 @@
 }
 
 TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorState phase, GCCause::Cause cause): TraceMemoryManagerStats() {
-
+  GCMemoryManager* manager = CMSHeap::heap()->old_manager();
   switch (phase) {
     case CMSCollector::InitialMarking:
-      initialize(true  /* fullGC */ ,
-                 cause /* cause of the GC */,
-                 true  /* recordGCBeginTime */,
-                 true  /* recordPreGCUsage */,
-                 false /* recordPeakUsage */,
-                 false /* recordPostGCusage */,
-                 true  /* recordAccumulatedGCTime */,
-                 false /* recordGCEndTime */,
-                 false /* countCollection */  );
+      initialize(manager /* GC manager */ ,
+                 cause   /* cause of the GC */,
+                 true    /* recordGCBeginTime */,
+                 true    /* recordPreGCUsage */,
+                 false   /* recordPeakUsage */,
+                 false   /* recordPostGCusage */,
+                 true    /* recordAccumulatedGCTime */,
+                 false   /* recordGCEndTime */,
+                 false   /* countCollection */  );
       break;
 
     case CMSCollector::FinalMarking:
-      initialize(true  /* fullGC */ ,
-                 cause /* cause of the GC */,
-                 false /* recordGCBeginTime */,
-                 false /* recordPreGCUsage */,
-                 false /* recordPeakUsage */,
-                 false /* recordPostGCusage */,
-                 true  /* recordAccumulatedGCTime */,
-                 false /* recordGCEndTime */,
-                 false /* countCollection */  );
+      initialize(manager /* GC manager */ ,
+                 cause   /* cause of the GC */,
+                 false   /* recordGCBeginTime */,
+                 false   /* recordPreGCUsage */,
+                 false   /* recordPeakUsage */,
+                 false   /* recordPostGCusage */,
+                 true    /* recordAccumulatedGCTime */,
+                 false   /* recordGCEndTime */,
+                 false   /* countCollection */  );
       break;
 
     case CMSCollector::Sweeping:
-      initialize(true  /* fullGC */ ,
-                 cause /* cause of the GC */,
-                 false /* recordGCBeginTime */,
-                 false /* recordPreGCUsage */,
-                 true  /* recordPeakUsage */,
-                 true  /* recordPostGCusage */,
-                 false /* recordAccumulatedGCTime */,
-                 true  /* recordGCEndTime */,
-                 true  /* countCollection */  );
+      initialize(manager /* GC manager */ ,
+                 cause   /* cause of the GC */,
+                 false   /* recordGCBeginTime */,
+                 false   /* recordPreGCUsage */,
+                 true    /* recordPeakUsage */,
+                 true    /* recordPostGCusage */,
+                 false   /* recordAccumulatedGCTime */,
+                 true    /* recordGCEndTime */,
+                 true    /* countCollection */  );
       break;
 
     default:
--- a/src/hotspot/share/gc/cms/gSpaceCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/gSpaceCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/cms/gSpaceCounters.hpp"
 #include "gc/shared/generation.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "utilities/macros.hpp"
 
@@ -71,3 +72,7 @@
                                      _gen->capacity(), CHECK);
   }
 }
+
+GSpaceCounters::~GSpaceCounters() {
+  if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+}
--- a/src/hotspot/share/gc/cms/gSpaceCounters.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/cms/gSpaceCounters.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -52,9 +52,7 @@
   GSpaceCounters(const char* name, int ordinal, size_t max_size, Generation* g,
                  GenerationCounters* gc, bool sampled=true);
 
-  ~GSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
+  ~GSpaceCounters();
 
   inline void update_capacity() {
     _capacity->set_value(_gen->capacity());
--- a/src/hotspot/share/gc/g1/dirtyCardQueue.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/dirtyCardQueue.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 
 // Closure used for updating remembered sets and recording references that
 // point into the collection set while the mutator is running.
@@ -319,7 +320,7 @@
   clear();
   // Since abandon is done only at safepoints, we can safely manipulate
   // these queues.
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->dirty_card_queue().reset();
   }
   shared_dirty_card_queue()->reset();
@@ -338,7 +339,7 @@
   int save_max_completed_queue = _max_completed_queue;
   _max_completed_queue = max_jint;
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     concatenate_log(t->dirty_card_queue());
   }
   concatenate_log(_shared_dirty_card_queue);
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #include "gc/g1/g1Arguments.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
 #include "runtime/globals.hpp"
@@ -92,6 +93,22 @@
   }
 
   log_trace(gc)("MarkStackSize: %uk  MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
+
+#ifdef COMPILER2
+  // Enable loop strip mining to offer better pause time guarantees
+  if (FLAG_IS_DEFAULT(UseCountedLoopSafepoints)) {
+    FLAG_SET_DEFAULT(UseCountedLoopSafepoints, true);
+  }
+  if (UseCountedLoopSafepoints && FLAG_IS_DEFAULT(LoopStripMiningIter)) {
+    FLAG_SET_DEFAULT(LoopStripMiningIter, 1000);
+  }
+#endif
+}
+
+bool G1Arguments::parse_verification_type(const char* type) {
+  G1CollectedHeap::heap()->verifier()->parse_verification_type(type);
+  // Always return true because we want to parse all values.
+  return true;
 }
 
 CollectedHeap* G1Arguments::create_heap() {
--- a/src/hotspot/share/gc/g1/g1Arguments.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1Arguments.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 class G1Arguments : public GCArguments {
 public:
   virtual void initialize_flags();
+  virtual bool parse_verification_type(const char* type);
   virtual size_t conservative_max_heap_alignment();
   virtual CollectedHeap* create_heap();
 };
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -39,12 +39,12 @@
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1FullCollector.hpp"
-#include "gc/g1/g1FullGCScope.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HeapSizingPolicy.hpp"
 #include "gc/g1/g1HeapTransition.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
+#include "gc/g1/g1MemoryPool.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
 #include "gc/g1/g1Policy.hpp"
@@ -81,6 +81,7 @@
 #include "runtime/atomic.hpp"
 #include "runtime/init.hpp"
 #include "runtime/orderAccess.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -1083,7 +1084,6 @@
     PostCompactionPrinterClosure cl(hr_printer());
     heap_region_iterate(&cl);
   }
-
 }
 
 void G1CollectedHeap::abort_concurrent_cycle() {
@@ -1132,7 +1132,7 @@
   assert(!GCCause::is_user_requested_gc(gc_cause()) || explicit_gc, "invariant");
   assert(used() == recalculate_used(), "Should be equal");
   _verifier->verify_region_sets_optional();
-  _verifier->verify_before_gc();
+  _verifier->verify_before_gc(G1HeapVerifier::G1VerifyFull);
   _verifier->check_bitmaps("Full GC Start");
 }
 
@@ -1173,7 +1173,7 @@
   check_gc_time_stamps();
   _hrm.verify_optional();
   _verifier->verify_region_sets_optional();
-  _verifier->verify_after_gc();
+  _verifier->verify_after_gc(G1HeapVerifier::G1VerifyFull);
   // Clear the previous marking bitmap, if needed for bitmap verification.
   // Note we cannot do this when we clear the next marking bitmap in
   // G1ConcurrentMark::abort() above since VerifyDuringGC verifies the
@@ -1217,34 +1217,6 @@
 #endif
 }
 
-void G1CollectedHeap::do_full_collection_inner(G1FullGCScope* scope) {
-  GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
-  g1_policy()->record_full_collection_start();
-
-  print_heap_before_gc();
-  print_heap_regions();
-
-  abort_concurrent_cycle();
-  verify_before_full_collection(scope->is_explicit_gc());
-
-  gc_prologue(true);
-  prepare_heap_for_full_collection();
-
-  G1FullCollector collector(scope, ref_processor_stw(), concurrent_mark()->next_mark_bitmap(), workers()->active_workers());
-  collector.prepare_collection();
-  collector.collect();
-  collector.complete_collection();
-
-  prepare_heap_for_mutators();
-
-  g1_policy()->record_full_collection_end();
-  gc_epilogue(true);
-
-  verify_after_full_collection();
-
-  print_heap_after_full_collection(scope->heap_transition());
-}
-
 bool G1CollectedHeap::do_full_collection(bool explicit_gc,
                                          bool clear_all_soft_refs) {
   assert_at_safepoint(true /* should_be_vm_thread */);
@@ -1257,8 +1229,12 @@
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
       collector_policy()->should_clear_all_soft_refs();
 
-  G1FullGCScope scope(explicit_gc, do_clear_all_soft_refs);
-  do_full_collection_inner(&scope);
+  G1FullCollector collector(this, &_full_gc_memory_manager, explicit_gc, do_clear_all_soft_refs);
+  GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
+
+  collector.prepare_collection();
+  collector.collect();
+  collector.complete_collection();
 
   // Full collection was successfully completed.
   return true;
@@ -1550,6 +1526,11 @@
   CollectedHeap(),
   _young_gen_sampling_thread(NULL),
   _collector_policy(collector_policy),
+  _memory_manager("G1 Young Generation", "end of minor GC"),
+  _full_gc_memory_manager("G1 Old Generation", "end of major GC"),
+  _eden_pool(NULL),
+  _survivor_pool(NULL),
+  _old_pool(NULL),
   _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()),
   _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
   _g1_policy(create_g1_policy(_gc_timer_stw)),
@@ -1854,6 +1835,20 @@
   return JNI_OK;
 }
 
+void G1CollectedHeap::initialize_serviceability() {
+  _eden_pool = new G1EdenPool(this);
+  _survivor_pool = new G1SurvivorPool(this);
+  _old_pool = new G1OldGenPool(this);
+
+  _full_gc_memory_manager.add_pool(_eden_pool);
+  _full_gc_memory_manager.add_pool(_survivor_pool);
+  _full_gc_memory_manager.add_pool(_old_pool);
+
+  _memory_manager.add_pool(_eden_pool);
+  _memory_manager.add_pool(_survivor_pool);
+
+}
+
 void G1CollectedHeap::stop() {
   // Stop all concurrent threads. We do this to make sure these threads
   // do not continue to execute and access resources (e.g. logging)
@@ -1879,6 +1874,7 @@
 }
 
 void G1CollectedHeap::post_initialize() {
+  CollectedHeap::post_initialize();
   ref_processing_init();
 }
 
@@ -2653,11 +2649,9 @@
 
 size_t G1CollectedHeap::pending_card_num() {
   size_t extra_cards = 0;
-  JavaThread *curr = Threads::first();
-  while (curr != NULL) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *curr = jtiwh.next(); ) {
     DirtyCardQueue& dcq = curr->dirty_card_queue();
     extra_cards += dcq.size();
-    curr = curr->next();
   }
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   size_t buffer_size = dcqs.buffer_size();
@@ -2963,13 +2957,17 @@
 
     GCTraceCPUTime tcpu;
 
+    G1HeapVerifier::G1VerifyType verify_type;
     FormatBuffer<> gc_string("Pause ");
     if (collector_state()->during_initial_mark_pause()) {
       gc_string.append("Initial Mark");
+      verify_type = G1HeapVerifier::G1VerifyInitialMark;
     } else if (collector_state()->gcs_are_young()) {
       gc_string.append("Young");
+      verify_type = G1HeapVerifier::G1VerifyYoungOnly;
     } else {
       gc_string.append("Mixed");
+      verify_type = G1HeapVerifier::G1VerifyMixed;
     }
     GCTraceTime(Info, gc) tm(gc_string, NULL, gc_cause(), true);
 
@@ -2980,7 +2978,7 @@
     log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
-    TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
+    TraceMemoryManagerStats tms(&_memory_manager, gc_cause());
 
     // If the secondary_free_list is not empty, append it to the
     // free_list. No need to wait for the cleanup operation to finish;
@@ -3010,7 +3008,7 @@
         heap_region_iterate(&v_cl);
       }
 
-      _verifier->verify_before_gc();
+      _verifier->verify_before_gc(verify_type);
 
       _verifier->check_bitmaps("GC Start");
 
@@ -3170,7 +3168,7 @@
           heap_region_iterate(&v_cl);
         }
 
-        _verifier->verify_after_gc();
+        _verifier->verify_after_gc(verify_type);
         _verifier->check_bitmaps("GC End");
 
         assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
@@ -5394,3 +5392,18 @@
   RebuildStrongCodeRootClosure blob_cl(this);
   CodeCache::blobs_do(&blob_cl);
 }
+
+GrowableArray<GCMemoryManager*> G1CollectedHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(&_memory_manager);
+  memory_managers.append(&_full_gc_memory_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> G1CollectedHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -42,14 +42,15 @@
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc/g1/g1SurvivorRegions.hpp"
 #include "gc/g1/g1YCTypes.hpp"
-#include "gc/g1/hSpaceCounters.hpp"
 #include "gc/g1/heapRegionManager.hpp"
 #include "gc/g1/heapRegionSet.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/plab.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "memory/memRegion.hpp"
+#include "services/memoryManager.hpp"
 #include "utilities/stack.hpp"
 
 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
@@ -64,6 +65,7 @@
 class G1ParScanThreadState;
 class G1ParScanThreadStateSet;
 class G1ParScanThreadState;
+class MemoryPool;
 class ObjectClosure;
 class SpaceClosure;
 class CompactibleSpaceClosure;
@@ -126,6 +128,7 @@
   friend class VM_G1IncCollectionPause;
   friend class VMStructs;
   friend class MutatorAllocRegion;
+  friend class G1FullCollector;
   friend class G1GCAllocRegion;
   friend class G1HeapVerifier;
 
@@ -148,6 +151,13 @@
   WorkGang* _workers;
   G1CollectorPolicy* _collector_policy;
 
+  GCMemoryManager _memory_manager;
+  GCMemoryManager _full_gc_memory_manager;
+
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
+
   static size_t _humongous_object_threshold_in_words;
 
   // The secondary free list which contains regions that have been
@@ -161,6 +171,8 @@
   // It keeps track of the humongous regions.
   HeapRegionSet _humongous_set;
 
+  virtual void initialize_serviceability();
+
   void eagerly_reclaim_humongous_regions();
   // Start a new incremental collection set for the next pause.
   void start_new_collection_set();
@@ -517,7 +529,6 @@
 private:
   // Internal helpers used during full GC to split it up to
   // increase readability.
-  void do_full_collection_inner(G1FullGCScope* scope);
   void abort_concurrent_cycle();
   void verify_before_full_collection(bool explicit_gc);
   void prepare_heap_for_full_collection();
@@ -1006,6 +1017,9 @@
   // Adaptive size policy.  No such thing for g1.
   virtual AdaptiveSizePolicy* size_policy() { return NULL; }
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   // The rem set and barrier set.
   G1RemSet* g1_rem_set() const { return _g1_rem_set; }
 
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1015,9 +1015,7 @@
   SvcGCMarker sgcm(SvcGCMarker::OTHER);
 
   if (VerifyDuringGC) {
-    HandleMark hm;  // handle scope
-    g1h->prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
+    g1h->verifier()->verify(G1HeapVerifier::G1VerifyRemark, VerifyOption_G1UsePrevMarking, "During GC (before)");
   }
   g1h->verifier()->check_bitmaps("Remark Start");
 
@@ -1038,9 +1036,7 @@
 
     // Verify the heap w.r.t. the previous marking bitmap.
     if (VerifyDuringGC) {
-      HandleMark hm;  // handle scope
-      g1h->prepare_for_verify();
-      Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (overflow)");
+      g1h->verifier()->verify(G1HeapVerifier::G1VerifyRemark, VerifyOption_G1UsePrevMarking, "During GC (overflow)");
     }
 
     // Clear the marking state because we will be restarting
@@ -1055,9 +1051,7 @@
                                        true /* expected_active */);
 
     if (VerifyDuringGC) {
-      HandleMark hm;  // handle scope
-      g1h->prepare_for_verify();
-      Universe::verify(VerifyOption_G1UseNextMarking, "During GC (after)");
+      g1h->verifier()->verify(G1HeapVerifier::G1VerifyRemark, VerifyOption_G1UseNextMarking, "During GC (after)");
     }
     g1h->verifier()->check_bitmaps("Remark End");
     assert(!restart_for_overflow(), "sanity");
@@ -1189,9 +1183,7 @@
   g1h->verifier()->verify_region_sets_optional();
 
   if (VerifyDuringGC) {
-    HandleMark hm;  // handle scope
-    g1h->prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
+    g1h->verifier()->verify(G1HeapVerifier::G1VerifyCleanup, VerifyOption_G1UsePrevMarking, "During GC (before)");
   }
   g1h->verifier()->check_bitmaps("Cleanup Start");
 
@@ -1263,9 +1255,7 @@
   Universe::update_heap_info_at_gc();
 
   if (VerifyDuringGC) {
-    HandleMark hm;  // handle scope
-    g1h->prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (after)");
+    g1h->verifier()->verify(G1HeapVerifier::G1VerifyCleanup, VerifyOption_G1UsePrevMarking, "During GC (after)");
   }
 
   g1h->verifier()->check_bitmaps("Cleanup End");
@@ -1756,28 +1746,24 @@
   G1ConcurrentMark* _cm;
 public:
   void work(uint worker_id) {
-    // Since all available tasks are actually started, we should
-    // only proceed if we're supposed to be active.
-    if (worker_id < _cm->active_tasks()) {
-      G1CMTask* task = _cm->task(worker_id);
-      task->record_start_time();
-      {
-        ResourceMark rm;
-        HandleMark hm;
-
-        G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
-        Threads::threads_do(&threads_f);
-      }
-
-      do {
-        task->do_marking_step(1000000000.0 /* something very large */,
-                              true         /* do_termination       */,
-                              false        /* is_serial            */);
-      } while (task->has_aborted() && !_cm->has_overflown());
-      // If we overflow, then we do not want to restart. We instead
-      // want to abort remark and do concurrent marking again.
-      task->record_end_time();
+    G1CMTask* task = _cm->task(worker_id);
+    task->record_start_time();
+    {
+      ResourceMark rm;
+      HandleMark hm;
+
+      G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
+      Threads::threads_do(&threads_f);
     }
+
+    do {
+      task->do_marking_step(1000000000.0 /* something very large */,
+                            true         /* do_termination       */,
+                            false        /* is_serial            */);
+    } while (task->has_aborted() && !_cm->has_overflown());
+    // If we overflow, then we do not want to restart. We instead
+    // want to abort remark and do concurrent marking again.
+    task->record_end_time();
   }
 
   G1CMRemarkTask(G1ConcurrentMark* cm, uint active_workers) :
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "logging/log.hpp"
+#include "memory/allocation.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/debug.hpp"
@@ -33,6 +34,107 @@
 #include "utilities/pair.hpp"
 #include <math.h>
 
+G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) {
+  G1ConcurrentRefineThread* result = NULL;
+  if (initializing || !InjectGCWorkerCreationFailure) {
+    result = new G1ConcurrentRefineThread(_cr, worker_id);
+  }
+  if (result == NULL || result->osthread() == NULL) {
+    log_warning(gc)("Failed to create refinement thread %u, no more %s",
+                    worker_id,
+                    result == NULL ? "memory" : "OS threads");
+  }
+  return result;
+}
+
+G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
+  _cr(NULL),
+  _threads(NULL),
+  _num_max_threads(0)
+{
+}
+
+G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
+  for (uint i = 0; i < _num_max_threads; i++) {
+    G1ConcurrentRefineThread* t = _threads[i];
+    if (t != NULL) {
+      delete t;
+    }
+  }
+  FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
+}
+
+jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint num_max_threads) {
+  assert(cr != NULL, "G1ConcurrentRefine must not be NULL");
+  _cr = cr;
+  _num_max_threads = num_max_threads;
+
+  _threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, num_max_threads, mtGC);
+  if (_threads == NULL) {
+    vm_shutdown_during_initialization("Could not allocate thread holder array.");
+    return JNI_ENOMEM;
+  }
+
+  for (uint i = 0; i < num_max_threads; i++) {
+    if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) {
+      _threads[i] = NULL;
+    } else {
+      _threads[i] = create_refinement_thread(i, true);
+      if (_threads[i] == NULL) {
+        vm_shutdown_during_initialization("Could not allocate refinement threads.");
+        return JNI_ENOMEM;
+      }
+    }
+  }
+  return JNI_OK;
+}
+
+void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) {
+  assert(cur_worker_id < _num_max_threads,
+         "Activating another thread from %u not allowed since there can be at most %u",
+         cur_worker_id, _num_max_threads);
+  if (cur_worker_id == (_num_max_threads - 1)) {
+    // Already the last thread, there is no more thread to activate.
+    return;
+  }
+
+  uint worker_id = cur_worker_id + 1;
+  G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
+  if (thread_to_activate == NULL) {
+    // Still need to create the thread...
+    _threads[worker_id] = create_refinement_thread(worker_id, false);
+    thread_to_activate = _threads[worker_id];
+  }
+  if (thread_to_activate != NULL && !thread_to_activate->is_active()) {
+    thread_to_activate->activate();
+  }
+}
+
+void G1ConcurrentRefineThreadControl::print_on(outputStream* st) const {
+  for (uint i = 0; i < _num_max_threads; ++i) {
+    if (_threads[i] != NULL) {
+      _threads[i]->print_on(st);
+      st->cr();
+    }
+  }
+}
+
+void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
+  for (uint i = 0; i < _num_max_threads; i++) {
+    if (_threads[i] != NULL) {
+      tc->do_thread(_threads[i]);
+    }
+  }
+}
+
+void G1ConcurrentRefineThreadControl::stop() {
+  for (uint i = 0; i < _num_max_threads; i++) {
+    if (_threads[i] != NULL) {
+      _threads[i]->stop();
+    }
+  }
+}
+
 // Arbitrary but large limits, to simplify some of the zone calculations.
 // The general idea is to allow expressions like
 //   MIN2(x OP y, max_XXX_zone)
@@ -96,7 +198,7 @@
                                   size_t yellow_zone,
                                   uint worker_i) {
   double yellow_size = yellow_zone - green_zone;
-  double step = yellow_size / G1ConcurrentRefine::thread_num();
+  double step = yellow_size / G1ConcurrentRefine::max_num_threads();
   if (worker_i == 0) {
     // Potentially activate worker 0 more aggressively, to keep
     // available buffers near green_zone value.  When yellow_size is
@@ -115,8 +217,7 @@
                                        size_t yellow_zone,
                                        size_t red_zone,
                                        size_t min_yellow_zone_size) :
-  _threads(NULL),
-  _n_worker_threads(thread_num()),
+  _thread_control(),
   _green_zone(green_zone),
   _yellow_zone(yellow_zone),
   _red_zone(red_zone),
@@ -125,9 +226,13 @@
   assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
 }
 
+jint G1ConcurrentRefine::initialize() {
+  return _thread_control.initialize(this, max_num_threads());
+}
+
 static size_t calc_min_yellow_zone_size() {
   size_t step = G1ConcRefinementThresholdStep;
-  uint n_workers = G1ConcurrentRefine::thread_num();
+  uint n_workers = G1ConcurrentRefine::max_num_threads();
   if ((max_yellow_zone / step) < n_workers) {
     return max_yellow_zone;
   } else {
@@ -191,77 +296,27 @@
     return NULL;
   }
 
-  cr->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, cr->_n_worker_threads, mtGC);
-  if (cr->_threads == NULL) {
-    *ecode = JNI_ENOMEM;
-    vm_shutdown_during_initialization("Could not allocate an array for G1ConcurrentRefineThread");
-    return NULL;
-  }
-
-  uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
-
-  G1ConcurrentRefineThread *next = NULL;
-  for (uint i = cr->_n_worker_threads - 1; i != UINT_MAX; i--) {
-    Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i);
-    G1ConcurrentRefineThread* t =
-      new G1ConcurrentRefineThread(cr,
-                                   next,
-                                   worker_id_offset,
-                                   i,
-                                   activation_level(thresholds),
-                                   deactivation_level(thresholds));
-    assert(t != NULL, "Conc refine should have been created");
-    if (t->osthread() == NULL) {
-      *ecode = JNI_ENOMEM;
-      vm_shutdown_during_initialization("Could not create G1ConcurrentRefineThread");
-      return NULL;
-    }
-
-    assert(t->cr() == cr, "Conc refine thread should refer to this");
-    cr->_threads[i] = t;
-    next = t;
-  }
-
-  *ecode = JNI_OK;
+  *ecode = cr->initialize();
   return cr;
 }
 
 void G1ConcurrentRefine::stop() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    _threads[i]->stop();
-  }
-}
-
-void G1ConcurrentRefine::update_thread_thresholds() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i);
-    _threads[i]->update_thresholds(activation_level(thresholds),
-                                   deactivation_level(thresholds));
-  }
+  _thread_control.stop();
 }
 
 G1ConcurrentRefine::~G1ConcurrentRefine() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    delete _threads[i];
-  }
-  FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
 }
 
 void G1ConcurrentRefine::threads_do(ThreadClosure *tc) {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    tc->do_thread(_threads[i]);
-  }
+  _thread_control.worker_threads_do(tc);
 }
 
-uint G1ConcurrentRefine::thread_num() {
+uint G1ConcurrentRefine::max_num_threads() {
   return G1ConcRefinementThreads;
 }
 
 void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
-  for (uint i = 0; i < _n_worker_threads; ++i) {
-    _threads[i]->print_on(st);
-    st->cr();
-  }
+  _thread_control.print_on(st);
 }
 
 static size_t calc_new_green_zone(size_t green,
@@ -326,16 +381,15 @@
 
   if (G1UseAdaptiveConcRefinement) {
     update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
-    update_thread_thresholds();
 
     // Change the barrier params
-    if (_n_worker_threads == 0) {
+    if (max_num_threads() == 0) {
       // Disable dcqs notification when there are no threads to notify.
       dcqs.set_process_completed_threshold(INT_MAX);
     } else {
       // Worker 0 is the primary; wakeup is via dcqs notification.
       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
-      size_t activate = _threads[0]->activation_threshold();
+      size_t activate = activation_threshold(0);
       dcqs.set_process_completed_threshold((int)activate);
     }
     dcqs.set_max_completed_queue((int)red_zone());
@@ -349,3 +403,42 @@
   }
   dcqs.notify_if_necessary();
 }
+
+size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
+  Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
+  return activation_level(thresholds);
+}
+
+size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const {
+  Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
+  return deactivation_level(thresholds);
+}
+
+uint G1ConcurrentRefine::worker_id_offset() {
+  return DirtyCardQueueSet::num_par_ids();
+}
+
+void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers) {
+  if (num_cur_buffers > activation_threshold(worker_id + 1)) {
+    _thread_control.maybe_activate_next(worker_id);
+  }
+}
+
+bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+
+  size_t curr_buffer_num = dcqs.completed_buffers_num();
+  // If the number of the buffers falls down into the yellow zone,
+  // that means that the transition period after the evacuation pause has ended.
+  // Since the value written to the DCQS is the same for all threads, there is no
+  // need to synchronize.
+  if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= yellow_zone()) {
+    dcqs.set_completed_queue_padding(0);
+  }
+
+  maybe_activate_more_threads(worker_id, curr_buffer_num);
+
+  // Process the next buffer, if there are enough left.
+  return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
+                                                   deactivation_threshold(worker_id));
+}
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -30,30 +30,63 @@
 
 // Forward decl
 class CardTableEntryClosure;
+class G1ConcurrentRefine;
 class G1ConcurrentRefineThread;
 class outputStream;
 class ThreadClosure;
 
-class G1ConcurrentRefine : public CHeapObj<mtGC> {
+// Helper class for refinement thread management. Used to start, stop and
+// iterate over them.
+class G1ConcurrentRefineThreadControl VALUE_OBJ_CLASS_SPEC {
+  G1ConcurrentRefine* _cr;
+
   G1ConcurrentRefineThread** _threads;
-  uint _n_worker_threads;
- /*
-  * The value of the update buffer queue length falls into one of 3 zones:
-  * green, yellow, red. If the value is in [0, green) nothing is
-  * done, the buffers are left unprocessed to enable the caching effect of the
-  * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
-  * threads are gradually activated. In [yellow, red) all threads are
-  * running. If the length becomes red (max queue length) the mutators start
-  * processing the buffers.
-  *
-  * There are some interesting cases (when G1UseAdaptiveConcRefinement
-  * is turned off):
-  * 1) green = yellow = red = 0. In this case the mutator will process all
-  *    buffers. Except for those that are created by the deferred updates
-  *    machinery during a collection.
-  * 2) green = 0. Means no caching. Can be a good way to minimize the
-  *    amount of time spent updating rsets during a collection.
-  */
+  uint _num_max_threads;
+
+  // Create the refinement thread for the given worker id.
+  // If initializing is true, ignore InjectGCWorkerCreationFailure.
+  G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing);
+public:
+  G1ConcurrentRefineThreadControl();
+  ~G1ConcurrentRefineThreadControl();
+
+  jint initialize(G1ConcurrentRefine* cr, uint num_max_threads);
+
+  // If there is a "successor" thread that can be activated given the current id,
+  // activate it.
+  void maybe_activate_next(uint cur_worker_id);
+
+  void print_on(outputStream* st) const;
+  void worker_threads_do(ThreadClosure* tc);
+  void stop();
+};
+
+// Controls refinement threads and their activation based on the number of completed
+// buffers currently available in the global dirty card queue.
+// Refinement threads pick work from the queue based on these thresholds. They are activated
+// gradually based on the amount of work to do.
+// Refinement thread n activates thread n+1 if the instance of this class determines there
+// is enough work available. Threads deactivate themselves if the current amount of
+// completed buffers falls below their individual threshold.
+class G1ConcurrentRefine : public CHeapObj<mtGC> {
+  G1ConcurrentRefineThreadControl _thread_control;
+  /*
+   * The value of the completed dirty card queue length falls into one of 3 zones:
+   * green, yellow, red. If the value is in [0, green) nothing is
+   * done, the buffers are left unprocessed to enable the caching effect of the
+   * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
+   * threads are gradually activated. In [yellow, red) all threads are
+   * running. If the length becomes red (max queue length) the mutators start
+   * processing the buffers.
+   *
+   * There are some interesting cases (when G1UseAdaptiveConcRefinement
+   * is turned off):
+   * 1) green = yellow = red = 0. In this case the mutator will process all
+   *    buffers. Except for those that are created by the deferred updates
+   *    machinery during a collection.
+   * 2) green = 0. Means no caching. Can be a good way to minimize the
+   *    amount of time spent updating remembered sets during a collection.
+   */
   size_t _green_zone;
   size_t _yellow_zone;
   size_t _red_zone;
@@ -69,24 +102,32 @@
                     size_t update_rs_processed_buffers,
                     double goal_ms);
 
-  // Update thread thresholds to account for updated zone values.
-  void update_thread_thresholds();
+  static uint worker_id_offset();
+  void maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers);
 
- public:
+  jint initialize();
+public:
   ~G1ConcurrentRefine();
 
-  // Returns a G1ConcurrentRefine instance if succeeded to create/initialize G1ConcurrentRefine and G1ConcurrentRefineThreads.
-  // Otherwise, returns NULL with error code.
+  // Returns a G1ConcurrentRefine instance if succeeded to create/initialize the
+  // G1ConcurrentRefine instance. Otherwise, returns NULL with error code.
   static G1ConcurrentRefine* create(jint* ecode);
 
   void stop();
 
+  // Adjust refinement thresholds based on work done during the pause and the goal time.
   void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
 
+  size_t activation_threshold(uint worker_id) const;
+  size_t deactivation_threshold(uint worker_id) const;
+  // Perform a single refinement step. Called by the refinement threads when woken up.
+  bool do_refinement_step(uint worker_id);
+
   // Iterate over all concurrent refinement threads applying the given closure.
   void threads_do(ThreadClosure *tc);
 
-  static uint thread_num();
+  // Maximum number of refinement threads.
+  static uint max_num_threads();
 
   void print_threads_on(outputStream* st) const;
 
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,32 +25,20 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
-#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1RemSet.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 
-G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr,
-                                                   G1ConcurrentRefineThread *next,
-                                                   uint worker_id_offset,
-                                                   uint worker_id,
-                                                   size_t activate,
-                                                   size_t deactivate) :
+G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
   ConcurrentGCThread(),
-  _worker_id_offset(worker_id_offset),
   _worker_id(worker_id),
   _active(false),
-  _next(next),
   _monitor(NULL),
   _cr(cr),
-  _vtime_accum(0.0),
-  _activation_threshold(activate),
-  _deactivation_threshold(deactivate)
+  _vtime_accum(0.0)
 {
-
   // Each thread has its own monitor. The i-th thread is responsible for signaling
   // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
   // thread. Monitors are also used to wake up the threads during termination.
@@ -67,13 +55,6 @@
   create_and_start();
 }
 
-void G1ConcurrentRefineThread::update_thresholds(size_t activate,
-                                                 size_t deactivate) {
-  assert(deactivate < activate, "precondition");
-  _activation_threshold = activate;
-  _deactivation_threshold = deactivate;
-}
-
 void G1ConcurrentRefineThread::wait_for_completed_buffers() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   while (!should_terminate() && !is_active()) {
@@ -118,9 +99,9 @@
     }
 
     size_t buffers_processed = 0;
-    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-    log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
-                          _worker_id, _activation_threshold, dcqs.completed_buffers_num());
+    log_debug(gc, refine)("Activated worker %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
+                          _worker_id, _cr->activation_threshold(_worker_id),
+                           JavaThread::dirty_card_queue_set().completed_buffers_num());
 
     {
       SuspendibleThreadSetJoiner sts_join;
@@ -131,33 +112,18 @@
           continue;             // Re-check for termination after yield delay.
         }
 
-        size_t curr_buffer_num = dcqs.completed_buffers_num();
-        // If the number of the buffers falls down into the yellow zone,
-        // that means that the transition period after the evacuation pause has ended.
-        if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cr()->yellow_zone()) {
-          dcqs.set_completed_queue_padding(0);
-        }
-
-        // Check if we need to activate the next thread.
-        if ((_next != NULL) &&
-            !_next->is_active() &&
-            (curr_buffer_num > _next->_activation_threshold)) {
-          _next->activate();
-        }
-
-        // Process the next buffer, if there are enough left.
-        if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) {
-          break; // Deactivate, number of buffers fell below threshold.
+        if (!_cr->do_refinement_step(_worker_id)) {
+          break;
         }
         ++buffers_processed;
       }
     }
 
     deactivate();
-    log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
+    log_debug(gc, refine)("Deactivated worker %d, off threshold: " SIZE_FORMAT
                           ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
-                          _worker_id, _deactivation_threshold,
-                          dcqs.completed_buffers_num(),
+                          _worker_id, _cr->deactivation_threshold(_worker_id),
+                          JavaThread::dirty_card_queue_set().completed_buffers_num(),
                           buffers_processed);
 
     if (os::supports_vtime()) {
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -43,43 +43,29 @@
   uint _worker_id;
   uint _worker_id_offset;
 
-  // The refinement threads collection is linked list. A predecessor can activate a successor
-  // when the number of the rset update buffer crosses a certain threshold. A successor
-  // would self-deactivate when the number of the buffers falls below the threshold.
   bool _active;
-  G1ConcurrentRefineThread* _next;
   Monitor* _monitor;
   G1ConcurrentRefine* _cr;
 
-  // This thread's activation/deactivation thresholds
-  size_t _activation_threshold;
-  size_t _deactivation_threshold;
-
   void wait_for_completed_buffers();
 
   void set_active(bool x) { _active = x; }
-  bool is_active();
-  void activate();
+  // Deactivate this thread.
   void deactivate();
 
   bool is_primary() { return (_worker_id == 0); }
 
   void run_service();
   void stop_service();
+public:
+  G1ConcurrentRefineThread(G1ConcurrentRefine* cg1r, uint worker_id);
 
-public:
-  // Constructor
-  G1ConcurrentRefineThread(G1ConcurrentRefine* cr, G1ConcurrentRefineThread* next,
-                           uint worker_id_offset, uint worker_id,
-                           size_t activate, size_t deactivate);
-
-  void update_thresholds(size_t activate, size_t deactivate);
-  size_t activation_threshold() const { return _activation_threshold; }
+  bool is_active();
+  // Activate this thread.
+  void activate();
 
   // Total virtual time so far.
   double vtime_accum() { return _vtime_accum; }
-
-  G1ConcurrentRefine* cr() { return _cr;     }
 };
 
 #endif // SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP
--- a/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -52,7 +52,7 @@
   _analytics(new G1Analytics(&_predictor)),
   _mmu_tracker(new G1MMUTrackerQueue(GCPauseIntervalMillis / 1000.0, MaxGCPauseMillis / 1000.0)),
   _ihop_control(create_ihop_control(&_predictor)),
-  _policy_counters(new GCPolicyCounters("GarbageFirst", 1, 3)),
+  _policy_counters(new GCPolicyCounters("GarbageFirst", 1, 2)),
   _young_list_fixed_length(0),
   _short_lived_surv_rate_group(new SurvRateGroup()),
   _survivor_surv_rate_group(new SurvRateGroup()),
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 #include "gc/g1/g1FullGCReferenceProcessorExecutor.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 #include "gc/g1/g1OopClosures.hpp"
+#include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/preservedMarks.hpp"
@@ -62,20 +63,24 @@
 #endif
 }
 
-G1FullCollector::G1FullCollector(G1FullGCScope* scope,
-                                 ReferenceProcessor* reference_processor,
-                                 G1CMBitMap* bitmap,
-                                 uint workers) :
-    _scope(scope),
-    _num_workers(workers),
-    _mark_bitmap(bitmap),
+G1CMBitMap* G1FullCollector::mark_bitmap() {
+  return _heap->concurrent_mark()->next_mark_bitmap();
+}
+
+ReferenceProcessor* G1FullCollector::reference_processor() {
+  return _heap->ref_processor_stw();
+}
+
+G1FullCollector::G1FullCollector(G1CollectedHeap* heap, GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft_refs) :
+    _heap(heap),
+    _scope(memory_manager, explicit_gc, clear_soft_refs),
+    _num_workers(heap->workers()->active_workers()),
     _oop_queue_set(_num_workers),
     _array_queue_set(_num_workers),
     _preserved_marks_set(true),
-    _reference_processor(reference_processor),
     _serial_compaction_point(),
-    _is_alive(_mark_bitmap),
-    _is_alive_mutator(_reference_processor, &_is_alive) {
+    _is_alive(heap->concurrent_mark()->next_mark_bitmap()),
+    _is_alive_mutator(heap->ref_processor_stw(), &_is_alive) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
 
   _preserved_marks_set.init(_num_workers);
@@ -99,8 +104,19 @@
 }
 
 void G1FullCollector::prepare_collection() {
-  _reference_processor->enable_discovery();
-  _reference_processor->setup_policy(scope()->should_clear_soft_refs());
+  _heap->g1_policy()->record_full_collection_start();
+
+  _heap->print_heap_before_gc();
+  _heap->print_heap_regions();
+
+  _heap->abort_concurrent_cycle();
+  _heap->verify_before_full_collection(scope()->is_explicit_gc());
+
+  _heap->gc_prologue(true);
+  _heap->prepare_heap_for_full_collection();
+
+  reference_processor()->enable_discovery();
+  reference_processor()->setup_policy(scope()->should_clear_soft_refs());
 
   // When collecting the permanent generation Method*s may be moving,
   // so we either have to flush all bcp data or convert it into bci.
@@ -139,6 +155,15 @@
   BiasedLocking::restore_marks();
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
+
+  _heap->prepare_heap_for_mutators();
+
+  _heap->g1_policy()->record_full_collection_end();
+  _heap->gc_epilogue(true);
+
+  _heap->verify_after_full_collection();
+
+  _heap->print_heap_after_full_collection(scope()->heap_transition());
 }
 
 void G1FullCollector::phase1_mark_live_objects() {
@@ -164,11 +189,11 @@
     GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer());
     // Unload classes and purge the SystemDictionary.
     bool purged_class = SystemDictionary::do_unloading(&_is_alive, scope()->timer());
-    G1CollectedHeap::heap()->complete_cleaning(&_is_alive, purged_class);
+    _heap->complete_cleaning(&_is_alive, purged_class);
   } else {
     GCTraceTime(Debug, gc, phases) debug("Phase 1: String and Symbol Tables Cleanup", scope()->timer());
     // If no class unloading just clean out strings and symbols.
-    G1CollectedHeap::heap()->partial_cleaning(&_is_alive, true, true, G1StringDedup::is_enabled());
+    _heap->partial_cleaning(&_is_alive, true, true, G1StringDedup::is_enabled());
   }
 
   scope()->tracer()->report_object_count_after_gc(&_is_alive);
@@ -210,18 +235,18 @@
 }
 
 void G1FullCollector::restore_marks() {
-  SharedRestorePreservedMarksTaskExecutor task_executor(G1CollectedHeap::heap()->workers());
+  SharedRestorePreservedMarksTaskExecutor task_executor(_heap->workers());
   _preserved_marks_set.restore(&task_executor);
   _preserved_marks_set.reclaim();
 }
 
 void G1FullCollector::run_task(AbstractGangTask* task) {
-  G1CollectedHeap::heap()->workers()->run_task(task, _num_workers);
+  _heap->workers()->run_task(task, _num_workers);
 }
 
 void G1FullCollector::verify_after_marking() {
-  if (!VerifyDuringGC) {
-    //Only do verification if VerifyDuringGC is set.
+  if (!VerifyDuringGC || !_heap->verifier()->should_verify(G1HeapVerifier::G1VerifyFull)) {
+    // Only do verification if VerifyDuringGC and G1VerifyFull is set.
     return;
   }
 
@@ -229,7 +254,7 @@
 #if COMPILER2_OR_JVMCI
   DerivedPointerTableDeactivate dpt_deact;
 #endif
-  G1CollectedHeap::heap()->prepare_for_verify();
+  _heap->prepare_for_verify();
   // Note: we can verify only the heap here. When an object is
   // marked, the previous value of the mark word (including
   // identity hash values, ages, etc) is preserved, and the mark
@@ -240,6 +265,6 @@
   // fail. At the end of the GC, the original mark word values
   // (including hash values) are restored to the appropriate
   // objects.
-  GCTraceTime(Info, gc, verify)("During GC (full)");
-  G1CollectedHeap::heap()->verify(VerifyOption_G1UseFullMarking);
+  GCTraceTime(Info, gc, verify)("Verifying During GC (full)");
+  _heap->verify(VerifyOption_G1UseFullMarking);
 }
--- a/src/hotspot/share/gc/g1/g1FullCollector.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 #include "gc/g1/g1FullGCCompactionPoint.hpp"
 #include "gc/g1/g1FullGCMarker.hpp"
 #include "gc/g1/g1FullGCOopClosures.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/taskqueue.hpp"
@@ -38,45 +39,41 @@
 class G1FullGCMarker;
 class G1FullGCScope;
 class G1FullGCCompactionPoint;
+class GCMemoryManager;
 class ReferenceProcessor;
 
 // The G1FullCollector holds data associated with the current Full GC.
 class G1FullCollector : StackObj {
-  G1FullGCScope*            _scope;
+  G1CollectedHeap*          _heap;
+  G1FullGCScope             _scope;
   uint                      _num_workers;
   G1FullGCMarker**          _markers;
   G1FullGCCompactionPoint** _compaction_points;
-  G1CMBitMap*               _mark_bitmap;
   OopQueueSet               _oop_queue_set;
   ObjArrayTaskQueueSet      _array_queue_set;
   PreservedMarksSet         _preserved_marks_set;
-  ReferenceProcessor*       _reference_processor;
   G1FullGCCompactionPoint   _serial_compaction_point;
-
   G1IsAliveClosure          _is_alive;
   ReferenceProcessorIsAliveMutator _is_alive_mutator;
 
 public:
-  G1FullCollector(G1FullGCScope* scope,
-                  ReferenceProcessor* reference_processor,
-                  G1CMBitMap* mark_bitmap,
-                  uint workers);
+  G1FullCollector(G1CollectedHeap* heap, GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft_refs);
   ~G1FullCollector();
 
   void prepare_collection();
   void collect();
   void complete_collection();
 
-  G1FullGCScope*           scope() { return _scope; }
+  G1FullGCScope*           scope() { return &_scope; }
   uint                     workers() { return _num_workers; }
   G1FullGCMarker*          marker(uint id) { return _markers[id]; }
   G1FullGCCompactionPoint* compaction_point(uint id) { return _compaction_points[id]; }
-  G1CMBitMap*              mark_bitmap() { return _mark_bitmap; }
   OopQueueSet*             oop_queue_set() { return &_oop_queue_set; }
   ObjArrayTaskQueueSet*    array_queue_set() { return &_array_queue_set; }
   PreservedMarksSet*       preserved_mark_set() { return &_preserved_marks_set; }
-  ReferenceProcessor*      reference_processor() { return _reference_processor; }
   G1FullGCCompactionPoint* serial_compaction_point() { return &_serial_compaction_point; }
+  G1CMBitMap*              mark_bitmap();
+  ReferenceProcessor*      reference_processor();
 
 private:
   void phase1_mark_live_objects();
--- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #define SHARE_GC_G1_G1FULLGCCOMPACTIONPOINT_HPP
 
 #include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
 #include "utilities/growableArray.hpp"
 
 class HeapRegion;
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 
-G1FullGCScope::G1FullGCScope(bool explicit_gc, bool clear_soft) :
+G1FullGCScope::G1FullGCScope(GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft) :
     _rm(),
     _explicit_gc(explicit_gc),
     _g1h(G1CollectedHeap::heap()),
@@ -36,7 +36,7 @@
     _active(),
     _cpu_time(),
     _soft_refs(clear_soft, _g1h->collector_policy()),
-    _memory_stats(true, _g1h->gc_cause()),
+    _memory_stats(memory_manager, _g1h->gc_cause()),
     _collector_stats(_g1h->g1mm()->full_collection_counters()),
     _heap_transition(_g1h) {
   _timer.register_gc_start();
--- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,8 @@
 #include "memory/allocation.hpp"
 #include "services/memoryService.hpp"
 
+class GCMemoryManager;
+
 // Class used to group scoped objects used in the Full GC together.
 class G1FullGCScope : public StackObj {
   ResourceMark            _rm;
@@ -54,7 +56,7 @@
   G1HeapTransition        _heap_transition;
 
 public:
-  G1FullGCScope(bool explicit_gc, bool clear_soft);
+  G1FullGCScope(GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft);
   ~G1FullGCScope();
 
   bool is_explicit_gc();
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -376,6 +376,37 @@
   }
 };
 
+void G1HeapVerifier::parse_verification_type(const char* type) {
+  if (strcmp(type, "young-only") == 0) {
+    enable_verification_type(G1VerifyYoungOnly);
+  } else if (strcmp(type, "initial-mark") == 0) {
+    enable_verification_type(G1VerifyInitialMark);
+  } else if (strcmp(type, "mixed") == 0) {
+    enable_verification_type(G1VerifyMixed);
+  } else if (strcmp(type, "remark") == 0) {
+    enable_verification_type(G1VerifyRemark);
+  } else if (strcmp(type, "cleanup") == 0) {
+    enable_verification_type(G1VerifyCleanup);
+  } else if (strcmp(type, "full") == 0) {
+    enable_verification_type(G1VerifyFull);
+  } else {
+    log_warning(gc, verify)("VerifyGCType: '%s' is unknown. Available types are: "
+                            "young-only, initial-mark, mixed, remark, cleanup and full", type);
+  }
+}
+
+void G1HeapVerifier::enable_verification_type(G1VerifyType type) {
+  // First enable will clear _enabled_verification_types.
+  if (_enabled_verification_types == G1VerifyAll) {
+    _enabled_verification_types = type;
+  } else {
+    _enabled_verification_types |= type;
+  }
+}
+
+bool G1HeapVerifier::should_verify(G1VerifyType type) {
+  return (_enabled_verification_types & type) == type;
+}
 
 void G1HeapVerifier::verify(VerifyOption vo) {
   if (!SafepointSynchronize::is_at_safepoint()) {
@@ -541,28 +572,32 @@
   }
 }
 
-double G1HeapVerifier::verify(bool guard, const char* msg) {
+double G1HeapVerifier::verify(G1VerifyType type, VerifyOption vo, const char* msg) {
   double verify_time_ms = 0.0;
 
-  if (guard && _g1h->total_collections() >= VerifyGCStartAt) {
+  if (should_verify(type) && _g1h->total_collections() >= VerifyGCStartAt) {
     double verify_start = os::elapsedTime();
     HandleMark hm;  // Discard invalid handles created during verification
     prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking, msg);
+    Universe::verify(vo, msg);
     verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
   }
 
   return verify_time_ms;
 }
 
-void G1HeapVerifier::verify_before_gc() {
-  double verify_time_ms = verify(VerifyBeforeGC, "Before GC");
-  _g1h->g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+void G1HeapVerifier::verify_before_gc(G1VerifyType type) {
+  if (VerifyBeforeGC) {
+    double verify_time_ms = verify(type, VerifyOption_G1UsePrevMarking, "Before GC");
+    _g1h->g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+  }
 }
 
-void G1HeapVerifier::verify_after_gc() {
-  double verify_time_ms = verify(VerifyAfterGC, "After GC");
-  _g1h->g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+void G1HeapVerifier::verify_after_gc(G1VerifyType type) {
+  if (VerifyAfterGC) {
+    double verify_time_ms = verify(type, VerifyOption_G1UsePrevMarking, "After GC");
+    _g1h->g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+  }
 }
 
 
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 class G1HeapVerifier : public CHeapObj<mtGC> {
 private:
   G1CollectedHeap* _g1h;
+  int _enabled_verification_types;
 
   // verify_region_sets() performs verification over the region
   // lists. It will be compiled in the product code to be used when
@@ -41,8 +42,21 @@
   void verify_region_sets();
 
 public:
+  enum G1VerifyType {
+    G1VerifyYoungOnly   =  1, // -XX:VerifyGCType=young-only
+    G1VerifyInitialMark =  2, // -XX:VerifyGCType=initial-mark
+    G1VerifyMixed       =  4, // -XX:VerifyGCType=mixed
+    G1VerifyRemark      =  8, // -XX:VerifyGCType=remark
+    G1VerifyCleanup     = 16, // -XX:VerifyGCType=cleanup
+    G1VerifyFull        = 32, // -XX:VerifyGCType=full
+    G1VerifyAll         = -1
+  };
 
-  G1HeapVerifier(G1CollectedHeap* heap) : _g1h(heap) { }
+  G1HeapVerifier(G1CollectedHeap* heap) : _g1h(heap), _enabled_verification_types(G1VerifyAll) { }
+
+  void parse_verification_type(const char* type);
+  void enable_verification_type(G1VerifyType type);
+  bool should_verify(G1VerifyType type);
 
   // Perform verification.
 
@@ -73,9 +87,9 @@
 #endif // HEAP_REGION_SET_FORCE_VERIFY
 
   void prepare_for_verify();
-  double verify(bool guard, const char* msg);
-  void verify_before_gc();
-  void verify_after_gc();
+  double verify(G1VerifyType type, VerifyOption vo, const char* msg);
+  void verify_before_gc(G1VerifyType type);
+  void verify_after_gc(G1VerifyType type);
 
 #ifndef PRODUCT
   // Make sure that the given bitmap has no marked objects in the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1MemoryPool.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2007, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1MemoryPool.hpp"
+#include "gc/g1/heapRegion.hpp"
+
+G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
+                                     const char* name,
+                                     size_t init_size,
+                                     size_t max_size,
+                                     bool support_usage_threshold) :
+  _g1mm(g1h->g1mm()), CollectedMemoryPool(name,
+                                          init_size,
+                                          max_size,
+                                          support_usage_threshold) {
+  assert(UseG1GC, "sanity");
+}
+
+G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
+  G1MemoryPoolSuper(g1h,
+                    "G1 Eden Space",
+                    g1h->g1mm()->eden_space_committed(), /* init_size */
+                    _undefined_max,
+                    false /* support_usage_threshold */) { }
+
+MemoryUsage G1EdenPool::get_memory_usage() {
+  size_t initial_sz = initial_size();
+  size_t max_sz     = max_size();
+  size_t used       = used_in_bytes();
+  size_t committed  = _g1mm->eden_space_committed();
+
+  return MemoryUsage(initial_sz, used, committed, max_sz);
+}
+
+G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
+  G1MemoryPoolSuper(g1h,
+                    "G1 Survivor Space",
+                    g1h->g1mm()->survivor_space_committed(), /* init_size */
+                    _undefined_max,
+                    false /* support_usage_threshold */) { }
+
+MemoryUsage G1SurvivorPool::get_memory_usage() {
+  size_t initial_sz = initial_size();
+  size_t max_sz     = max_size();
+  size_t used       = used_in_bytes();
+  size_t committed  = _g1mm->survivor_space_committed();
+
+  return MemoryUsage(initial_sz, used, committed, max_sz);
+}
+
+G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
+  G1MemoryPoolSuper(g1h,
+                    "G1 Old Gen",
+                    g1h->g1mm()->old_space_committed(), /* init_size */
+                    g1h->g1mm()->old_gen_max(),
+                    true /* support_usage_threshold */) { }
+
+MemoryUsage G1OldGenPool::get_memory_usage() {
+  size_t initial_sz = initial_size();
+  size_t max_sz     = max_size();
+  size_t used       = used_in_bytes();
+  size_t committed  = _g1mm->old_space_committed();
+
+  return MemoryUsage(initial_sz, used, committed, max_sz);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1MemoryPool.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007, 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1MEMORYPOOL_HPP
+#define SHARE_VM_GC_G1_G1MEMORYPOOL_HPP
+
+#include "gc/g1/g1MonitoringSupport.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryUsage.hpp"
+
+// This file contains the three classes that represent the memory
+// pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and
+// G1OldGenPool. In G1, unlike our other GCs, we do not have a
+// physical space for each of those spaces. Instead, we allocate
+// regions for all three spaces out of a single pool of regions (that
+// pool basically covers the entire heap). As a result, the eden,
+// survivor, and old gen are considered logical spaces in G1, as each
+// is a set of non-contiguous regions. This is also reflected in the
+// way we map them to memory pools here. The easiest way to have done
+// this would have been to map the entire G1 heap to a single memory
+// pool. However, it's helpful to show how large the eden and survivor
+// get, as this does affect the performance and behavior of G1. Which
+// is why we introduce the three memory pools implemented here.
+//
+// See comments in g1MonitoringSupport.hpp for additional details
+// on this model.
+//
+
+class G1CollectedHeap;
+
+// This class is shared by the three G1 memory pool classes
+// (G1EdenPool, G1SurvivorPool, G1OldGenPool).
+class G1MemoryPoolSuper : public CollectedMemoryPool {
+protected:
+  const static size_t _undefined_max = (size_t) -1;
+  G1MonitoringSupport* _g1mm;
+
+  // Would only be called from subclasses.
+  G1MemoryPoolSuper(G1CollectedHeap* g1h,
+                    const char* name,
+                    size_t init_size,
+                    size_t max_size,
+                    bool support_usage_threshold);
+};
+
+// Memory pool that represents the G1 eden.
+class G1EdenPool : public G1MemoryPoolSuper {
+public:
+  G1EdenPool(G1CollectedHeap* g1h);
+
+  size_t used_in_bytes() {
+    return _g1mm->eden_space_used();
+  }
+  size_t max_size() const {
+    return _undefined_max;
+  }
+  MemoryUsage get_memory_usage();
+};
+
+// Memory pool that represents the G1 survivor.
+class G1SurvivorPool : public G1MemoryPoolSuper {
+public:
+  G1SurvivorPool(G1CollectedHeap* g1h);
+
+  size_t used_in_bytes() {
+    return _g1mm->survivor_space_used();
+  }
+  size_t max_size() const {
+    return _undefined_max;
+  }
+  MemoryUsage get_memory_usage();
+};
+
+// Memory pool that represents the G1 old gen.
+class G1OldGenPool : public G1MemoryPoolSuper {
+public:
+  G1OldGenPool(G1CollectedHeap* g1h);
+
+  size_t used_in_bytes() {
+    return _g1mm->old_space_used();
+  }
+  size_t max_size() const {
+    return _g1mm->old_gen_max();
+  }
+  MemoryUsage get_memory_usage();
+};
+
+#endif // SHARE_VM_GC_G1_G1MEMORYPOOL_HPP
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1MonitoringSupport.hpp"
 #include "gc/g1/g1Policy.hpp"
+#include "gc/shared/hSpaceCounters.hpp"
 
 G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
                                            const char* name,
@@ -128,10 +129,10 @@
   //  name  "generation.1.space.0"
   // Counters are created from maxCapacity, capacity, initCapacity,
   // and used.
-  _old_space_counters = new HSpaceCounters("space", 0 /* ordinal */,
+  _old_space_counters = new HSpaceCounters(_old_collection_counters->name_space(),
+    "space", 0 /* ordinal */,
     pad_capacity(overall_reserved()) /* max_capacity */,
-    pad_capacity(old_space_committed()) /* init_capacity */,
-   _old_collection_counters);
+    pad_capacity(old_space_committed()) /* init_capacity */);
 
   //   Young collection set
   //  name "generation.0".  This is logically the young generation.
@@ -139,27 +140,29 @@
   // See  _old_collection_counters for additional counters
   _young_collection_counters = new G1YoungGenerationCounters(this, "young");
 
+  const char* young_collection_name_space = _young_collection_counters->name_space();
+
   //  name "generation.0.space.0"
   // See _old_space_counters for additional counters
-  _eden_counters = new HSpaceCounters("eden", 0 /* ordinal */,
+  _eden_counters = new HSpaceCounters(young_collection_name_space,
+    "eden", 0 /* ordinal */,
     pad_capacity(overall_reserved()) /* max_capacity */,
-    pad_capacity(eden_space_committed()) /* init_capacity */,
-    _young_collection_counters);
+    pad_capacity(eden_space_committed()) /* init_capacity */);
 
   //  name "generation.0.space.1"
   // See _old_space_counters for additional counters
   // Set the arguments to indicate that this survivor space is not used.
-  _from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
+  _from_counters = new HSpaceCounters(young_collection_name_space,
+    "s0", 1 /* ordinal */,
     pad_capacity(0) /* max_capacity */,
-    pad_capacity(0) /* init_capacity */,
-    _young_collection_counters);
+    pad_capacity(0) /* init_capacity */);
 
   //  name "generation.0.space.2"
   // See _old_space_counters for additional counters
-  _to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
+  _to_counters = new HSpaceCounters(young_collection_name_space,
+    "s1", 2 /* ordinal */,
     pad_capacity(overall_reserved()) /* max_capacity */,
-    pad_capacity(survivor_space_committed()) /* init_capacity */,
-    _young_collection_counters);
+    pad_capacity(survivor_space_committed()) /* init_capacity */);
 
   if (UsePerfData) {
     // Given that this survivor space is not used, we update it here
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,9 +25,11 @@
 #ifndef SHARE_VM_GC_G1_G1MONITORINGSUPPORT_HPP
 #define SHARE_VM_GC_G1_G1MONITORINGSUPPORT_HPP
 
-#include "gc/g1/hSpaceCounters.hpp"
+#include "gc/shared/generationCounters.hpp"
 
+class CollectorCounters;
 class G1CollectedHeap;
+class HSpaceCounters;
 
 // Class for monitoring logical spaces in G1. It provides data for
 // both G1's jstat counters as well as G1's memory pools.
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
+#include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/prefetch.inline.hpp"
 
@@ -390,3 +391,21 @@
   }
 }
 
+G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length) :
+    _g1h(g1h),
+    _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
+    _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
+    _young_cset_length(young_cset_length),
+    _n_workers(n_workers),
+    _flushed(false) {
+  for (uint i = 0; i < n_workers; ++i) {
+    _states[i] = NULL;
+  }
+  memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t));
+}
+
+G1ParScanThreadStateSet::~G1ParScanThreadStateSet() {
+  assert(_flushed, "thread local state from the per thread states should have been flushed");
+  FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states);
+  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_total);
+}
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -204,24 +204,8 @@
   bool _flushed;
 
  public:
-  G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length) :
-      _g1h(g1h),
-      _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
-      _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
-      _young_cset_length(young_cset_length),
-      _n_workers(n_workers),
-      _flushed(false) {
-    for (uint i = 0; i < n_workers; ++i) {
-      _states[i] = NULL;
-    }
-    memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t));
-  }
-
-  ~G1ParScanThreadStateSet() {
-    assert(_flushed, "thread local state from the per thread states should have been flushed");
-    FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states);
-    FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_total);
-  }
+  G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length);
+  ~G1ParScanThreadStateSet();
 
   void flush();
 
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -298,7 +298,7 @@
 }
 
 uint G1RemSet::num_par_rem_sets() {
-  return MAX2(DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::thread_num(), ParallelGCThreads);
+  return MAX2(DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads(), ParallelGCThreads);
 }
 
 void G1RemSet::initialize(size_t capacity, uint max_regions) {
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -86,7 +86,7 @@
   _num_processed_buf_mutator(0),
   _num_processed_buf_rs_threads(0),
   _num_coarsenings(0),
-  _num_vtimes(G1ConcurrentRefine::thread_num()),
+  _num_vtimes(G1ConcurrentRefine::max_num_threads()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
   _sampling_thread_vtime(0.0f) {
 
@@ -99,7 +99,7 @@
   _num_processed_buf_mutator(0),
   _num_processed_buf_rs_threads(0),
   _num_coarsenings(0),
-  _num_vtimes(G1ConcurrentRefine::thread_num()),
+  _num_vtimes(G1ConcurrentRefine::max_num_threads()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
   _sampling_thread_vtime(0.0f) {
   update();
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -175,6 +175,9 @@
 
 void
 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
+  if (mr.is_empty()) {
+    return;
+  }
   volatile jbyte* byte = byte_for(mr.start());
   jbyte* last_byte = byte_for(mr.last());
   Thread* thr = Thread::current();
--- a/src/hotspot/share/gc/g1/hSpaceCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/hSpaceCounters.hpp"
-#include "gc/shared/generation.hpp"
-#include "memory/resourceArea.hpp"
-
-HSpaceCounters::HSpaceCounters(const char* name,
-                               int ordinal,
-                               size_t max_size,
-                               size_t initial_capacity,
-                               GenerationCounters* gc) {
-
-  if (UsePerfData) {
-    EXCEPTION_MARK;
-    ResourceMark rm;
-
-    const char* cns =
-      PerfDataManager::name_space(gc->name_space(), "space", ordinal);
-
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
-    strcpy(_name_space, cns);
-
-    const char* cname = PerfDataManager::counter_name(_name_space, "name");
-    PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
-    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
-                                     (jlong)max_size, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "capacity");
-    _capacity = PerfDataManager::create_variable(SUN_GC, cname,
-                                                 PerfData::U_Bytes,
-                                                 initial_capacity, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "used");
-    _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes,
-                                             (jlong) 0, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "initCapacity");
-    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
-                                     initial_capacity, CHECK);
-  }
-}
--- a/src/hotspot/share/gc/g1/hSpaceCounters.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, 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.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_HSPACECOUNTERS_HPP
-#define SHARE_VM_GC_G1_HSPACECOUNTERS_HPP
-
-#include "gc/shared/generation.hpp"
-#include "gc/shared/generationCounters.hpp"
-#include "runtime/perfData.hpp"
-#include "utilities/macros.hpp"
-
-// A HSpaceCounter is a holder class for performance counters
-// that track a collections (logical spaces) in a heap;
-
-class HeapSpaceUsedHelper;
-class G1SpaceMonitoringSupport;
-
-class HSpaceCounters: public CHeapObj<mtGC> {
-  friend class VMStructs;
-
- private:
-  PerfVariable*        _capacity;
-  PerfVariable*        _used;
-
-  // Constant PerfData types don't need to retain a reference.
-  // However, it's a good idea to document them here.
-
-  char*             _name_space;
-
- public:
-
-  HSpaceCounters(const char* name, int ordinal, size_t max_size,
-                 size_t initial_capacity, GenerationCounters* gc);
-
-  ~HSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
-
-  inline void update_capacity(size_t v) {
-    _capacity->set_value(v);
-  }
-
-  inline void update_used(size_t v) {
-    _used->set_value(v);
-  }
-
-  debug_only(
-    // for security reasons, we do not allow arbitrary reads from
-    // the counters as they may live in shared memory.
-    jlong used() {
-      return _used->get_value();
-    }
-    jlong capacity() {
-      return _used->get_value();
-    }
-  )
-
-  inline void update_all(size_t capacity, size_t used) {
-    update_capacity(capacity);
-    update_used(used);
-  }
-
-  const char* name_space() const        { return _name_space; }
-};
-#endif // SHARE_VM_GC_G1_HSPACECOUNTERS_HPP
--- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 
 SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset, bool permanent) :
@@ -214,7 +215,7 @@
   log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
   log_error(gc, verify)("Actual SATB active states:");
   log_error(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     log_error(gc, verify)("  Thread \"%s\" queue: %s", t->name(), t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
   }
   log_error(gc, verify)("  Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
@@ -228,7 +229,7 @@
   }
 
   // Verify thread queue states
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     if (t->satb_mark_queue().is_active() != expected_active) {
       dump_active_states(expected_active);
       guarantee(false, "Thread SATB queue has an unexpected active state");
@@ -249,14 +250,14 @@
   verify_active_states(expected_active);
 #endif // ASSERT
   _all_active = active;
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->satb_mark_queue().set_active(active);
   }
   shared_satb_queue()->set_active(active);
 }
 
 void SATBMarkQueueSet::filter_thread_buffers() {
-  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->satb_mark_queue().filter();
   }
   shared_satb_queue()->filter();
@@ -309,7 +310,7 @@
     i += 1;
   }
 
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
     t->satb_mark_queue().print(buffer);
   }
@@ -341,8 +342,8 @@
   }
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   // So we can safely manipulate these queues.
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->satb_mark_queue().reset();
   }
- shared_satb_queue()->reset();
+  shared_satb_queue()->reset();
 }
--- a/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "utilities/align.hpp"
 
 MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment), _must_use_large_pages(false) {
@@ -90,14 +91,14 @@
     MutableSpace *s = ls->space();
     if (s->top() < top()) { // For all spaces preceding the one containing top()
       if (s->free_in_words() > 0) {
-        intptr_t cur_top = (intptr_t)s->top();
+        HeapWord* cur_top = s->top();
         size_t words_left_to_fill = pointer_delta(s->end(), s->top());;
         while (words_left_to_fill > 0) {
           size_t words_to_fill = MIN2(words_left_to_fill, CollectedHeap::filler_array_max_size());
           assert(words_to_fill >= CollectedHeap::min_fill_size(),
                  "Remaining size (" SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
                  words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size());
-          CollectedHeap::fill_with_object((HeapWord*)cur_top, words_to_fill);
+          CollectedHeap::fill_with_object(cur_top, words_to_fill);
           if (!os::numa_has_static_binding()) {
             size_t touched_words = words_to_fill;
 #ifndef ASSERT
@@ -107,19 +108,19 @@
             }
 #endif
             MemRegion invalid;
-            HeapWord *crossing_start = align_up((HeapWord*)cur_top, os::vm_page_size());
-            HeapWord *crossing_end = align_down((HeapWord*)(cur_top + touched_words), os::vm_page_size());
+            HeapWord *crossing_start = align_up(cur_top, os::vm_page_size());
+            HeapWord *crossing_end = align_down(cur_top + touched_words, os::vm_page_size());
             if (crossing_start != crossing_end) {
               // If object header crossed a small page boundary we mark the area
               // as invalid rounding it to a page_size().
-              HeapWord *start = MAX2(align_down((HeapWord*)cur_top, page_size()), s->bottom());
-              HeapWord *end = MIN2(align_up((HeapWord*)(cur_top + touched_words), page_size()), s->end());
+              HeapWord *start = MAX2(align_down(cur_top, page_size()), s->bottom());
+              HeapWord *end = MIN2(align_up(cur_top + touched_words, page_size()), s->end());
               invalid = MemRegion(start, end);
             }
 
             ls->add_invalid_region(invalid);
           }
-          cur_top = cur_top + (words_to_fill * HeapWordSize);
+          cur_top += words_to_fill;
           words_left_to_fill -= words_to_fill;
         }
       }
@@ -287,7 +288,7 @@
     FREE_C_HEAP_ARRAY(int, lgrp_ids);
 
     if (changed) {
-      for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+      for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
         thread->set_lgrp_id(-1);
       }
     }
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
 #include "gc/parallel/psMarkSweep.hpp"
+#include "gc/parallel/psMemoryPool.hpp"
 #include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/parallel/psPromotionManager.hpp"
 #include "gc/parallel/psScavenge.hpp"
@@ -45,6 +46,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/memoryManager.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/vmError.hpp"
 
@@ -105,9 +107,9 @@
     (old_gen()->virtual_space()->high_boundary() ==
      young_gen()->virtual_space()->low_boundary()),
     "Boundaries must meet");
-  // initialize the policy counters - 2 collectors, 3 generations
+  // initialize the policy counters - 2 collectors, 2 generations
   _gc_policy_counters =
-    new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy);
+    new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 2, _size_policy);
 
   // Set up the GCTaskManager
   _gc_task_manager = GCTaskManager::create(ParallelGCThreads);
@@ -119,7 +121,35 @@
   return JNI_OK;
 }
 
+void ParallelScavengeHeap::initialize_serviceability() {
+
+  _eden_pool = new EdenMutableSpacePool(_young_gen,
+                                        _young_gen->eden_space(),
+                                        "PS Eden Space",
+                                        false /* support_usage_threshold */);
+
+  _survivor_pool = new SurvivorMutableSpacePool(_young_gen,
+                                                "PS Survivor Space",
+                                                false /* support_usage_threshold */);
+
+  _old_pool = new PSGenerationPool(_old_gen,
+                                   "PS Old Gen",
+                                   true /* support_usage_threshold */);
+
+  _young_manager = new GCMemoryManager("PS Scavenge", "end of minor GC");
+  _old_manager = new GCMemoryManager("PS MarkSweep", "end of major GC");
+
+  _old_manager->add_pool(_eden_pool);
+  _old_manager->add_pool(_survivor_pool);
+  _old_manager->add_pool(_old_pool);
+
+  _young_manager->add_pool(_eden_pool);
+  _young_manager->add_pool(_survivor_pool);
+
+}
+
 void ParallelScavengeHeap::post_initialize() {
+  CollectedHeap::post_initialize();
   // Need to init the tenuring threshold
   PSScavenge::initialize();
   if (UseParallelOldGC) {
@@ -674,3 +704,19 @@
 void ParallelScavengeHeap::verify_nmethod(nmethod* nm) {
   CodeCache::verify_scavenge_root_nmethod(nm);
 }
+
+GrowableArray<GCMemoryManager*> ParallelScavengeHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(_young_manager);
+  memory_managers.append(_old_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> ParallelScavengeHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
+
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -36,11 +36,14 @@
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "memory/metaspace.hpp"
+#include "utilities/growableArray.hpp"
 #include "utilities/ostream.hpp"
 
 class AdjoiningGenerations;
 class GCHeapSummary;
 class GCTaskManager;
+class MemoryManager;
+class MemoryPool;
 class PSAdaptiveSizePolicy;
 class PSHeapSummary;
 
@@ -64,6 +67,15 @@
   // The task manager
   static GCTaskManager* _gc_task_manager;
 
+  GCMemoryManager* _young_manager;
+  GCMemoryManager* _old_manager;
+
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
+
+  virtual void initialize_serviceability();
+
   void trace_heap(GCWhen::Type when, const GCTracer* tracer);
 
  protected:
@@ -94,6 +106,9 @@
 
   virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   static PSYoungGen* young_gen() { return _young_gen; }
   static PSOldGen* old_gen()     { return _old_gen; }
 
@@ -244,6 +259,9 @@
     ParStrongRootsScope();
     ~ParStrongRootsScope();
   };
+
+  GCMemoryManager* old_gc_manager() const { return _old_manager; }
+  GCMemoryManager* young_gc_manager() const { return _young_manager; }
 };
 
 // Simple class for storing info about the heap at the start of GC, to be used
--- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 #include "gc/parallel/psScavenge.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
+#include "gc/shared/gcUtil.inline.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
--- a/src/hotspot/share/gc/parallel/psGenerationCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psGenerationCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,9 +25,9 @@
 
 #include "precompiled.hpp"
 #include "gc/parallel/psGenerationCounters.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 
-
 PSGenerationCounters::PSGenerationCounters(const char* name,
                                        int ordinal, int spaces,
                                        size_t min_capacity,
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -172,7 +172,7 @@
     heap->pre_full_gc_dump(_gc_timer);
 
     TraceCollectorStats tcs(counters());
-    TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
+    TraceMemoryManagerStats tms(heap->old_gc_manager(),gc_cause);
 
     if (log_is_enabled(Debug, gc, heap, exit)) {
       accumulated_time()->start();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/psMemoryPool.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/parallel/psMemoryPool.hpp"
+
+PSGenerationPool::PSGenerationPool(PSOldGen* old_gen,
+                                   const char* name,
+                                   bool support_usage_threshold) :
+  CollectedMemoryPool(name, old_gen->capacity_in_bytes(),
+                      old_gen->reserved().byte_size(), support_usage_threshold), _old_gen(old_gen) {
+}
+
+MemoryUsage PSGenerationPool::get_memory_usage() {
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+  size_t used      = used_in_bytes();
+  size_t committed = _old_gen->capacity_in_bytes();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+// The max size of EdenMutableSpacePool =
+//     max size of the PSYoungGen - capacity of two survivor spaces
+//
+// Max size of PS eden space is changing due to ergonomic.
+// PSYoungGen, PSOldGen, Eden, Survivor spaces are all resizable.
+//
+EdenMutableSpacePool::EdenMutableSpacePool(PSYoungGen* young_gen,
+                                           MutableSpace* space,
+                                           const char* name,
+                                           bool support_usage_threshold) :
+  CollectedMemoryPool(name, space->capacity_in_bytes(),
+                      (young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes()),
+                       support_usage_threshold),
+  _young_gen(young_gen),
+  _space(space) {
+}
+
+MemoryUsage EdenMutableSpacePool::get_memory_usage() {
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+  size_t used = used_in_bytes();
+  size_t committed = _space->capacity_in_bytes();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+// The max size of SurvivorMutableSpacePool =
+//     current capacity of the from-space
+//
+// PS from and to survivor spaces could have different sizes.
+//
+SurvivorMutableSpacePool::SurvivorMutableSpacePool(PSYoungGen* young_gen,
+                                                   const char* name,
+                                                   bool support_usage_threshold) :
+  CollectedMemoryPool(name, young_gen->from_space()->capacity_in_bytes(),
+                      young_gen->from_space()->capacity_in_bytes(),
+                      support_usage_threshold), _young_gen(young_gen) {
+}
+
+MemoryUsage SurvivorMutableSpacePool::get_memory_usage() {
+  size_t maxSize = (available_for_allocation() ? max_size() : 0);
+  size_t used    = used_in_bytes();
+  size_t committed = committed_in_bytes();
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/psMemoryPool.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2007, 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
+#define SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
+
+#include "gc/parallel/mutableSpace.hpp"
+#include "gc/parallel/psOldGen.hpp"
+#include "gc/parallel/psYoungGen.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryUsage.hpp"
+
+class PSGenerationPool : public CollectedMemoryPool {
+private:
+  PSOldGen* _old_gen;
+
+public:
+  PSGenerationPool(PSOldGen* pool, const char* name, bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes() { return _old_gen->used_in_bytes(); }
+  size_t max_size() const { return _old_gen->reserved().byte_size(); }
+};
+
+class EdenMutableSpacePool : public CollectedMemoryPool {
+private:
+  PSYoungGen*   _young_gen;
+  MutableSpace* _space;
+
+public:
+  EdenMutableSpacePool(PSYoungGen* young_gen,
+                       MutableSpace* space,
+                       const char* name,
+                       bool support_usage_threshold);
+
+  MutableSpace* space()                     { return _space; }
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes()                    { return space()->used_in_bytes(); }
+  size_t max_size() const {
+    // Eden's max_size = max_size of Young Gen - the current committed size of survivor spaces
+    return _young_gen->max_size() - _young_gen->from_space()->capacity_in_bytes() - _young_gen->to_space()->capacity_in_bytes();
+  }
+};
+
+class SurvivorMutableSpacePool : public CollectedMemoryPool {
+private:
+  PSYoungGen*   _young_gen;
+
+public:
+  SurvivorMutableSpacePool(PSYoungGen* young_gen,
+                           const char* name,
+                           bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+
+  size_t used_in_bytes() {
+    return _young_gen->from_space()->used_in_bytes();
+  }
+  size_t committed_in_bytes() {
+    return _young_gen->from_space()->capacity_in_bytes();
+  }
+  size_t max_size() const {
+    // Return current committed size of the from-space
+    return _young_gen->from_space()->capacity_in_bytes();
+  }
+};
+
+#endif // SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1772,7 +1772,7 @@
     heap->pre_full_gc_dump(&_gc_timer);
 
     TraceCollectorStats tcs(counters());
-    TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
+    TraceMemoryManagerStats tms(heap->old_gc_manager(), gc_cause);
 
     if (log_is_enabled(Debug, gc, heap, exit)) {
       accumulated_time()->start();
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -305,7 +305,7 @@
     GCTraceCPUTime tcpu;
     GCTraceTime(Info, gc) tm("Pause Young", NULL, gc_cause, true);
     TraceCollectorStats tcs(counters());
-    TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
+    TraceMemoryManagerStats tms(heap->young_gc_manager(), gc_cause);
 
     if (log_is_enabled(Debug, gc, heap, exit)) {
       accumulated_time()->start();
--- a/src/hotspot/share/gc/parallel/spaceCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/spaceCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/parallel/spaceCounters.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "utilities/macros.hpp"
 
@@ -63,3 +64,7 @@
                                      _object_space->capacity_in_bytes(), CHECK);
   }
 }
+
+SpaceCounters::~SpaceCounters() {
+  if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+}
--- a/src/hotspot/share/gc/parallel/spaceCounters.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/parallel/spaceCounters.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -53,9 +53,7 @@
   SpaceCounters(const char* name, int ordinal, size_t max_size,
                 MutableSpace* m, GenerationCounters* gc);
 
-  ~SpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
+  ~SpaceCounters();
 
   inline void update_capacity() {
     _capacity->set_value(_object_space->capacity_in_bytes());
--- a/src/hotspot/share/gc/serial/cSpaceCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/serial/cSpaceCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/serial/cSpaceCounters.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/metaspace.hpp"
 #include "memory/resourceArea.hpp"
 
@@ -64,6 +65,10 @@
   }
 }
 
+CSpaceCounters::~CSpaceCounters() {
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+}
+
 void CSpaceCounters::update_capacity() {
   _capacity->set_value(_space->capacity());
 }
--- a/src/hotspot/share/gc/serial/cSpaceCounters.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/serial/cSpaceCounters.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -52,9 +52,7 @@
   CSpaceCounters(const char* name, int ordinal, size_t max_size,
                  ContiguousSpace* s, GenerationCounters* gc);
 
-  ~CSpaceCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
+  ~CSpaceCounters();
 
   virtual void update_capacity();
   virtual void update_used();
--- a/src/hotspot/share/gc/serial/serialHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/serial/serialHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,9 +23,44 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/serial/defNewGeneration.hpp"
 #include "gc/serial/serialHeap.hpp"
+#include "gc/shared/genMemoryPools.hpp"
+#include "services/memoryManager.hpp"
+
+SerialHeap::SerialHeap(GenCollectorPolicy* policy) :
+  GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+  _young_manager = new GCMemoryManager("Copy", "end of minor GC");
+  _old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC");
+}
+
+void SerialHeap::initialize_serviceability() {
+
+  DefNewGeneration* young = (DefNewGeneration*) young_gen();
 
-SerialHeap::SerialHeap(GenCollectorPolicy* policy) : GenCollectedHeap(policy) {}
+  // Add a memory pool for each space and young gen doesn't
+  // support low memory detection as it is expected to get filled up.
+  _eden_pool = new ContiguousSpacePool(young->eden(),
+                                       "Eden Space",
+                                       young->max_eden_size(),
+                                       false /* support_usage_threshold */);
+  _survivor_pool = new SurvivorContiguousSpacePool(young,
+                                                   "Survivor Space",
+                                                   young->max_survivor_size(),
+                                                   false /* support_usage_threshold */);
+  Generation* old = old_gen();
+  _old_pool = new GenerationPool(old, "Tenured Gen", true);
+
+  _young_manager->add_pool(_eden_pool);
+  _young_manager->add_pool(_survivor_pool);
+  young->set_gc_manager(_young_manager);
+
+  _old_manager->add_pool(_eden_pool);
+  _old_manager->add_pool(_survivor_pool);
+  _old_manager->add_pool(_old_pool);
+  old->set_gc_manager(_old_manager);
+
+}
 
 void SerialHeap::check_gen_kinds() {
   assert(young_gen()->kind() == Generation::DefNew,
@@ -33,3 +68,18 @@
   assert(old_gen()->kind() == Generation::MarkSweepCompact,
          "Wrong generation kind");
 }
+
+GrowableArray<GCMemoryManager*> SerialHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(_young_manager);
+  memory_managers.append(_old_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> SerialHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
--- a/src/hotspot/share/gc/serial/serialHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/serial/serialHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,10 +26,20 @@
 #define SHARE_VM_GC_SERIAL_SERIALHEAP_HPP
 
 #include "gc/shared/genCollectedHeap.hpp"
+#include "utilities/growableArray.hpp"
 
 class GenCollectorPolicy;
+class GCMemoryManager;
+class MemoryPool;
 
 class SerialHeap : public GenCollectedHeap {
+private:
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
+
+  virtual void initialize_serviceability();
+
 protected:
   virtual void check_gen_kinds();
 
@@ -44,6 +54,9 @@
     return "Serial";
   }
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   // override
   virtual bool is_in_closed_subset(const void* p) const {
     return is_in(p);
@@ -52,7 +65,6 @@
   virtual bool card_mark_must_follow_store() const {
     return false;
   }
-
 };
 
 #endif // SHARE_VM_GC_CMS_CMSHEAP_HPP
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
+#include "gc/shared/gcUtil.inline.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -40,6 +40,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "services/heapDumper.hpp"
 #include "utilities/align.hpp"
 
@@ -540,10 +541,11 @@
   const bool deferred = _defer_initial_card_mark;
   // The main thread starts allocating via a TLAB even before it
   // has added itself to the threads list at vm boot-up.
-  assert(!use_tlab || Threads::first() != NULL,
+  JavaThreadIteratorWithHandle jtiwh;
+  assert(!use_tlab || jtiwh.length() > 0,
          "Attempt to fill tlabs before main thread has been added"
          " to threads list is doomed to failure!");
-  for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+  for (; JavaThread *thread = jtiwh.next(); ) {
      if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
 #if COMPILER2_OR_JVMCI
      // The deferred store barriers must all have been flushed to the
@@ -609,3 +611,7 @@
   _reserved.set_start(start);
   _reserved.set_end(end);
 }
+
+void CollectedHeap::post_initialize() {
+  initialize_serviceability();
+}
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 #include "utilities/debug.hpp"
 #include "utilities/events.hpp"
 #include "utilities/formatBuffer.hpp"
+#include "utilities/growableArray.hpp"
 
 // A "CollectedHeap" is an implementation of a java heap for HotSpot.  This
 // is an abstract class: there may be many different kinds of heaps.  This
@@ -46,6 +47,8 @@
 class GCHeapSummary;
 class GCTimer;
 class GCTracer;
+class GCMemoryManager;
+class MemoryPool;
 class MetaspaceSummary;
 class Thread;
 class ThreadClosure;
@@ -217,7 +220,7 @@
   // In many heaps, there will be a need to perform some initialization activities
   // after the Universe is fully formed, but before general heap allocation is allowed.
   // This is the correct place to place such initialization methods.
-  virtual void post_initialize() = 0;
+  virtual void post_initialize();
 
   // Stop any onging concurrent work and prepare for exit.
   virtual void stop() {}
@@ -485,6 +488,9 @@
   // Return the CollectorPolicy for the heap
   virtual CollectorPolicy* collector_policy() const = 0;
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers() = 0;
+  virtual GrowableArray<MemoryPool*> memory_pools() = 0;
+
   // Iterate over all objects, calling "cl.do_object" on each.
   virtual void object_iterate(ObjectClosure* cl) = 0;
 
@@ -529,6 +535,9 @@
   // Generate any dumps preceding or following a full gc
  private:
   void full_gc_dump(GCTimer* timer, bool before);
+
+  virtual void initialize_serviceability() = 0;
+
  public:
   void pre_full_gc_dump(GCTimer* timer);
   void post_full_gc_dump(GCTimer* timer);
--- a/src/hotspot/share/gc/shared/collectorCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectorCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,7 +24,9 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/collectorCounters.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/os.hpp"
 
 CollectorCounters::CollectorCounters(const char* name, int ordinal) {
 
@@ -59,3 +61,24 @@
                                                        CHECK);
   }
 }
+
+CollectorCounters::~CollectorCounters() {
+  if (_name_space != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name_space);
+  }
+}
+
+TraceCollectorStats::TraceCollectorStats(CollectorCounters* c) :
+    PerfTraceTimedEvent(c->time_counter(), c->invocation_counter()),
+    _c(c) {
+
+  if (UsePerfData) {
+     _c->last_entry_counter()->set_value(os::elapsed_counter());
+  }
+}
+
+TraceCollectorStats::~TraceCollectorStats() {
+  if (UsePerfData) {
+    _c->last_exit_counter()->set_value(os::elapsed_counter());
+  }
+}
--- a/src/hotspot/share/gc/shared/collectorCounters.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectorCounters.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -49,9 +49,7 @@
 
     CollectorCounters(const char* name, int ordinal);
 
-    ~CollectorCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-    }
+    ~CollectorCounters();
 
     inline PerfCounter* invocation_counter() const  { return _invocations; }
 
@@ -70,18 +68,9 @@
     CollectorCounters* _c;
 
   public:
-    inline TraceCollectorStats(CollectorCounters* c) :
-           PerfTraceTimedEvent(c->time_counter(), c->invocation_counter()),
-           _c(c) {
+    TraceCollectorStats(CollectorCounters* c);
 
-      if (UsePerfData) {
-         _c->last_entry_counter()->set_value(os::elapsed_counter());
-      }
-    }
-
-    inline ~TraceCollectorStats() {
-      if (UsePerfData) _c->last_exit_counter()->set_value(os::elapsed_counter());
-    }
+    ~TraceCollectorStats();
 };
 
 #endif // SHARE_VM_GC_SHARED_COLLECTORCOUNTERS_HPP
--- a/src/hotspot/share/gc/shared/collectorPolicy.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectorPolicy.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -911,7 +911,7 @@
 }
 
 void MarkSweepPolicy::initialize_gc_policy_counters() {
-  // Initialize the policy counters - 2 collectors, 3 generations.
-  _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
+  // Initialize the policy counters - 2 collectors, 2 generations.
+  _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 2);
 }
 
--- a/src/hotspot/share/gc/shared/gcArguments.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcArguments.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/shared/gcArguments.hpp"
 #include "gc/serial/serialArguments.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
@@ -84,6 +85,12 @@
 #endif // INCLUDE_ALL_GCS
 }
 
+bool GCArguments::parse_verification_type(const char* type) {
+  log_warning(gc, verify)("VerifyGCType is not supported by this collector.");
+  // Return false to avoid multiple warnings.
+  return false;
+}
+
 void GCArguments::initialize_flags() {
 #if INCLUDE_ALL_GCS
   if (MinHeapFreeRatio == 100) {
@@ -99,6 +106,24 @@
 #endif // INCLUDE_ALL_GCS
 }
 
+void GCArguments::post_heap_initialize() {
+  if (strlen(VerifyGCType) > 0) {
+    const char delimiter[] = " ,\n";
+    size_t length = strlen(VerifyGCType);
+    char* type_list = NEW_C_HEAP_ARRAY(char, length + 1, mtInternal);
+    strncpy(type_list, VerifyGCType, length + 1);
+    char* token = strtok(type_list, delimiter);
+    while (token != NULL) {
+      bool success = parse_verification_type(token);
+      if (!success) {
+        break;
+      }
+      token = strtok(NULL, delimiter);
+    }
+    FREE_C_HEAP_ARRAY(char, type_list);
+  }
+}
+
 jint GCArguments::initialize() {
   assert(!is_initialized(), "GC arguments already initialized");
 
--- a/src/hotspot/share/gc/shared/gcArguments.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcArguments.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -46,8 +46,16 @@
   static bool is_initialized();
   static GCArguments* arguments();
 
+  void post_heap_initialize();
+
   virtual void initialize_flags();
 
+  // Collector specific function to allow finer grained verification
+  // through VerifyGCType. If not overridden the default version will
+  // warn that the flag is not supported for the given collector.
+  // Returns true if parsing should continue, false otherwise.
+  virtual bool parse_verification_type(const char* type);
+
   virtual size_t conservative_max_heap_alignment() = 0;
 
   virtual CollectedHeap* create_heap() = 0;
--- a/src/hotspot/share/gc/shared/gcLocker.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcLocker.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -29,6 +29,7 @@
 #include "logging/log.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 
 volatile jint GCLocker::_jni_lock_count = 0;
 volatile bool GCLocker::_needs_gc       = false;
@@ -45,14 +46,16 @@
     assert(!needs_gc() || _debug_jni_lock_count == _jni_lock_count, "must agree");
     int count = 0;
     // Count the number of threads with critical operations in progress
-    for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) {
+    JavaThreadIteratorWithHandle jtiwh;
+    for (; JavaThread *thr = jtiwh.next(); ) {
       if (thr->in_critical()) {
         count++;
       }
     }
     if (_jni_lock_count != count) {
       log_error(gc, verify)("critical counts don't match: %d != %d", _jni_lock_count, count);
-      for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) {
+      jtiwh.rewind();
+      for (; JavaThread *thr = jtiwh.next(); ) {
         if (thr->in_critical()) {
           log_error(gc, verify)(INTPTR_FORMAT " in_critical %d", p2i(thr), thr->in_critical());
         }
--- a/src/hotspot/share/gc/shared/gcStats.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcStats.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,8 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/gcStats.hpp"
-#include "gc/shared/gcUtil.hpp"
-#include "memory/allocation.inline.hpp"
+#include "gc/shared/gcUtil.inline.hpp"
 
 GCStats::GCStats() {
     _avg_promoted       = new AdaptivePaddedNoZeroDevAverage(
--- a/src/hotspot/share/gc/shared/gcUtil.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcUtil.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -146,7 +146,7 @@
   // Placement support
   void* operator new(size_t ignored, void* p) throw() { return p; }
   // Allocator
-  void* operator new(size_t size) throw() { return CHeapObj<mtGC>::operator new(size); }
+  void* operator new(size_t size) throw();
 
   // Accessor
   float padded_average() const         { return _padded_avg; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/gcUtil.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2002, 2015, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_GCUTIL_INLINE_HPP
+#define SHARE_VM_GC_SHARED_GCUTIL_INLINE_HPP
+
+#include "gc/shared/gcUtil.hpp"
+#include "memory/allocation.inline.hpp"
+
+inline void* AdaptivePaddedAverage::operator new(size_t size) throw() {
+  return CHeapObj<mtGC>::operator new(size);
+}
+
+#endif // SHARE_VM_GC_SHARED_GCUTIL_INLINE_HPP
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -143,6 +143,7 @@
 }
 
 void GenCollectedHeap::post_initialize() {
+  CollectedHeap::post_initialize();
   ref_processing_init();
   check_gen_kinds();
   DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
@@ -270,7 +271,7 @@
   FormatBuffer<> title("Collect gen: %s", gen->short_name());
   GCTraceTime(Trace, gc, phases) t1(title);
   TraceCollectorStats tcs(gen->counters());
-  TraceMemoryManagerStats tmms(gen->kind(),gc_cause());
+  TraceMemoryManagerStats tmms(gen->gc_manager(), gc_cause());
 
   gen->stat_record()->invocations++;
   gen->stat_record()->accumulated_time.start();
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -112,6 +112,9 @@
   // (gen-specific) roots processing.
   SubTasksDone* _process_strong_tasks;
 
+  GCMemoryManager* _young_manager;
+  GCMemoryManager* _old_manager;
+
   // Helper functions for allocation
   HeapWord* attempt_allocation(size_t size,
                                bool   is_tlab,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/genMemoryPools.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/serial/defNewGeneration.hpp"
+#include "gc/shared/generation.hpp"
+#include "gc/shared/genMemoryPools.hpp"
+#include "gc/shared/space.hpp"
+
+ContiguousSpacePool::ContiguousSpacePool(ContiguousSpace* space,
+                                         const char* name,
+                                         size_t max_size,
+                                         bool support_usage_threshold) :
+  CollectedMemoryPool(name, space->capacity(), max_size,
+                      support_usage_threshold), _space(space) {
+}
+
+size_t ContiguousSpacePool::used_in_bytes() {
+  return space()->used();
+}
+
+MemoryUsage ContiguousSpacePool::get_memory_usage() {
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+  size_t used      = used_in_bytes();
+  size_t committed = _space->capacity();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+SurvivorContiguousSpacePool::SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
+                                                         const char* name,
+                                                         size_t max_size,
+                                                         bool support_usage_threshold) :
+  CollectedMemoryPool(name, young_gen->from()->capacity(), max_size,
+                      support_usage_threshold), _young_gen(young_gen) {
+}
+
+size_t SurvivorContiguousSpacePool::used_in_bytes() {
+  return _young_gen->from()->used();
+}
+
+size_t SurvivorContiguousSpacePool::committed_in_bytes() {
+  return _young_gen->from()->capacity();
+}
+
+MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
+  size_t maxSize = (available_for_allocation() ? max_size() : 0);
+  size_t used    = used_in_bytes();
+  size_t committed = committed_in_bytes();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+GenerationPool::GenerationPool(Generation* gen,
+                               const char* name,
+                               bool support_usage_threshold) :
+  CollectedMemoryPool(name, gen->capacity(), gen->max_capacity(),
+                      support_usage_threshold), _gen(gen) {
+}
+
+size_t GenerationPool::used_in_bytes() {
+  return _gen->used();
+}
+
+MemoryUsage GenerationPool::get_memory_usage() {
+  size_t used      = used_in_bytes();
+  size_t committed = _gen->capacity();
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/genMemoryPools.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_GENMEMORYPOOLS_HPP
+#define SHARE_VM_GC_SHARED_GENMEMORYPOOLS_HPP
+
+#include "services/memoryPool.hpp"
+
+class ContiguousSpace;
+class DefNewGeneration;
+class Generation;
+
+class ContiguousSpacePool : public CollectedMemoryPool {
+private:
+  ContiguousSpace* _space;
+
+public:
+  ContiguousSpacePool(ContiguousSpace* space,
+                      const char* name,
+                      size_t max_size,
+                      bool support_usage_threshold);
+
+  ContiguousSpace* space() { return _space; }
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes();
+};
+
+class SurvivorContiguousSpacePool : public CollectedMemoryPool {
+private:
+  DefNewGeneration* _young_gen;
+
+public:
+  SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
+                              const char* name,
+                              size_t max_size,
+                              bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+
+  size_t used_in_bytes();
+  size_t committed_in_bytes();
+};
+
+class GenerationPool : public CollectedMemoryPool {
+private:
+  Generation* _gen;
+public:
+  GenerationPool(Generation* gen, const char* name, bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes();
+};
+
+#endif // SHARE_VM_GC_SHARED_GENMEMORYPOOLS_HPP
--- a/src/hotspot/share/gc/shared/generation.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/generation.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -44,7 +44,8 @@
 #include "utilities/events.hpp"
 
 Generation::Generation(ReservedSpace rs, size_t initial_size) :
-  _ref_processor(NULL) {
+  _ref_processor(NULL),
+  _gc_manager(NULL) {
   if (!_virtual_space.initialize(rs, initial_size)) {
     vm_exit_during_initialization("Could not reserve enough space for "
                     "object heap");
--- a/src/hotspot/share/gc/shared/generation.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/generation.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -58,6 +58,7 @@
 //
 
 class DefNewGeneration;
+class GCMemoryManager;
 class GenerationSpec;
 class CompactibleSpace;
 class ContiguousSpace;
@@ -86,6 +87,8 @@
   MemRegion _prev_used_region; // for collectors that want to "remember" a value for
                                // used region at some specific point during collection.
 
+  GCMemoryManager* _gc_manager;
+
  protected:
   // Minimum and maximum addresses for memory reserved (not necessarily
   // committed) for generation.
@@ -554,6 +557,16 @@
   // Performance Counter support
   virtual void update_counters() = 0;
   virtual CollectorCounters* counters() { return _gc_counters; }
+
+  GCMemoryManager* gc_manager() const {
+    assert(_gc_manager != NULL, "not initialized yet");
+    return _gc_manager;
+  }
+
+  void set_gc_manager(GCMemoryManager* gc_manager) {
+    _gc_manager = gc_manager;
+  }
+
 };
 
 #endif // SHARE_VM_GC_SHARED_GENERATION_HPP
--- a/src/hotspot/share/gc/shared/generationCounters.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/generationCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/generationCounters.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 
 void GenerationCounters::initialize(const char* name, int ordinal, int spaces,
@@ -78,6 +79,12 @@
   initialize(name, ordinal, spaces, min_capacity, max_capacity, curr_capacity);
 }
 
+GenerationCounters::~GenerationCounters() {
+  if (_name_space != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name_space);
+  }
+}
+
 void GenerationCounters::update_all() {
   assert(_virtual_space != NULL, "otherwise, override this method");
   _current_size->set_value(_virtual_space->committed_size());
--- a/src/hotspot/share/gc/shared/generationCounters.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/generationCounters.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -68,9 +68,7 @@
   GenerationCounters(const char* name, int ordinal, int spaces,
                      size_t min_capacity, size_t max_capacity, VirtualSpace* v);
 
-  ~GenerationCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
+  ~GenerationCounters();
 
   virtual void update_all();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/hSpaceCounters.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/hSpaceCounters.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/perfData.hpp"
+
+HSpaceCounters::HSpaceCounters(const char* name_space,
+                               const char* name,
+                               int ordinal,
+                               size_t max_size,
+                               size_t initial_capacity) {
+
+  if (UsePerfData) {
+    EXCEPTION_MARK;
+    ResourceMark rm;
+
+    const char* cns =
+      PerfDataManager::name_space(name_space, "space", ordinal);
+
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
+    strcpy(_name_space, cns);
+
+    const char* cname = PerfDataManager::counter_name(_name_space, "name");
+    PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
+    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
+                                     (jlong)max_size, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "capacity");
+    _capacity = PerfDataManager::create_variable(SUN_GC, cname,
+                                                 PerfData::U_Bytes,
+                                                 initial_capacity, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "used");
+    _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes,
+                                             (jlong) 0, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "initCapacity");
+    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
+                                     initial_capacity, CHECK);
+  }
+}
+
+HSpaceCounters::~HSpaceCounters() {
+  if (_name_space != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name_space);
+  }
+}
+
+void HSpaceCounters::update_capacity(size_t v) {
+  _capacity->set_value(v);
+}
+
+void HSpaceCounters::update_used(size_t v) {
+  _used->set_value(v);
+}
+
+void HSpaceCounters::update_all(size_t capacity, size_t used) {
+  update_capacity(capacity);
+  update_used(used);
+}
+
+debug_only(
+  // for security reasons, we do not allow arbitrary reads from
+  // the counters as they may live in shared memory.
+  jlong HSpaceCounters::used() {
+    return _used->get_value();
+  }
+  jlong HSpaceCounters::capacity() {
+    return _used->get_value();
+  }
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/hSpaceCounters.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_HSPACECOUNTERS_HPP
+#define SHARE_VM_GC_SHARED_HSPACECOUNTERS_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/perfData.hpp"
+#include "utilities/macros.hpp"
+
+// A HSpaceCounter is a holder class for performance counters
+// that track a collections (logical spaces) in a heap;
+
+class HSpaceCounters: public CHeapObj<mtGC> {
+  friend class VMStructs;
+
+ private:
+  PerfVariable* _capacity;
+  PerfVariable* _used;
+
+  // Constant PerfData types don't need to retain a reference.
+  // However, it's a good idea to document them here.
+
+  char*         _name_space;
+
+ public:
+
+  HSpaceCounters(const char* name_space, const char* name, int ordinal,
+                 size_t max_size, size_t initial_capacity);
+
+  ~HSpaceCounters();
+
+  void update_capacity(size_t v);
+  void update_used(size_t v);
+
+  void update_all(size_t capacity, size_t used);
+
+  debug_only(
+    // for security reasons, we do not allow arbitrary reads from
+    // the counters as they may live in shared memory.
+    jlong used();
+    jlong capacity();
+  )
+
+  const char* name_space() const        { return _name_space; }
+};
+#endif // SHARE_VM_GC_SHARED_HSPACECOUNTERS_HPP
--- a/src/hotspot/share/gc/shared/taskqueue.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,8 @@
 #define SHARE_VM_GC_SHARED_TASKQUEUE_HPP
 
 #include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "utilities/ostream.hpp"
 #include "utilities/stack.hpp"
 
 // Simple TaskQueue stats that are collected by default in debug builds.
@@ -425,7 +427,7 @@
 private:
   uint _n_threads;
   TaskQueueSetSuper* _queue_set;
-  uint _offered_termination;
+  volatile uint _offered_termination;
 
 #ifdef TRACESPINNING
   static uint _total_yields;
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 #include "memory/universe.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "utilities/copy.hpp"
 
 // Thread-Local Edens support
@@ -48,7 +49,7 @@
 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
   global_stats()->initialize();
 
-  for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     thread->tlab().accumulate_statistics();
     thread->tlab().initialize_statistics();
   }
@@ -130,7 +131,7 @@
 
 void ThreadLocalAllocBuffer::resize_all_tlabs() {
   if (ResizeTLAB) {
-    for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
       thread->tlab().resize();
     }
   }
--- a/src/hotspot/share/gc/shared/workgroup.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/workgroup.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -261,6 +261,10 @@
     _dispatcher(create_dispatcher())
 { }
 
+WorkGang::~WorkGang() {
+  delete _dispatcher;
+}
+
 AbstractGangWorker* WorkGang::allocate_worker(uint worker_id) {
   return new GangWorker(this, worker_id);
 }
--- a/src/hotspot/share/gc/shared/workgroup.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/gc/shared/workgroup.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -122,6 +122,8 @@
   // Printing support.
   const char* _name;
 
+  ~AbstractWorkGang() {}
+
  private:
   // Initialize only instance data.
   const bool _are_GC_task_threads;
@@ -206,9 +208,6 @@
   // To get access to the GangTaskDispatcher instance.
   friend class GangWorker;
 
-  // Never deleted.
-  ~WorkGang();
-
   GangTaskDispatcher* const _dispatcher;
   GangTaskDispatcher* dispatcher() const {
     return _dispatcher;
@@ -220,6 +219,8 @@
            bool are_GC_task_threads,
            bool are_ConcurrentGC_threads);
 
+  ~WorkGang();
+
   // Run a task using the current active number of workers, returns when the task is done.
   virtual void run_task(AbstractGangTask* task);
   // Run a task with the given number of workers, returns
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -42,6 +42,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/sharedRuntime.hpp"
+#include "runtime/threadSMR.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/macros.hpp"
@@ -598,12 +599,13 @@
 JRT_END
 
 JRT_ENTRY(jboolean, JVMCIRuntime::thread_is_interrupted(JavaThread* thread, oopDesc* receiver, jboolean clear_interrupted))
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate.
-  // This locking requires thread_in_vm which is why this method cannot be JRT_LEAF.
   Handle receiverHandle(thread, receiver);
-  MutexLockerEx ml(thread->threadObj() == (void*)receiver ? NULL : Threads_lock);
+  // A nested ThreadsListHandle may require the Threads_lock which
+  // requires thread_in_vm which is why this method cannot be JRT_LEAF.
+  ThreadsListHandle tlh;
+
   JavaThread* receiverThread = java_lang_Thread::thread(receiverHandle());
-  if (receiverThread == NULL) {
+  if (receiverThread == NULL || (EnableThreadSMRExtraValidityChecks && !tlh.includes(receiverThread))) {
     // The other thread may exit during this process, which is ok so return false.
     return JNI_FALSE;
   } else {
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -317,6 +317,7 @@
                                                                                                                                      \
   nonstatic_field(Thread,                   _tlab,                                            ThreadLocalAllocBuffer)                \
   nonstatic_field(Thread,                   _allocated_bytes,                                 jlong)                                 \
+  nonstatic_field(Thread,                   _polling_page,                                    address)                               \
                                                                                                                                      \
   nonstatic_field(ThreadLocalAllocBuffer,   _start,                                           HeapWord*)                             \
   nonstatic_field(ThreadLocalAllocBuffer,   _top,                                             HeapWord*)                             \
--- a/src/hotspot/share/logging/logTag.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/logging/logTag.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -121,6 +121,7 @@
   LOG_TAG(safepoint) \
   LOG_TAG(scavenge) \
   LOG_TAG(scrub) \
+  LOG_TAG(smr) \
   LOG_TAG(stacktrace) \
   LOG_TAG(stackwalk) \
   LOG_TAG(start) \
--- a/src/hotspot/share/memory/metaspace.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/memory/metaspace.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -785,7 +785,10 @@
   Mutex* const _lock;
 
   // Type of metadata allocated.
-  Metaspace::MetadataType _mdtype;
+  const Metaspace::MetadataType   _mdtype;
+
+  // Type of metaspace
+  const Metaspace::MetaspaceType  _space_type;
 
   // List of chunks in use by this SpaceManager.  Allocations
   // are done from the current chunk.  The list is used for deallocating
@@ -796,6 +799,10 @@
   // Maximum number of small chunks to allocate to a SpaceManager
   static uint const _small_chunk_limit;
 
+  // Maximum number of specialize chunks to allocate for anonymous
+  // metadata space to a SpaceManager
+  static uint const _anon_metadata_specialize_chunk_limit;
+
   // Sum of all space in allocated chunks
   size_t _allocated_blocks_words;
 
@@ -846,6 +853,7 @@
 
  public:
   SpaceManager(Metaspace::MetadataType mdtype,
+               Metaspace::MetaspaceType space_type,
                Mutex* lock);
   ~SpaceManager();
 
@@ -963,6 +971,7 @@
 };
 
 uint const SpaceManager::_small_chunk_limit = 4;
+uint const SpaceManager::_anon_metadata_specialize_chunk_limit = 4;
 
 const char* SpaceManager::_expand_lock_name =
   "SpaceManager chunk allocation lock";
@@ -2400,6 +2409,20 @@
   // _small_chunk_limit small chunks can be allocated.
   // After that a medium chunk is preferred.
   size_t chunk_word_size;
+
+  // Special case for anonymous metadata space.
+  // Anonymous metadata space is usually small, with majority within 1K - 2K range and
+  // rarely about 4K (64-bits JVM).
+  // Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation
+  // from SpecializeChunk up to _anon_metadata_specialize_chunk_limit (4) reduces space waste
+  // from 60+% to around 30%.
+  if (_space_type == Metaspace::AnonymousMetaspaceType &&
+      _mdtype == Metaspace::NonClassType &&
+      sum_count_in_chunks_in_use(SpecializedIndex) < _anon_metadata_specialize_chunk_limit &&
+      word_size + Metachunk::overhead() <= SpecializedChunk) {
+    return SpecializedChunk;
+  }
+
   if (chunks_in_use(MediumIndex) == NULL &&
       sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
     chunk_word_size = (size_t) small_chunk_size();
@@ -2504,8 +2527,10 @@
 }
 
 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
+                           Metaspace::MetaspaceType space_type,
                            Mutex* lock) :
   _mdtype(mdtype),
+  _space_type(space_type),
   _allocated_blocks_words(0),
   _allocated_chunks_words(0),
   _allocated_chunks_count(0),
@@ -3781,11 +3806,11 @@
   verify_global_initialization();
 
   // Allocate SpaceManager for metadata objects.
-  _vsm = new SpaceManager(NonClassType, lock);
+  _vsm = new SpaceManager(NonClassType, type, lock);
 
   if (using_class_space()) {
     // Allocate SpaceManager for classes.
-    _class_vsm = new SpaceManager(ClassType, lock);
+    _class_vsm = new SpaceManager(ClassType, type, lock);
   }
 
   MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
--- a/src/hotspot/share/memory/resourceArea.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/memory/resourceArea.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,7 +24,7 @@
 
 #include "precompiled.hpp"
 #include "memory/allocation.inline.hpp"
-#include "memory/resourceArea.hpp"
+#include "memory/resourceArea.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.inline.hpp"
 #include "services/memTracker.hpp"
--- a/src/hotspot/share/memory/resourceArea.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/memory/resourceArea.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -57,18 +57,7 @@
     debug_only(_nesting = 0;);
   }
 
-  char* allocate_bytes(size_t size, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
-#ifdef ASSERT
-    if (_nesting < 1 && !_warned++)
-      fatal("memory leak: allocating without ResourceMark");
-    if (UseMallocOnly) {
-      // use malloc, but save pointer in res. area for later freeing
-      char** save = (char**)internal_malloc_4(sizeof(char*));
-      return (*save = (char*)os::malloc(size, mtThread, CURRENT_PC));
-    }
-#endif
-    return (char*)Amalloc(size, alloc_failmode);
-  }
+  char* allocate_bytes(size_t size, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
 
   // Bias this resource area to specific memory type
   // (by default, ResourceArea is tagged as mtThread, per-thread general purpose storage)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/resourceArea.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_RESOURCEAREA_INLINE_HPP
+#define SHARE_VM_MEMORY_RESOURCEAREA_INLINE_HPP
+
+#include "memory/resourceArea.hpp"
+
+inline char* ResourceArea::allocate_bytes(size_t size, AllocFailType alloc_failmode) {
+#ifdef ASSERT
+  if (_nesting < 1 && !_warned++)
+    fatal("memory leak: allocating without ResourceMark");
+  if (UseMallocOnly) {
+    // use malloc, but save pointer in res. area for later freeing
+    char** save = (char**)internal_malloc_4(sizeof(char*));
+    return (*save = (char*)os::malloc(size, mtThread, CURRENT_PC));
+  }
+#endif
+  return (char*)Amalloc(size, alloc_failmode);
+}
+
+#endif // SHARE_VM_MEMORY_RESOURCEAREA_INLINE_HPP
--- a/src/hotspot/share/memory/universe.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/memory/universe.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -687,6 +687,10 @@
 
   Metaspace::global_initialize();
 
+  // Initialize performance counters for metaspaces
+  MetaspaceCounters::initialize_performance_counters();
+  CompressedClassSpaceCounters::initialize_performance_counters();
+
   AOTLoader::universe_init();
 
   // Checks 'AfterMemoryInit' constraints.
@@ -764,6 +768,7 @@
   }
   log_info(gc)("Using %s", _collectedHeap->name());
 
+  GCArguments::arguments()->post_heap_initialize();
   ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
 
 #ifdef _LP64
@@ -852,7 +857,7 @@
       || use_large_pages, "Wrong alignment to use large pages");
 
   // Now create the space.
-  ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages);
+  ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages, AllocateHeapAt);
 
   if (total_rs.is_reserved()) {
     assert((total_reserved == total_rs.size()) && ((uintptr_t)total_rs.base() % alignment == 0),
@@ -866,6 +871,9 @@
       Universe::set_narrow_oop_base((address)total_rs.compressed_oop_base());
     }
 
+    if (AllocateHeapAt != NULL) {
+      log_info(gc,heap)("Successfully allocated Java heap at location %s", AllocateHeapAt);
+    }
     return total_rs;
   }
 
@@ -1085,10 +1093,6 @@
   // ("weak") refs processing infrastructure initialization
   Universe::heap()->post_initialize();
 
-  // Initialize performance counters for metaspaces
-  MetaspaceCounters::initialize_performance_counters();
-  CompressedClassSpaceCounters::initialize_performance_counters();
-
   MemoryService::add_metaspace_memory_pools();
 
   MemoryService::set_universe_heap(Universe::heap());
--- a/src/hotspot/share/memory/virtualspace.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/memory/virtualspace.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -35,10 +35,10 @@
 
 // Dummy constructor
 ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
-    _alignment(0), _special(false), _executable(false) {
+    _alignment(0), _special(false), _executable(false), _fd_for_heap(-1) {
 }
 
-ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) {
+ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) : _fd_for_heap(-1) {
   bool has_preferred_page_size = preferred_page_size != 0;
   // Want to use large pages where possible and pad with small pages.
   size_t page_size = has_preferred_page_size ? preferred_page_size : os::page_size_for_region_unaligned(size, 1);
@@ -59,19 +59,30 @@
 
 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
                              bool large,
-                             char* requested_address) {
+                             char* requested_address) : _fd_for_heap(-1) {
   initialize(size, alignment, large, requested_address, false);
 }
 
 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
                              bool large,
-                             bool executable) {
+                             bool executable) : _fd_for_heap(-1) {
   initialize(size, alignment, large, NULL, executable);
 }
 
+// Helper method
+static void unmap_or_release_memory(char* base, size_t size, bool is_file_mapped) {
+  if (is_file_mapped) {
+    if (!os::unmap_memory(base, size)) {
+      fatal("os::unmap_memory failed");
+    }
+  } else if (!os::release_memory(base, size)) {
+    fatal("os::release_memory failed");
+  }
+}
+
 // Helper method.
 static bool failed_to_reserve_as_requested(char* base, char* requested_address,
-                                           const size_t size, bool special)
+                                           const size_t size, bool special, bool is_file_mapped = false)
 {
   if (base == requested_address || requested_address == NULL)
     return false; // did not fail
@@ -87,9 +98,7 @@
         fatal("os::release_memory_special failed");
       }
     } else {
-      if (!os::release_memory(base, size)) {
-        fatal("os::release_memory failed");
-      }
+      unmap_or_release_memory(base, size, is_file_mapped);
     }
   }
   return true;
@@ -120,7 +129,18 @@
 
   // If OS doesn't support demand paging for large page memory, we need
   // to use reserve_memory_special() to reserve and pin the entire region.
+  // If there is a backing file directory for this space then whether
+  // large pages are allocated is up to the filesystem of the backing file.
+  // So we ignore the UseLargePages flag in this case.
   bool special = large && !os::can_commit_large_page_memory();
+  if (special && _fd_for_heap != -1) {
+    special = false;
+    if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
+      !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
+      log_debug(gc, heap)("Ignoring UseLargePages since large page support is up to the file system of the backing file for Java heap");
+    }
+  }
+
   char* base = NULL;
 
   if (special) {
@@ -157,13 +177,13 @@
     // important.  If available space is not detected, return NULL.
 
     if (requested_address != 0) {
-      base = os::attempt_reserve_memory_at(size, requested_address);
-      if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
+      base = os::attempt_reserve_memory_at(size, requested_address, _fd_for_heap);
+      if (failed_to_reserve_as_requested(base, requested_address, size, false, _fd_for_heap != -1)) {
         // OS ignored requested address. Try different address.
         base = NULL;
       }
     } else {
-      base = os::reserve_memory(size, NULL, alignment);
+      base = os::reserve_memory(size, NULL, alignment, _fd_for_heap);
     }
 
     if (base == NULL) return;
@@ -171,13 +191,14 @@
     // Check alignment constraints
     if ((((size_t)base) & (alignment - 1)) != 0) {
       // Base not aligned, retry
-      if (!os::release_memory(base, size)) fatal("os::release_memory failed");
+      unmap_or_release_memory(base, size, _fd_for_heap != -1 /*is_file_mapped*/);
+
       // Make sure that size is aligned
       size = align_up(size, alignment);
-      base = os::reserve_memory_aligned(size, alignment);
+      base = os::reserve_memory_aligned(size, alignment, _fd_for_heap);
 
       if (requested_address != 0 &&
-          failed_to_reserve_as_requested(base, requested_address, size, false)) {
+          failed_to_reserve_as_requested(base, requested_address, size, false, _fd_for_heap != -1)) {
         // As a result of the alignment constraints, the allocated base differs
         // from the requested address. Return back to the caller who can
         // take remedial action (like try again without a requested address).
@@ -190,6 +211,10 @@
   _base = base;
   _size = size;
   _alignment = alignment;
+  // If heap is reserved with a backing file, the entire space has been committed. So set the _special flag to true
+  if (_fd_for_heap != -1) {
+    _special = true;
+  }
 }
 
 
@@ -252,7 +277,11 @@
     char *real_base = _base - _noaccess_prefix;
     const size_t real_size = _size + _noaccess_prefix;
     if (special()) {
-      os::release_memory_special(real_base, real_size);
+      if (_fd_for_heap != -1) {
+        os::unmap_memory(real_base, real_size);
+      } else {
+        os::release_memory_special(real_base, real_size);
+      }
     } else{
       os::release_memory(real_base, real_size);
     }
@@ -313,7 +342,17 @@
 
   // If OS doesn't support demand paging for large page memory, we need
   // to use reserve_memory_special() to reserve and pin the entire region.
+  // If there is a backing file directory for this space then whether
+  // large pages are allocated is up to the filesystem of the backing file.
+  // So we ignore the UseLargePages flag in this case.
   bool special = large && !os::can_commit_large_page_memory();
+  if (special && _fd_for_heap != -1) {
+    special = false;
+    if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
+                          !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
+      log_debug(gc, heap)("Cannot allocate large pages for Java Heap when AllocateHeapAt option is set.");
+    }
+  }
   char* base = NULL;
 
   log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT
@@ -350,9 +389,9 @@
     // important.  If available space is not detected, return NULL.
 
     if (requested_address != 0) {
-      base = os::attempt_reserve_memory_at(size, requested_address);
+      base = os::attempt_reserve_memory_at(size, requested_address, _fd_for_heap);
     } else {
-      base = os::reserve_memory(size, NULL, alignment);
+      base = os::reserve_memory(size, NULL, alignment, _fd_for_heap);
     }
   }
   if (base == NULL) { return; }
@@ -362,6 +401,11 @@
   _size = size;
   _alignment = alignment;
 
+  // If heap is reserved with a backing file, the entire space has been committed. So set the _special flag to true
+  if (_fd_for_heap != -1) {
+    _special = true;
+  }
+
   // Check alignment constraints
   if ((((size_t)base) & (alignment - 1)) != 0) {
     // Base not aligned, retry.
@@ -556,12 +600,20 @@
   }
 }
 
-ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large) : ReservedSpace() {
+ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large, const char* heap_allocation_directory) : ReservedSpace() {
 
   if (size == 0) {
     return;
   }
 
+  if (heap_allocation_directory != NULL) {
+    _fd_for_heap = os::create_file_for_heap(heap_allocation_directory);
+    if (_fd_for_heap == -1) {
+      vm_exit_during_initialization(
+        err_msg("Could not create file for Heap at location %s", heap_allocation_directory));
+    }
+  }
+
   // Heap size should be aligned to alignment, too.
   guarantee(is_aligned(size, alignment), "set by caller");
 
@@ -585,6 +637,10 @@
   if (base() != NULL) {
     MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap);
   }
+
+  if (_fd_for_heap != -1) {
+    os::close(_fd_for_heap);
+  }
 }
 
 // Reserve space for code segment.  Same as Java heap only we mark this as
--- a/src/hotspot/share/memory/virtualspace.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/memory/virtualspace.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
   size_t _noaccess_prefix;
   size_t _alignment;
   bool   _special;
+  int    _fd_for_heap;
  private:
   bool   _executable;
 
@@ -115,7 +116,9 @@
   void establish_noaccess_prefix();
  public:
   // Constructor. Tries to find a heap that is good for compressed oops.
-  ReservedHeapSpace(size_t size, size_t forced_base_alignment, bool large);
+  // heap_allocation_directory is the path to the backing memory for Java heap. When set, Java heap will be allocated
+  // on the device which is managed by the file system where the directory resides.
+  ReservedHeapSpace(size_t size, size_t forced_base_alignment, bool large, const char* heap_allocation_directory = NULL);
   // Returns the base to be used for compression, i.e. so that null can be
   // encoded safely and implicit null checks can work.
   char *compressed_oop_base() { return _base - _noaccess_prefix; }
--- a/src/hotspot/share/oops/array.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/oops/array.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,7 +26,6 @@
 #define SHARE_VM_OOPS_ARRAY_HPP
 
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "memory/metaspace.hpp"
 #include "runtime/orderAccess.hpp"
 #include "utilities/align.hpp"
--- a/src/hotspot/share/oops/constantPool.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/oops/constantPool.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "interpreter/linkResolver.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/heapInspection.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
@@ -2300,3 +2301,11 @@
   }
   return NULL;
 }
+
+void SymbolHashMap::initialize_table(int table_size) {
+  _table_size = table_size;
+  _buckets = NEW_C_HEAP_ARRAY(SymbolHashMapBucket, table_size, mtSymbol);
+  for (int index = 0; index < table_size; index++) {
+    _buckets[index].clear();
+  }
+}
--- a/src/hotspot/share/oops/constantPool.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/oops/constantPool.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -982,13 +982,7 @@
   int                   _table_size;
   SymbolHashMapBucket*  _buckets;
 
-  void initialize_table(int table_size) {
-    _table_size = table_size;
-    _buckets = NEW_C_HEAP_ARRAY(SymbolHashMapBucket, table_size, mtSymbol);
-    for (int index = 0; index < table_size; index++) {
-      _buckets[index].clear();
-    }
-  }
+  void initialize_table(int table_size);
 
  public:
 
--- a/src/hotspot/share/oops/generateOopMap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/oops/generateOopMap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 #include "interpreter/bytecodeStream.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
+#include "memory/allocation.inline.hpp"
 #include "oops/generateOopMap.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
@@ -217,6 +218,12 @@
 int RetTable::_init_nof_entries = 10;
 int RetTableEntry::_init_nof_jsrs = 5;
 
+RetTableEntry::RetTableEntry(int target, RetTableEntry *next) {
+  _target_bci = target;
+  _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs);
+  _next = next;
+}
+
 void RetTableEntry::add_delta(int bci, int delta) {
   if (_target_bci > bci) _target_bci += delta;
 
--- a/src/hotspot/share/oops/generateOopMap.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/oops/generateOopMap.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,7 +26,7 @@
 #define SHARE_VM_OOPS_GENERATEOOPMAP_HPP
 
 #include "interpreter/bytecodeStream.hpp"
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/method.hpp"
 #include "oops/oopsHierarchy.hpp"
@@ -57,7 +57,7 @@
   GrowableArray<intptr_t> * _jsrs;                     // List of return addresses  (bytecode index)
   RetTableEntry *_next;                           // Link to next entry
  public:
-   RetTableEntry(int target, RetTableEntry *next)  { _target_bci=target; _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs); _next = next;  }
+   RetTableEntry(int target, RetTableEntry *next);
 
   // Query
   int target_bci() const                      { return _target_bci; }
--- a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -71,10 +71,15 @@
         Devirtualizer<nv>::do_klass(closure, klass);
       }
     } else {
-      // If klass is NULL then this a mirror for a primitive type.
-      // We don't have to follow them, since they are handled as strong
-      // roots in Universe::oops_do.
-      assert(java_lang_Class::is_primitive(obj), "Sanity check");
+      // We would like to assert here (as below) that if klass has been NULL, then
+      // this has been a mirror for a primitive type that we do not need to follow
+      // as they are always strong roots.
+      // However, we might get across a klass that just changed during CMS concurrent
+      // marking if allocation occurred in the old generation.
+      // This is benign here, as we keep alive all CLDs that were loaded during the
+      // CMS concurrent phase in the class loading, i.e. they will be iterated over
+      // and kept alive during remark.
+      // assert(java_lang_Class::is_primitive(obj), "Sanity check");
     }
   }
 
--- a/src/hotspot/share/opto/c2_globals.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/c2_globals.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -740,6 +740,14 @@
                                                                             \
   develop(bool, RenumberLiveNodes, true,                                    \
           "Renumber live nodes")                                            \
+                                                                            \
+  product(uintx, LoopStripMiningIter, 0,                                    \
+          "Number of iterations in strip mined loop")                       \
+          range(0, max_juint)                                               \
+                                                                            \
+  product(uintx, LoopStripMiningIterShortLoop, 0,                           \
+          "Loop with fewer iterations are not strip mined")                 \
+          range(0, max_juint)                                               \
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, \
          DECLARE_PD_DEVELOPER_FLAG, \
--- a/src/hotspot/share/opto/callGenerator.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/callGenerator.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -362,6 +362,20 @@
     return;
   }
 
+  // check for unreachable loop
+  CallProjections callprojs;
+  call->extract_projections(&callprojs, true);
+  if (callprojs.fallthrough_catchproj == call->in(0) ||
+      callprojs.catchall_catchproj == call->in(0) ||
+      callprojs.fallthrough_memproj == call->in(TypeFunc::Memory) ||
+      callprojs.catchall_memproj == call->in(TypeFunc::Memory) ||
+      callprojs.fallthrough_ioproj == call->in(TypeFunc::I_O) ||
+      callprojs.catchall_ioproj == call->in(TypeFunc::I_O) ||
+      (callprojs.resproj != NULL && call->find_edge(callprojs.resproj) != -1) ||
+      (callprojs.exobj != NULL && call->find_edge(callprojs.exobj) != -1)) {
+    return;
+  }
+
   Compile* C = Compile::current();
   // Remove inlined methods from Compiler's lists.
   if (call->is_macro()) {
--- a/src/hotspot/share/opto/cfgnode.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/cfgnode.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -571,6 +571,18 @@
       return NULL;
     } else if (can_reshape) {   // Optimization phase - remove the node
       PhaseIterGVN *igvn = phase->is_IterGVN();
+      // Strip mined (inner) loop is going away, remove outer loop.
+      if (is_CountedLoop() &&
+          as_Loop()->is_strip_mined()) {
+        Node* outer_sfpt = as_CountedLoop()->outer_safepoint();
+        Node* outer_out = as_CountedLoop()->outer_loop_exit();
+        if (outer_sfpt != NULL && outer_out != NULL) {
+          Node* in = outer_sfpt->in(0);
+          igvn->replace_node(outer_out, in);
+          LoopNode* outer = as_CountedLoop()->outer_loop();
+          igvn->replace_input_of(outer, LoopNode::LoopBackControl, igvn->C->top());
+        }
+      }
       Node *parent_ctrl;
       if( cnt == 0 ) {
         assert( req() == 1, "no inputs expected" );
--- a/src/hotspot/share/opto/classes.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/classes.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -133,6 +133,8 @@
 macro(ConvL2I)
 macro(CountedLoop)
 macro(CountedLoopEnd)
+macro(OuterStripMinedLoop)
+macro(OuterStripMinedLoopEnd)
 macro(CountLeadingZerosI)
 macro(CountLeadingZerosL)
 macro(CountTrailingZerosI)
@@ -252,6 +254,7 @@
 macro(SafePointScalarObject)
 macro(SCMemProj)
 macro(SqrtD)
+macro(SqrtF)
 macro(Start)
 macro(StartOSR)
 macro(StoreB)
@@ -320,6 +323,7 @@
 macro(NegVF)
 macro(NegVD)
 macro(SqrtVD)
+macro(SqrtVF)
 macro(LShiftCntV)
 macro(RShiftCntV)
 macro(LShiftVB)
--- a/src/hotspot/share/opto/compile.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/compile.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -2751,27 +2751,28 @@
   case Op_CallRuntime:
   case Op_CallLeaf:
   case Op_CallLeafNoFP: {
-    assert( n->is_Call(), "" );
+    assert (n->is_Call(), "");
     CallNode *call = n->as_Call();
     // Count call sites where the FP mode bit would have to be flipped.
     // Do not count uncommon runtime calls:
     // uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking,
     // _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ...
-    if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) {
+    if (!call->is_CallStaticJava() || !call->as_CallStaticJava()->_name) {
       frc.inc_call_count();   // Count the call site
     } else {                  // See if uncommon argument is shared
       Node *n = call->in(TypeFunc::Parms);
       int nop = n->Opcode();
       // Clone shared simple arguments to uncommon calls, item (1).
-      if( n->outcnt() > 1 &&
+      if (n->outcnt() > 1 &&
           !n->is_Proj() &&
           nop != Op_CreateEx &&
           nop != Op_CheckCastPP &&
           nop != Op_DecodeN &&
           nop != Op_DecodeNKlass &&
-          !n->is_Mem() ) {
+          !n->is_Mem() &&
+          !n->is_Phi()) {
         Node *x = n->clone();
-        call->set_req( TypeFunc::Parms, x );
+        call->set_req(TypeFunc::Parms, x);
       }
     }
     break;
@@ -3244,9 +3245,11 @@
     break;
   case Op_Loop:
   case Op_CountedLoop:
+  case Op_OuterStripMinedLoop:
     if (n->as_Loop()->is_inner_loop()) {
       frc.inc_inner_loop_count();
     }
+    n->as_Loop()->verify_strip_mined(0);
     break;
   case Op_LShiftI:
   case Op_RShiftI:
@@ -3525,6 +3528,14 @@
         record_method_not_compilable("infinite loop");
         return true;            // Found unvisited kid; must be unreach
       }
+
+    // Here so verification code in final_graph_reshaping_walk()
+    // always see an OuterStripMinedLoopEnd
+    if (n->is_OuterStripMinedLoopEnd()) {
+      IfNode* init_iff = n->as_If();
+      Node* iff = new IfNode(init_iff->in(0), init_iff->in(1), init_iff->_prob, init_iff->_fcnt);
+      n->subsume_by(iff, this);
+    }
   }
 
   // If original bytecodes contained a mixture of floats and doubles
--- a/src/hotspot/share/opto/convertnode.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/convertnode.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -73,6 +73,21 @@
   return TypeF::make( (float)td->getd() );
 }
 
+//------------------------------Ideal------------------------------------------
+// If we see pattern ConvF2D SomeDoubleOp ConvD2F, do operation as float.
+Node *ConvD2FNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+  if ( in(1)->Opcode() == Op_SqrtD ) {
+    Node* sqrtd = in(1);
+    if ( sqrtd->in(1)->Opcode() == Op_ConvF2D ) {
+      if ( Matcher::match_rule_supported(Op_SqrtF) ) {
+        Node* convf2d = sqrtd->in(1);
+        return new SqrtFNode(phase->C, sqrtd->in(0), convf2d->in(1));
+      }
+    }
+  }
+  return NULL;
+}
+
 //------------------------------Identity---------------------------------------
 // Float's can be converted to doubles with no loss of bits.  Hence
 // converting a float to a double and back to a float is a NOP.
--- a/src/hotspot/share/opto/convertnode.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/convertnode.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -51,6 +51,7 @@
   virtual const Type *bottom_type() const { return Type::FLOAT; }
   virtual const Type* Value(PhaseGVN* phase) const;
   virtual Node* Identity(PhaseGVN* phase);
+  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   virtual uint  ideal_reg() const { return Op_RegF; }
 };
 
--- a/src/hotspot/share/opto/idealGraphPrinter.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/idealGraphPrinter.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, 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
@@ -29,6 +29,7 @@
 #include "opto/machnode.hpp"
 #include "opto/parse.hpp"
 #include "runtime/threadCritical.hpp"
+#include "runtime/threadSMR.hpp"
 
 #ifndef PRODUCT
 
@@ -91,8 +92,7 @@
 }
 
 void IdealGraphPrinter::clean_up() {
-  JavaThread *p;
-  for (p = Threads::first(); p; p = p->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *p = jtiwh.next(); ) {
     if (p->is_Compiler_thread()) {
       CompilerThread *c = (CompilerThread *)p;
       IdealGraphPrinter *printer = c->ideal_graph_printer();
--- a/src/hotspot/share/opto/ifnode.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/ifnode.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -117,6 +117,7 @@
   // No intervening control, like a simple Call
   Node *r = iff->in(0);
   if( !r->is_Region() ) return NULL;
+  if (r->is_Loop() && r->in(LoopNode::LoopBackControl)->is_top()) return NULL; // going away anyway
   if( phi->region() != r ) return NULL;
   // No other users of the cmp/bool
   if (b->outcnt() != 1 || cmp->outcnt() != 1) {
--- a/src/hotspot/share/opto/loopPredicate.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/loopPredicate.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -515,8 +515,8 @@
     _visited(area), _invariant(area), _stack(area, 10 /* guess */),
     _clone_visited(area), _old_new(area)
   {
-    Node* head = _lpt->_head;
-    Node* entry = head->in(LoopNode::EntryControl);
+    LoopNode* head = _lpt->_head->as_Loop();
+    Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
     if (entry->outcnt() != 1) {
       // If a node is pinned between the predicates and the loop
       // entry, we won't be able to move any node in the loop that
@@ -801,6 +801,10 @@
     return false;
   }
 
+  if (head->is_OuterStripMinedLoop()) {
+    return false;
+  }
+
   CountedLoopNode *cl = NULL;
   if (head->is_valid_counted_loop()) {
     cl = head->as_CountedLoop();
@@ -812,7 +816,7 @@
       cl = NULL;
   }
 
-  Node* entry = head->in(LoopNode::EntryControl);
+  Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
   ProjNode *predicate_proj = NULL;
   // Loop limit check predicate should be near the loop.
   predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
@@ -1007,6 +1011,8 @@
   }
 #endif
 
+  head->verify_strip_mined(1);
+
   return hoisted;
 }
 
--- a/src/hotspot/share/opto/loopTransform.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/loopTransform.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -67,6 +67,16 @@
     Node *n = _body.at(i);
     _phase->_igvn._worklist.push(n);
   }
+  // put body of outer strip mined loop on igvn work list as well
+  if (_head->is_CountedLoop() && _head->as_Loop()->is_strip_mined()) {
+    CountedLoopNode* l = _head->as_CountedLoop();
+    _phase->_igvn._worklist.push(l->outer_loop());
+    _phase->_igvn._worklist.push(l->outer_loop_tail());
+    _phase->_igvn._worklist.push(l->outer_loop_end());
+    _phase->_igvn._worklist.push(l->outer_safepoint());
+    Node* cle_out = _head->as_CountedLoop()->loopexit()->proj_out(false);
+    _phase->_igvn._worklist.push(cle_out);
+  }
 }
 
 //------------------------------compute_exact_trip_count-----------------------
@@ -494,7 +504,7 @@
     loop->dump_head();
   }
 #endif
-  Node* head = loop->_head;
+  LoopNode* head = loop->_head->as_Loop();
   bool counted_loop = head->is_CountedLoop();
   if (counted_loop) {
     CountedLoopNode *cl = head->as_CountedLoop();
@@ -514,7 +524,7 @@
 
   // Step 1: Clone the loop body.  The clone becomes the peeled iteration.
   //         The pre-loop illegally has 2 control users (old & new loops).
-  clone_loop( loop, old_new, dom_depth(head) );
+  clone_loop(loop, old_new, dom_depth(head->skip_strip_mined()), ControlAroundStripMined);
 
   // Step 2: Make the old-loop fall-in edges point to the peeled iteration.
   //         Do this by making the old-loop fall-in edges act as if they came
@@ -523,8 +533,8 @@
   //         the pre-loop with only 1 user (the new peeled iteration), but the
   //         peeled-loop backedge has 2 users.
   Node* new_entry = old_new[head->in(LoopNode::LoopBackControl)->_idx];
-  _igvn.hash_delete(head);
-  head->set_req(LoopNode::EntryControl, new_entry);
+  _igvn.hash_delete(head->skip_strip_mined());
+  head->skip_strip_mined()->set_req(LoopNode::EntryControl, new_entry);
   for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
     Node* old = head->fast_out(j);
     if (old->in(0) == loop->_head && old->req() == 3 && old->is_Phi()) {
@@ -1009,8 +1019,6 @@
   CountedLoopEndNode *main_end = main_head->loopexit();
   guarantee(main_end != NULL, "no loop exit node");
   assert( main_end->outcnt() == 2, "1 true, 1 false path only" );
-  uint dd_main_head = dom_depth(main_head);
-  uint max = main_head->outcnt();
 
   Node *pre_header= main_head->in(LoopNode::EntryControl);
   Node *init      = main_head->init_trip();
@@ -1043,7 +1051,16 @@
 
   // Step B1: Clone the loop body.  The clone becomes the pre-loop.  The main
   // loop pre-header illegally has 2 control users (old & new loops).
-  clone_loop( loop, old_new, dd_main_head );
+  LoopNode* outer_main_head = main_head;
+  IdealLoopTree* outer_loop = loop;
+  if (main_head->is_strip_mined()) {
+    main_head->verify_strip_mined(1);
+    outer_main_head = main_head->outer_loop();
+    outer_loop = loop->_parent;
+    assert(outer_loop->_head == outer_main_head, "broken loop tree");
+  }
+  uint dd_main_head = dom_depth(outer_main_head);
+  clone_loop(loop, old_new, dd_main_head, ControlAroundStripMined);
   CountedLoopNode*    pre_head = old_new[main_head->_idx]->as_CountedLoop();
   CountedLoopEndNode* pre_end  = old_new[main_end ->_idx]->as_CountedLoopEnd();
   pre_head->set_pre_loop(main_head);
@@ -1058,7 +1075,7 @@
   IfFalseNode *new_pre_exit = new IfFalseNode(pre_end);
   _igvn.register_new_node_with_optimizer( new_pre_exit );
   set_idom(new_pre_exit, pre_end, dd_main_head);
-  set_loop(new_pre_exit, loop->_parent);
+  set_loop(new_pre_exit, outer_loop->_parent);
 
   // Step B2: Build a zero-trip guard for the main-loop.  After leaving the
   // pre-loop, the main-loop may not execute at all.  Later in life this
@@ -1075,22 +1092,22 @@
   IfNode *min_iff = new IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN );
   _igvn.register_new_node_with_optimizer( min_iff );
   set_idom(min_iff, new_pre_exit, dd_main_head);
-  set_loop(min_iff, loop->_parent);
+  set_loop(min_iff, outer_loop->_parent);
 
   // Plug in the false-path, taken if we need to skip main-loop
   _igvn.hash_delete( pre_exit );
   pre_exit->set_req(0, min_iff);
   set_idom(pre_exit, min_iff, dd_main_head);
-  set_idom(pre_exit->unique_out(), min_iff, dd_main_head);
+  set_idom(pre_exit->unique_ctrl_out(), min_iff, dd_main_head);
   // Make the true-path, must enter the main loop
   Node *min_taken = new IfTrueNode( min_iff );
   _igvn.register_new_node_with_optimizer( min_taken );
   set_idom(min_taken, min_iff, dd_main_head);
-  set_loop(min_taken, loop->_parent);
+  set_loop(min_taken, outer_loop->_parent);
   // Plug in the true path
-  _igvn.hash_delete( main_head );
-  main_head->set_req(LoopNode::EntryControl, min_taken);
-  set_idom(main_head, min_taken, dd_main_head);
+  _igvn.hash_delete(outer_main_head);
+  outer_main_head->set_req(LoopNode::EntryControl, min_taken);
+  set_idom(outer_main_head, min_taken, dd_main_head);
 
   Arena *a = Thread::current()->resource_area();
   VectorSet visited(a);
@@ -1102,7 +1119,7 @@
     if( main_phi->is_Phi() && main_phi->in(0) == main_head && main_phi->outcnt() > 0 ) {
       Node *pre_phi = old_new[main_phi->_idx];
       Node *fallpre  = clone_up_backedge_goo(pre_head->back_control(),
-                                             main_head->init_control(),
+                                             main_head->skip_strip_mined()->in(LoopNode::EntryControl),
                                              pre_phi->in(LoopNode::LoopBackControl),
                                              visited, clones);
       _igvn.hash_delete(main_phi);
@@ -1305,16 +1322,24 @@
 Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree *loop, Node_List &old_new,
                                        CountedLoopNode *main_head, CountedLoopEndNode *main_end,
                                        Node *incr, Node *limit, CountedLoopNode *&post_head) {
+  IfNode* outer_main_end = main_end;
+  IdealLoopTree* outer_loop = loop;
+  if (main_head->is_strip_mined()) {
+    main_head->verify_strip_mined(1);
+    outer_main_end = main_head->outer_loop_end();
+    outer_loop = loop->_parent;
+    assert(outer_loop->_head == main_head->in(LoopNode::EntryControl), "broken loop tree");
+  }
 
   //------------------------------
   // Step A: Create a new post-Loop.
-  Node* main_exit = main_end->proj_out(false);
+  Node* main_exit = outer_main_end->proj_out(false);
   assert(main_exit->Opcode() == Op_IfFalse, "");
   int dd_main_exit = dom_depth(main_exit);
 
   // Step A1: Clone the loop body of main. The clone becomes the post-loop.
   // The main loop pre-header illegally has 2 control users (old & new loops).
-  clone_loop(loop, old_new, dd_main_exit);
+  clone_loop(loop, old_new, dd_main_exit, ControlAroundStripMined);
   assert(old_new[main_end->_idx]->Opcode() == Op_CountedLoopEnd, "");
   post_head = old_new[main_head->_idx]->as_CountedLoop();
   post_head->set_normal_loop();
@@ -1325,10 +1350,10 @@
   post_end->_prob = PROB_FAIR;
 
   // Build the main-loop normal exit.
-  IfFalseNode *new_main_exit = new IfFalseNode(main_end);
+  IfFalseNode *new_main_exit = new IfFalseNode(outer_main_end);
   _igvn.register_new_node_with_optimizer(new_main_exit);
-  set_idom(new_main_exit, main_end, dd_main_exit);
-  set_loop(new_main_exit, loop->_parent);
+  set_idom(new_main_exit, outer_main_end, dd_main_exit);
+  set_loop(new_main_exit, outer_loop->_parent);
 
   // Step A2: Build a zero-trip guard for the post-loop.  After leaving the
   // main-loop, the post-loop may not execute at all.  We 'opaque' the incr
@@ -1346,7 +1371,7 @@
   IfNode *zer_iff = new IfNode(new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN);
   _igvn.register_new_node_with_optimizer(zer_iff);
   set_idom(zer_iff, new_main_exit, dd_main_exit);
-  set_loop(zer_iff, loop->_parent);
+  set_loop(zer_iff, outer_loop->_parent);
 
   // Plug in the false-path, taken if we need to skip this post-loop
   _igvn.replace_input_of(main_exit, 0, zer_iff);
@@ -1356,7 +1381,7 @@
   Node *zer_taken = new IfTrueNode(zer_iff);
   _igvn.register_new_node_with_optimizer(zer_taken);
   set_idom(zer_taken, zer_iff, dd_main_exit);
-  set_loop(zer_taken, loop->_parent);
+  set_loop(zer_taken, outer_loop->_parent);
   // Plug in the true path
   _igvn.hash_delete(post_head);
   post_head->set_req(LoopNode::EntryControl, zer_taken);
@@ -1431,7 +1456,7 @@
   // if rounds of unroll,optimize are making progress
   loop_head->set_node_count_before_unroll(loop->_body.size());
 
-  Node *ctrl  = loop_head->in(LoopNode::EntryControl);
+  Node *ctrl  = loop_head->skip_strip_mined()->in(LoopNode::EntryControl);
   Node *limit = loop_head->limit();
   Node *init  = loop_head->init_trip();
   Node *stride = loop_head->stride();
@@ -1610,7 +1635,7 @@
   // represents the odd iterations; since the loop trips an even number of
   // times its backedge is never taken.  Kill the backedge.
   uint dd = dom_depth(loop_head);
-  clone_loop( loop, old_new, dd );
+  clone_loop(loop, old_new, dd, IgnoreStripMined);
 
   // Make backedges of the clone equal to backedges of the original.
   // Make the fall-in from the original come from the fall-out of the clone.
@@ -1653,6 +1678,7 @@
   }
 
   loop->record_for_igvn();
+  loop_head->clear_strip_mined();
 
 #ifndef PRODUCT
   if (C->do_vector_loop() && (PrintOpto && (VerifyLoopOptimizations || TraceLoopOpts))) {
@@ -2047,7 +2073,7 @@
   }
 
   // Need to find the main-loop zero-trip guard
-  Node *ctrl  = cl->in(LoopNode::EntryControl);
+  Node *ctrl  = cl->skip_strip_mined()->in(LoopNode::EntryControl);
   Node *iffm = ctrl->in(0);
   Node *opqzm = iffm->in(1)->in(1)->in(2);
   assert(opqzm->in(1) == main_limit, "do not understand situation");
@@ -2413,7 +2439,6 @@
     _igvn.register_new_node_with_optimizer(cur_min);
     Node *cmp_node = rce_loop_end->cmp_node();
     _igvn.replace_input_of(cmp_node, 2, cur_min);
-    set_idom(cmp_node, cur_min, dom_depth(ctrl));
     set_ctrl(cur_min, ctrl);
     set_loop(cur_min, rce_loop->_parent);
 
@@ -2519,7 +2544,7 @@
 
 #ifdef ASSERT
 static CountedLoopNode* locate_pre_from_main(CountedLoopNode *cl) {
-  Node *ctrl  = cl->in(LoopNode::EntryControl);
+  Node *ctrl  = cl->skip_strip_mined()->in(LoopNode::EntryControl);
   assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "");
   Node *iffm = ctrl->in(0);
   assert(iffm->Opcode() == Op_If, "");
@@ -2558,7 +2583,7 @@
   }
 
   assert(locate_pre_from_main(main_head) == cl, "bad main loop");
-  Node* main_iff = main_head->in(LoopNode::EntryControl)->in(0);
+  Node* main_iff = main_head->skip_strip_mined()->in(LoopNode::EntryControl)->in(0);
 
   // Remove the Opaque1Node of the pre loop and make it execute all iterations
   phase->_igvn.replace_input_of(pre_cmp, 2, pre_cmp->in(2)->in(2));
@@ -2619,7 +2644,7 @@
   }
   if (needs_guard) {
     // Check for an obvious zero trip guard.
-    Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->in(LoopNode::EntryControl));
+    Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->skip_strip_mined()->in(LoopNode::EntryControl));
     if (inctrl->Opcode() == Op_IfTrue || inctrl->Opcode() == Op_IfFalse) {
       bool maybe_swapped = (inctrl->Opcode() == Op_IfFalse);
       // The test should look like just the backedge of a CountedLoop
@@ -3167,6 +3192,8 @@
     return false;
   }
 
+  head->verify_strip_mined(1);
+
   // Check that the body only contains a store of a loop invariant
   // value that is indexed by the loop phi.
   Node* store = NULL;
@@ -3288,6 +3315,16 @@
   }
 */
 
+  if (head->is_strip_mined()) {
+    // Inner strip mined loop goes away so get rid of outer strip
+    // mined loop
+    Node* outer_sfpt = head->outer_safepoint();
+    Node* in = outer_sfpt->in(0);
+    Node* outer_out = head->outer_loop_exit();
+    lazy_replace(outer_out, in);
+    _igvn.replace_input_of(outer_sfpt, 0, C->top());
+  }
+
   // Redirect the old control and memory edges that are outside the loop.
   // Sometimes the memory phi of the head is used as the outgoing
   // state of the loop.  It's safe in this case to replace it with the
--- a/src/hotspot/share/opto/loopUnswitch.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/loopUnswitch.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -132,11 +132,11 @@
     head->as_CountedLoop()->set_normal_loop();
   }
 
-  ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode());
+  ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode(), CloneIncludesStripMined);
 
 #ifdef ASSERT
   Node* uniqc = proj_true->unique_ctrl_out();
-  Node* entry = head->in(LoopNode::EntryControl);
+  Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
   Node* predicate = find_predicate(entry);
   if (predicate != NULL && UseLoopPredicate) {
     // We may have two predicates, find first.
@@ -145,7 +145,8 @@
   }
   if (predicate != NULL) predicate = predicate->in(0);
   assert(proj_true->is_IfTrue() &&
-         (predicate == NULL && uniqc == head ||
+         (predicate == NULL && uniqc == head && !head->is_strip_mined() ||
+          predicate == NULL && uniqc == head->in(LoopNode::EntryControl) && head->is_strip_mined() ||
           predicate != NULL && uniqc == predicate), "by construction");
 #endif
   // Increment unswitch count
@@ -223,13 +224,16 @@
 // Return control projection of the entry to the fast version.
 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
                                                       Node_List &old_new,
-                                                      int opcode) {
+                                                      int opcode,
+                                                      CloneLoopMode mode) {
   LoopNode* head  = loop->_head->as_Loop();
   bool counted_loop = head->is_CountedLoop();
-  Node*     entry = head->in(LoopNode::EntryControl);
+  Node*     entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
   _igvn.rehash_node_delayed(entry);
   IdealLoopTree* outer_loop = loop->_parent;
 
+  head->verify_strip_mined(1);
+
   Node *cont      = _igvn.intcon(1);
   set_ctrl(cont, C->root());
   Node* opq       = new Opaque1Node(C, cont);
@@ -247,19 +251,21 @@
   // Clone the loop body.  The clone becomes the fast loop.  The
   // original pre-header will (illegally) have 3 control users
   // (old & new loops & new if).
-  clone_loop(loop, old_new, dom_depth(head), iff);
+  clone_loop(loop, old_new, dom_depth(head->skip_strip_mined()), mode, iff);
   assert(old_new[head->_idx]->is_Loop(), "" );
 
   // Fast (true) control
   Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
-  _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
-  set_idom(head, iffast_pred, dom_depth(head));
 
   // Slow (false) control
   Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
-  LoopNode* slow_head = old_new[head->_idx]->as_Loop();
-  _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred);
-  set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
+
+  Node* l = head->skip_strip_mined();
+  _igvn.replace_input_of(l, LoopNode::EntryControl, iffast_pred);
+  set_idom(l, iffast_pred, dom_depth(l));
+  LoopNode* slow_l = old_new[head->_idx]->as_Loop()->skip_strip_mined();
+  _igvn.replace_input_of(slow_l, LoopNode::EntryControl, ifslow_pred);
+  set_idom(slow_l, ifslow_pred, dom_depth(l));
 
   recompute_dom_depth();
 
@@ -270,9 +276,9 @@
   Node_List old_new;
   LoopNode* head  = loop->_head->as_Loop();
   bool counted_loop = head->is_CountedLoop();
-  Node*     entry = head->in(LoopNode::EntryControl);
+  Node*     entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
   _igvn.rehash_node_delayed(entry);
-  IdealLoopTree* outer_loop = loop->_parent;
+  IdealLoopTree* outer_loop = head->is_strip_mined() ? loop->_parent->_parent : loop->_parent;
 
   ConINode* const_1 = _igvn.intcon(1);
   set_ctrl(const_1, C->root());
@@ -286,7 +292,7 @@
   // Clone the loop body.  The clone becomes the fast loop.  The
   // original pre-header will (illegally) have 3 control users
   // (old & new loops & new if).
-  clone_loop(loop, old_new, dom_depth(head), iff);
+  clone_loop(loop, old_new, dom_depth(head), CloneIncludesStripMined, iff);
   assert(old_new[head->_idx]->is_Loop(), "" );
 
   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
@@ -303,9 +309,9 @@
 #endif
 
   // Fast (true) control
-  _igvn.replace_input_of(head, LoopNode::EntryControl, iffast);
+  _igvn.replace_input_of(head->skip_strip_mined(), LoopNode::EntryControl, iffast);
   // Slow (false) control
-  _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow);
+  _igvn.replace_input_of(slow_head->skip_strip_mined(), LoopNode::EntryControl, ifslow);
 
   recompute_dom_depth();
 
@@ -394,7 +400,7 @@
     return false;
   }
 
-  Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
+  Node* ifslow_pred = _lp_reserved->skip_strip_mined()->in(LoopNode::EntryControl);
 
   if (!ifslow_pred->is_IfFalse()) {
     return false;
--- a/src/hotspot/share/opto/loopnode.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/loopnode.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -261,8 +261,68 @@
   set_early_ctrl( n );
 }
 
+// Create a skeleton strip mined outer loop: a Loop head before the
+// inner strip mined loop, a safepoint and an exit condition guarded
+// by an opaque node after the inner strip mined loop with a backedge
+// to the loop head. The inner strip mined loop is left as it is. Only
+// once loop optimizations are over, do we adjust the inner loop exit
+// condition to limit its number of iterations, set the outer loop
+// exit condition and add Phis to the outer loop head. Some loop
+// optimizations that operate on the inner strip mined loop need to be
+// aware of the outer strip mined loop: loop unswitching needs to
+// clone the outer loop as well as the inner, unrolling needs to only
+// clone the inner loop etc. No optimizations need to change the outer
+// strip mined loop as it is only a skeleton.
+IdealLoopTree* PhaseIdealLoop::create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control,
+                                                             IdealLoopTree* loop, float cl_prob, float le_fcnt,
+                                                             Node*& entry_control, Node*& iffalse) {
+  Node* outer_test = _igvn.intcon(0);
+  set_ctrl(outer_test, C->root());
+  Node *orig = iffalse;
+  iffalse = iffalse->clone();
+  _igvn.register_new_node_with_optimizer(iffalse);
+  set_idom(iffalse, idom(orig), dom_depth(orig));
+
+  IfNode *outer_le = new OuterStripMinedLoopEndNode(iffalse, outer_test, cl_prob, le_fcnt);
+  Node *outer_ift = new IfTrueNode (outer_le);
+  Node* outer_iff = orig;
+  _igvn.replace_input_of(outer_iff, 0, outer_le);
+
+  LoopNode *outer_l = new OuterStripMinedLoopNode(C, init_control, outer_ift);
+  entry_control = outer_l;
+
+  IdealLoopTree* outer_ilt = new IdealLoopTree(this, outer_l, outer_ift);
+  IdealLoopTree* parent = loop->_parent;
+  IdealLoopTree* sibling = parent->_child;
+  if (sibling == loop) {
+    parent->_child = outer_ilt;
+  } else {
+    while (sibling->_next != loop) {
+      sibling = sibling->_next;
+    }
+    sibling->_next = outer_ilt;
+  }
+  outer_ilt->_next = loop->_next;
+  outer_ilt->_parent = parent;
+  outer_ilt->_child = loop;
+  outer_ilt->_nest = loop->_nest;
+  loop->_parent = outer_ilt;
+  loop->_next = NULL;
+  loop->_nest++;
+
+  set_loop(iffalse, outer_ilt);
+  register_control(outer_le, outer_ilt, iffalse);
+  register_control(outer_ift, outer_ilt, outer_le);
+  set_idom(outer_iff, outer_le, dom_depth(outer_le));
+  _igvn.register_new_node_with_optimizer(outer_l);
+  set_loop(outer_l, outer_ilt);
+  set_idom(outer_l, init_control, dom_depth(init_control)+1);
+
+  return outer_ilt;
+}
+
 //------------------------------is_counted_loop--------------------------------
-bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
+bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
   PhaseGVN *gvn = &_igvn;
 
   // Counted loop head must be a good RegionNode with only 3 not NULL
@@ -280,7 +340,7 @@
 
   // Allow funny placement of Safepoint
   if (back_control->Opcode() == Op_SafePoint) {
-    if (UseCountedLoopSafepoints) {
+    if (LoopStripMiningIter != 0) {
       // Leaving the safepoint on the backedge and creating a
       // CountedLoop will confuse optimizations. We can't move the
       // safepoint around because its jvm state wouldn't match a new
@@ -600,7 +660,7 @@
   }
   set_subtree_ctrl( limit );
 
-  if (!UseCountedLoopSafepoints) {
+  if (LoopStripMiningIter == 0) {
     // Check for SafePoint on backedge and remove
     Node *sfpt = x->in(LoopNode::LoopBackControl);
     if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
@@ -683,8 +743,20 @@
   assert(iff->outcnt() == 0, "should be dead now");
   lazy_replace( iff, le ); // fix 'get_ctrl'
 
+  Node *sfpt2 = le->in(0);
+
+  Node* entry_control = init_control;
+  bool strip_mine_loop = LoopStripMiningIter > 1 && loop->_child == NULL &&
+    sfpt2->Opcode() == Op_SafePoint && !loop->_has_call;
+  IdealLoopTree* outer_ilt = NULL;
+  if (strip_mine_loop) {
+    outer_ilt = create_outer_strip_mined_loop(test, cmp, init_control, loop,
+                                              cl_prob, le->_fcnt, entry_control,
+                                              iffalse);
+  }
+
   // Now setup a new CountedLoopNode to replace the existing LoopNode
-  CountedLoopNode *l = new CountedLoopNode(init_control, back_control);
+  CountedLoopNode *l = new CountedLoopNode(entry_control, back_control);
   l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve
   // The following assert is approximately true, and defines the intention
   // of can_be_counted_loop.  It fails, however, because phase->type
@@ -696,12 +768,19 @@
   // Fix all data nodes placed at the old loop head.
   // Uses the lazy-update mechanism of 'get_ctrl'.
   lazy_replace( x, l );
-  set_idom(l, init_control, dom_depth(x));
-
-  if (!UseCountedLoopSafepoints) {
+  set_idom(l, entry_control, dom_depth(entry_control) + 1);
+
+  if (LoopStripMiningIter == 0 || strip_mine_loop) {
     // Check for immediately preceding SafePoint and remove
-    Node *sfpt2 = le->in(0);
-    if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
+    if (sfpt2->Opcode() == Op_SafePoint && (LoopStripMiningIter != 0 || is_deleteable_safept(sfpt2))) {
+      if (strip_mine_loop) {
+        Node* outer_le = outer_ilt->_tail->in(0);
+        Node* sfpt = sfpt2->clone();
+        sfpt->set_req(0, iffalse);
+        outer_le->set_req(0, sfpt);
+        register_control(sfpt, outer_ilt, iffalse);
+        set_idom(outer_le, sfpt, dom_depth(sfpt));
+      }
       lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
       if (loop->_safepts != NULL) {
         loop->_safepts->yank(sfpt2);
@@ -730,6 +809,13 @@
   // bounds
   l->phi()->as_Phi()->set_type(l->phi()->Value(&_igvn));
 
+  if (strip_mine_loop) {
+    l->mark_strip_mined();
+    l->verify_strip_mined(1);
+    outer_ilt->_head->as_Loop()->verify_strip_mined(1);
+    loop = outer_ilt;
+  }
+
   return true;
 }
 
@@ -776,12 +862,93 @@
 // Return a node which is more "ideal" than the current node.
 // Attempt to convert into a counted-loop.
 Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) {
-  if (!can_be_counted_loop(phase)) {
+  if (!can_be_counted_loop(phase) && !is_OuterStripMinedLoop()) {
     phase->C->set_major_progress();
   }
   return RegionNode::Ideal(phase, can_reshape);
 }
 
+void LoopNode::verify_strip_mined(int expect_skeleton) const {
+#ifdef ASSERT
+  const OuterStripMinedLoopNode* outer = NULL;
+  const CountedLoopNode* inner = NULL;
+  if (is_strip_mined()) {
+    assert(is_CountedLoop(), "no Loop should be marked strip mined");
+    inner = as_CountedLoop();
+    outer = inner->in(LoopNode::EntryControl)->as_OuterStripMinedLoop();
+  } else if (is_OuterStripMinedLoop()) {
+    outer = this->as_OuterStripMinedLoop();
+    inner = outer->unique_ctrl_out()->as_CountedLoop();
+    assert(!is_strip_mined(), "outer loop shouldn't be marked strip mined");
+  }
+  if (inner != NULL || outer != NULL) {
+    assert(inner != NULL && outer != NULL, "missing loop in strip mined nest");
+    Node* outer_tail = outer->in(LoopNode::LoopBackControl);
+    Node* outer_le = outer_tail->in(0);
+    assert(outer_le->Opcode() == Op_OuterStripMinedLoopEnd, "tail of outer loop should be an If");
+    Node* sfpt = outer_le->in(0);
+    assert(sfpt->Opcode() == Op_SafePoint, "where's the safepoint?");
+    Node* inner_out = sfpt->in(0);
+    if (inner_out->outcnt() != 1) {
+      ResourceMark rm;
+      Unique_Node_List wq;
+
+      for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) {
+        Node* u = inner_out->fast_out(i);
+        if (u == sfpt) {
+          continue;
+        }
+        wq.clear();
+        wq.push(u);
+        bool found_sfpt = false;
+        for (uint next = 0; next < wq.size() && !found_sfpt; next++) {
+          Node *n = wq.at(next);
+          for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !found_sfpt; i++) {
+            Node* u = n->fast_out(i);
+            if (u == sfpt) {
+              found_sfpt = true;
+            }
+            if (!u->is_CFG()) {
+              wq.push(u);
+            }
+          }
+        }
+        assert(found_sfpt, "no node in loop that's not input to safepoint");
+      }
+    }
+    CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd();
+    assert(cle == inner->loopexit(), "mismatch");
+    bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0;
+    if (has_skeleton) {
+      assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node");
+      assert(outer->outcnt() == 2, "only phis");
+    } else {
+      assert(expect_skeleton == 0 || expect_skeleton == -1, "no skeleton node?");
+      uint phis = 0;
+      for (DUIterator_Fast imax, i = inner->fast_outs(imax); i < imax; i++) {
+        Node* u = inner->fast_out(i);
+        if (u->is_Phi()) {
+          phis++;
+        }
+      }
+      for (DUIterator_Fast imax, i = outer->fast_outs(imax); i < imax; i++) {
+        Node* u = outer->fast_out(i);
+        assert(u == outer || u == inner || u->is_Phi(), "nothing between inner and outer loop");
+      }
+      uint stores = 0;
+      for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) {
+        Node* u = inner_out->fast_out(i);
+        if (u->is_Store()) {
+          stores++;
+        }
+      }
+      assert(outer->outcnt() >= phis + 2 && outer->outcnt() <= phis + 2 + stores + 1, "only phis");
+    }
+    assert(sfpt->outcnt() == 1, "no data node");
+    assert(outer_tail->outcnt() == 1 || !has_skeleton, "no data node");
+  }
+#endif
+}
 
 //=============================================================================
 //------------------------------Ideal------------------------------------------
@@ -802,6 +969,7 @@
   if (is_pre_loop ()) st->print("pre of N%d" , _main_idx);
   if (is_main_loop()) st->print("main of N%d", _idx);
   if (is_post_loop()) st->print("post of N%d", _main_idx);
+  if (is_strip_mined()) st->print(" strip mined");
 }
 #endif
 
@@ -990,6 +1158,365 @@
   return NULL;
 }
 
+LoopNode* CountedLoopNode::skip_strip_mined(int expect_opaq) {
+  if (is_strip_mined()) {
+    verify_strip_mined(expect_opaq);
+    return in(EntryControl)->as_Loop();
+  }
+  return this;
+}
+
+OuterStripMinedLoopNode* CountedLoopNode::outer_loop() const {
+  assert(is_strip_mined(), "not a strip mined loop");
+  Node* c = in(EntryControl);
+  if (c == NULL || c->is_top() || !c->is_OuterStripMinedLoop()) {
+    return NULL;
+  }
+  return c->as_OuterStripMinedLoop();
+}
+
+IfTrueNode* OuterStripMinedLoopNode::outer_loop_tail() const {
+  Node* c = in(LoopBackControl);
+  if (c == NULL || c->is_top()) {
+    return NULL;
+  }
+  return c->as_IfTrue();
+}
+
+IfTrueNode* CountedLoopNode::outer_loop_tail() const {
+  LoopNode* l = outer_loop();
+  if (l == NULL) {
+    return NULL;
+  }
+  return l->outer_loop_tail();
+}
+
+OuterStripMinedLoopEndNode* OuterStripMinedLoopNode::outer_loop_end() const {
+  IfTrueNode* proj = outer_loop_tail();
+  if (proj == NULL) {
+    return NULL;
+  }
+  Node* c = proj->in(0);
+  if (c == NULL || c->is_top() || c->outcnt() != 2) {
+    return NULL;
+  }
+  return c->as_OuterStripMinedLoopEnd();
+}
+
+OuterStripMinedLoopEndNode* CountedLoopNode::outer_loop_end() const {
+  LoopNode* l = outer_loop();
+  if (l == NULL) {
+    return NULL;
+  }
+  return l->outer_loop_end();
+}
+
+IfFalseNode* OuterStripMinedLoopNode::outer_loop_exit() const {
+  IfNode* le = outer_loop_end();
+  if (le == NULL) {
+    return NULL;
+  }
+  Node* c = le->proj_out(false);
+  if (c == NULL) {
+    return NULL;
+  }
+  return c->as_IfFalse();
+}
+
+IfFalseNode* CountedLoopNode::outer_loop_exit() const {
+  LoopNode* l = outer_loop();
+  if (l == NULL) {
+    return NULL;
+  }
+  return l->outer_loop_exit();
+}
+
+SafePointNode* OuterStripMinedLoopNode::outer_safepoint() const {
+  IfNode* le = outer_loop_end();
+  if (le == NULL) {
+    return NULL;
+  }
+  Node* c = le->in(0);
+  if (c == NULL || c->is_top()) {
+    return NULL;
+  }
+  assert(c->Opcode() == Op_SafePoint, "broken outer loop");
+  return c->as_SafePoint();
+}
+
+SafePointNode* CountedLoopNode::outer_safepoint() const {
+  LoopNode* l = outer_loop();
+  if (l == NULL) {
+    return NULL;
+  }
+  return l->outer_safepoint();
+}
+
+void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
+  // Look for the outer & inner strip mined loop, reduce number of
+  // iterations of the inner loop, set exit condition of outer loop,
+  // construct required phi nodes for outer loop.
+  CountedLoopNode* inner_cl = unique_ctrl_out()->as_CountedLoop();
+  assert(inner_cl->is_strip_mined(), "inner loop should be strip mined");
+  Node* inner_iv_phi = inner_cl->phi();
+  if (inner_iv_phi == NULL) {
+    return;
+  }
+  CountedLoopEndNode* inner_cle = inner_cl->loopexit();
+
+  int stride = inner_cl->stride_con();
+  jlong scaled_iters_long = ((jlong)LoopStripMiningIter) * ABS(stride);
+  int scaled_iters = (int)scaled_iters_long;
+  int short_scaled_iters = LoopStripMiningIterShortLoop* ABS(stride);
+  const TypeInt* inner_iv_t = igvn->type(inner_iv_phi)->is_int();
+  jlong iter_estimate = (jlong)inner_iv_t->_hi - (jlong)inner_iv_t->_lo;
+  assert(iter_estimate > 0, "broken");
+  if ((jlong)scaled_iters != scaled_iters_long || iter_estimate <= short_scaled_iters) {
+    // Remove outer loop and safepoint (too few iterations)
+    Node* outer_sfpt = outer_safepoint();
+    Node* outer_out = outer_loop_exit();
+    igvn->replace_node(outer_out, outer_sfpt->in(0));
+    igvn->replace_input_of(outer_sfpt, 0, igvn->C->top());
+    inner_cl->clear_strip_mined();
+    return;
+  }
+  if (iter_estimate <= scaled_iters_long) {
+    // We would only go through one iteration of
+    // the outer loop: drop the outer loop but
+    // keep the safepoint so we don't run for
+    // too long without a safepoint
+    IfNode* outer_le = outer_loop_end();
+    Node* iff = igvn->transform(new IfNode(outer_le->in(0), outer_le->in(1), outer_le->_prob, outer_le->_fcnt));
+    igvn->replace_node(outer_le, iff);
+    inner_cl->clear_strip_mined();
+    return;
+  }
+
+  Node* cle_tail = inner_cle->proj_out(true);
+  ResourceMark rm;
+  Node_List old_new;
+  if (cle_tail->outcnt() > 1) {
+    // Look for nodes on backedge of inner loop and clone them
+    Unique_Node_List backedge_nodes;
+    for (DUIterator_Fast imax, i = cle_tail->fast_outs(imax); i < imax; i++) {
+      Node* u = cle_tail->fast_out(i);
+      if (u != inner_cl) {
+        assert(!u->is_CFG(), "control flow on the backedge?");
+        backedge_nodes.push(u);
+      }
+    }
+    uint last = igvn->C->unique();
+    for (uint next = 0; next < backedge_nodes.size(); next++) {
+      Node* n = backedge_nodes.at(next);
+      old_new.map(n->_idx, n->clone());
+      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+        Node* u = n->fast_out(i);
+        assert(!u->is_CFG(), "broken");
+        if (u->_idx >= last) {
+          continue;
+        }
+        if (!u->is_Phi()) {
+          backedge_nodes.push(u);
+        } else {
+          assert(u->in(0) == inner_cl, "strange phi on the backedge");
+        }
+      }
+    }
+    // Put the clones on the outer loop backedge
+    Node* le_tail = outer_loop_tail();
+    for (uint next = 0; next < backedge_nodes.size(); next++) {
+      Node *n = old_new[backedge_nodes.at(next)->_idx];
+      for (uint i = 1; i < n->req(); i++) {
+        if (n->in(i) != NULL && old_new[n->in(i)->_idx] != NULL) {
+          n->set_req(i, old_new[n->in(i)->_idx]);
+        }
+      }
+      if (n->in(0) != NULL) {
+        assert(n->in(0) == cle_tail, "node not on backedge?");
+        n->set_req(0, le_tail);
+      }
+      igvn->register_new_node_with_optimizer(n);
+    }
+  }
+
+  Node* iv_phi = NULL;
+  // Make a clone of each phi in the inner loop
+  // for the outer loop
+  for (uint i = 0; i < inner_cl->outcnt(); i++) {
+    Node* u = inner_cl->raw_out(i);
+    if (u->is_Phi()) {
+      assert(u->in(0) == inner_cl, "inconsistent");
+      Node* phi = u->clone();
+      phi->set_req(0, this);
+      Node* be = old_new[phi->in(LoopNode::LoopBackControl)->_idx];
+      if (be != NULL) {
+        phi->set_req(LoopNode::LoopBackControl, be);
+      }
+      phi = igvn->transform(phi);
+      igvn->replace_input_of(u, LoopNode::EntryControl, phi);
+      if (u == inner_iv_phi) {
+        iv_phi = phi;
+      }
+    }
+  }
+  Node* cle_out = inner_cle->proj_out(false);
+  if (cle_out->outcnt() > 1) {
+    // Look for chains of stores that were sunk
+    // out of the inner loop and are in the outer loop
+    for (DUIterator_Fast imax, i = cle_out->fast_outs(imax); i < imax; i++) {
+      Node* u = cle_out->fast_out(i);
+      if (u->is_Store()) {
+        Node* first = u;
+        for(;;) {
+          Node* next = first->in(MemNode::Memory);
+          if (!next->is_Store() || next->in(0) != cle_out) {
+            break;
+          }
+          first = next;
+        }
+        Node* last = u;
+        for(;;) {
+          Node* next = NULL;
+          for (DUIterator_Fast jmax, j = last->fast_outs(jmax); j < jmax; j++) {
+            Node* uu = last->fast_out(j);
+            if (uu->is_Store() && uu->in(0) == cle_out) {
+              assert(next == NULL, "only one in the outer loop");
+              next = uu;
+            }
+          }
+          if (next == NULL) {
+            break;
+          }
+          last = next;
+        }
+        Node* phi = NULL;
+        for (DUIterator_Fast jmax, j = fast_outs(jmax); j < jmax; j++) {
+          Node* uu = fast_out(j);
+          if (uu->is_Phi()) {
+            Node* be = uu->in(LoopNode::LoopBackControl);
+            while (be->is_Store() && old_new[be->_idx] != NULL) {
+              ShouldNotReachHere();
+              be = be->in(MemNode::Memory);
+            }
+            if (be == last || be == first->in(MemNode::Memory)) {
+              assert(phi == NULL, "only one phi");
+              phi = uu;
+            }
+          }
+        }
+#ifdef ASSERT
+        for (DUIterator_Fast jmax, j = fast_outs(jmax); j < jmax; j++) {
+          Node* uu = fast_out(j);
+          if (uu->is_Phi() && uu->bottom_type() == Type::MEMORY) {
+            if (uu->adr_type() == igvn->C->get_adr_type(igvn->C->get_alias_index(u->adr_type()))) {
+              assert(phi == uu, "what's that phi?");
+            } else if (uu->adr_type() == TypePtr::BOTTOM) {
+              Node* n = uu->in(LoopNode::LoopBackControl);
+              uint limit = igvn->C->live_nodes();
+              uint i = 0;
+              while (n != uu) {
+                i++;
+                assert(i < limit, "infinite loop");
+                if (n->is_Proj()) {
+                  n = n->in(0);
+                } else if (n->is_SafePoint() || n->is_MemBar()) {
+                  n = n->in(TypeFunc::Memory);
+                } else if (n->is_Phi()) {
+                  n = n->in(1);
+                } else if (n->is_MergeMem()) {
+                  n = n->as_MergeMem()->memory_at(igvn->C->get_alias_index(u->adr_type()));
+                } else if (n->is_Store() || n->is_LoadStore() || n->is_ClearArray()) {
+                  n = n->in(MemNode::Memory);
+                } else {
+                  n->dump();
+                  ShouldNotReachHere();
+                }
+              }
+            }
+          }
+        }
+#endif
+        if (phi == NULL) {
+          // If the an entire chains was sunk, the
+          // inner loop has no phi for that memory
+          // slice, create one for the outer loop
+          phi = PhiNode::make(this, first->in(MemNode::Memory), Type::MEMORY,
+                              igvn->C->get_adr_type(igvn->C->get_alias_index(u->adr_type())));
+          phi->set_req(LoopNode::LoopBackControl, last);
+          phi = igvn->transform(phi);
+          igvn->replace_input_of(first, MemNode::Memory, phi);
+        } else {
+          // Or fix the outer loop fix to include
+          // that chain of stores.
+          Node* be = phi->in(LoopNode::LoopBackControl);
+          while (be->is_Store() && old_new[be->_idx] != NULL) {
+            ShouldNotReachHere();
+            be = be->in(MemNode::Memory);
+          }
+          if (be == first->in(MemNode::Memory)) {
+            if (be == phi->in(LoopNode::LoopBackControl)) {
+              igvn->replace_input_of(phi, LoopNode::LoopBackControl, last);
+            } else {
+              igvn->replace_input_of(be, MemNode::Memory, last);
+            }
+          } else {
+#ifdef ASSERT
+            if (be == phi->in(LoopNode::LoopBackControl)) {
+              assert(phi->in(LoopNode::LoopBackControl) == last, "");
+            } else {
+              assert(be->in(MemNode::Memory) == last, "");
+            }
+#endif
+          }
+        }
+      }
+    }
+  }
+
+  if (iv_phi != NULL) {
+    // Now adjust the inner loop's exit condition
+    Node* limit = inner_cl->limit();
+    Node* sub = NULL;
+    if (stride > 0) {
+      sub = igvn->transform(new SubINode(limit, iv_phi));
+    } else {
+      sub = igvn->transform(new SubINode(iv_phi, limit));
+    }
+    Node* min = igvn->transform(new MinINode(sub, igvn->intcon(scaled_iters)));
+    Node* new_limit = NULL;
+    if (stride > 0) {
+      new_limit = igvn->transform(new AddINode(min, iv_phi));
+    } else {
+      new_limit = igvn->transform(new SubINode(iv_phi, min));
+    }
+    igvn->replace_input_of(inner_cle->cmp_node(), 2, new_limit);
+    Node* cmp = inner_cle->cmp_node()->clone();
+    Node* bol = inner_cle->in(CountedLoopEndNode::TestValue)->clone();
+    cmp->set_req(2, limit);
+    bol->set_req(1, igvn->transform(cmp));
+    igvn->replace_input_of(outer_loop_end(), 1, igvn->transform(bol));
+  } else {
+    assert(false, "should be able to adjust outer loop");
+    IfNode* outer_le = outer_loop_end();
+    Node* iff = igvn->transform(new IfNode(outer_le->in(0), outer_le->in(1), outer_le->_prob, outer_le->_fcnt));
+    igvn->replace_node(outer_le, iff);
+    inner_cl->clear_strip_mined();
+  }
+}
+
+const Type* OuterStripMinedLoopEndNode::Value(PhaseGVN* phase) const {
+  if (!in(0)) return Type::TOP;
+  if (phase->type(in(0)) == Type::TOP)
+    return Type::TOP;
+
+  return TypeTuple::IFBOTH;
+}
+
+Node *OuterStripMinedLoopEndNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+  if (remove_dead_region(phase, can_reshape))  return this;
+
+  return NULL;
+}
 
 //------------------------------filtered_type--------------------------------
 // Return a type based on condition control flow
@@ -1778,10 +2305,11 @@
     if (_head->is_Loop()) _head->as_Loop()->set_inner_loop();
   }
 
+  IdealLoopTree* loop = this;
   if (_head->is_CountedLoop() ||
-      phase->is_counted_loop(_head, this)) {
-
-    if (!UseCountedLoopSafepoints) {
+      phase->is_counted_loop(_head, loop)) {
+
+    if (LoopStripMiningIter == 0 || (LoopStripMiningIter > 1 && _child == NULL)) {
       // Indicate we do not need a safepoint here
       _has_sfpt = 1;
     }
@@ -1800,8 +2328,10 @@
   }
 
   // Recursively
-  if (_child) _child->counted_loop( phase );
-  if (_next)  _next ->counted_loop( phase );
+  assert(loop->_child != this || (loop->_head->as_Loop()->is_OuterStripMinedLoop() && _head->as_CountedLoop()->is_strip_mined()), "what kind of loop was added?");
+  assert(loop->_child != this || (loop->_child->_child == NULL && loop->_child->_next == NULL), "would miss some loops");
+  if (loop->_child && loop->_child != this) loop->_child->counted_loop(phase);
+  if (loop->_next)  loop->_next ->counted_loop(phase);
 }
 
 #ifndef PRODUCT
@@ -1812,7 +2342,7 @@
     tty->print("  ");
   tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
   if (_irreducible) tty->print(" IRREDUCIBLE");
-  Node* entry = _head->in(LoopNode::EntryControl);
+  Node* entry = _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl);
   Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
   if (predicate != NULL ) {
     tty->print(" limit_check");
@@ -1863,6 +2393,9 @@
   if (Verbose) {
     tty->print(" body={"); _body.dump_simple(); tty->print(" }");
   }
+  if (_head->as_Loop()->is_strip_mined()) {
+    tty->print(" strip_mined");
+  }
   tty->cr();
 }
 
@@ -3232,7 +3765,7 @@
   if (!cl->is_main_loop() && !cl->is_post_loop()) {
     return false;
   }
-  Node* ctrl = cl->in(LoopNode::EntryControl);
+  Node* ctrl = cl->skip_strip_mined()->in(LoopNode::EntryControl);
   if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) {
     return false;
   }
@@ -3292,7 +3825,7 @@
     }
     while(worklist.size() != 0 && LCA != early) {
       Node* s = worklist.pop();
-      if (s->is_Load()) {
+      if (s->is_Load() || s->Opcode() == Op_SafePoint) {
         continue;
       } else if (s->is_MergeMem()) {
         for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
@@ -3471,6 +4004,38 @@
   }
 }
 
+// Verify that no data node is schedules in the outer loop of a strip
+// mined loop.
+void PhaseIdealLoop::verify_strip_mined_scheduling(Node *n, Node* least) {
+#ifdef ASSERT
+  if (get_loop(least)->_nest == 0) {
+    return;
+  }
+  IdealLoopTree* loop = get_loop(least);
+  Node* head = loop->_head;
+  if (head->is_OuterStripMinedLoop()) {
+    Node* sfpt = head->as_Loop()->outer_safepoint();
+    ResourceMark rm;
+    Unique_Node_List wq;
+    wq.push(sfpt);
+    for (uint i = 0; i < wq.size(); i++) {
+      Node *m = wq.at(i);
+      for (uint i = 1; i < m->req(); i++) {
+        Node* nn = m->in(i);
+        if (nn == n) {
+          return;
+        }
+        if (nn != NULL && has_ctrl(nn) && get_loop(get_ctrl(nn)) == loop) {
+          wq.push(nn);
+        }
+      }
+    }
+    ShouldNotReachHere();
+  }
+#endif
+}
+
+
 //------------------------------build_loop_late_post---------------------------
 // Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
 // Second pass finds latest legal placement, and ideal loop placement.
@@ -3580,8 +4145,9 @@
   // which can inhibit range check elimination.
   if (least != early) {
     Node* ctrl_out = least->unique_ctrl_out();
-    if (ctrl_out && ctrl_out->is_CountedLoop() &&
-        least == ctrl_out->in(LoopNode::EntryControl)) {
+    if (ctrl_out && ctrl_out->is_Loop() &&
+        least == ctrl_out->in(LoopNode::EntryControl) &&
+        (ctrl_out->is_CountedLoop() || ctrl_out->is_OuterStripMinedLoop())) {
       Node* least_dom = idom(least);
       if (get_loop(least_dom)->is_member(get_loop(least))) {
         least = least_dom;
@@ -3606,6 +4172,7 @@
 
   // Assign discovered "here or above" point
   least = find_non_split_ctrl(least);
+  verify_strip_mined_scheduling(n, least);
   set_ctrl(n, least);
 
   // Collect inner loop bodies
--- a/src/hotspot/share/opto/loopnode.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/loopnode.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 class IdealLoopTree;
 class LoopNode;
 class Node;
+class OuterStripMinedLoopEndNode;
 class PhaseIdealLoop;
 class CountedLoopReserveKit;
 class VectorSet;
@@ -71,7 +72,8 @@
          VectorizedLoop=2048,
          HasAtomicPostLoop=4096,
          HasRangeChecks=8192,
-         IsMultiversioned=16384};
+         IsMultiversioned=16384,
+         StripMined=32768};
   char _unswitch_count;
   enum { _unswitch_max=3 };
   char _postloop_flags;
@@ -90,6 +92,7 @@
   int is_partial_peel_loop() const { return _loop_flags & PartialPeelLoop; }
   void set_partial_peel_loop() { _loop_flags |= PartialPeelLoop; }
   int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; }
+  int is_strip_mined() const { return _loop_flags & StripMined; }
 
   void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
   void mark_has_reductions() { _loop_flags |= HasReductions; }
@@ -100,6 +103,8 @@
   void mark_has_atomic_post_loop() { _loop_flags |= HasAtomicPostLoop; }
   void mark_has_range_checks() { _loop_flags |=  HasRangeChecks; }
   void mark_is_multiversioned() { _loop_flags |= IsMultiversioned; }
+  void mark_strip_mined() { _loop_flags |= StripMined; }
+  void clear_strip_mined() { _loop_flags &= ~StripMined; }
 
   int unswitch_max() { return _unswitch_max; }
   int unswitch_count() { return _unswitch_count; }
@@ -131,6 +136,13 @@
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const;
 #endif
+
+  void verify_strip_mined(int expect_skeleton) const;
+  virtual LoopNode* skip_strip_mined(int expect_opaq = 1) { return this; }
+  virtual IfTrueNode* outer_loop_tail() const { ShouldNotReachHere(); return NULL; }
+  virtual OuterStripMinedLoopEndNode* outer_loop_end() const { ShouldNotReachHere(); return NULL; }
+  virtual IfFalseNode* outer_loop_exit() const { ShouldNotReachHere(); return NULL; }
+  virtual SafePointNode* outer_safepoint() const { ShouldNotReachHere(); return NULL; }
 };
 
 //------------------------------Counted Loops----------------------------------
@@ -278,6 +290,13 @@
   void set_slp_max_unroll(int unroll_factor) { _slp_maximum_unroll_factor = unroll_factor; }
   int  slp_max_unroll() const                { return _slp_maximum_unroll_factor; }
 
+  virtual LoopNode* skip_strip_mined(int expect_opaq = 1);
+  OuterStripMinedLoopNode* outer_loop() const;
+  virtual IfTrueNode* outer_loop_tail() const;
+  virtual OuterStripMinedLoopEndNode* outer_loop_end() const;
+  virtual IfFalseNode* outer_loop_exit() const;
+  virtual SafePointNode* outer_safepoint() const;
+
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const;
 #endif
@@ -374,6 +393,40 @@
   virtual Node* Identity(PhaseGVN* phase);
 };
 
+// Support for strip mining
+class OuterStripMinedLoopNode : public LoopNode {
+private:
+  CountedLoopNode* inner_loop() const;
+public:
+  OuterStripMinedLoopNode(Compile* C, Node *entry, Node *backedge)
+    : LoopNode(entry, backedge) {
+    init_class_id(Class_OuterStripMinedLoop);
+    init_flags(Flag_is_macro);
+    C->add_macro_node(this);
+  }
+
+  virtual int Opcode() const;
+
+  virtual IfTrueNode* outer_loop_tail() const;
+  virtual OuterStripMinedLoopEndNode* outer_loop_end() const;
+  virtual IfFalseNode* outer_loop_exit() const;
+  virtual SafePointNode* outer_safepoint() const;
+  void adjust_strip_mined_loop(PhaseIterGVN* igvn);
+};
+
+class OuterStripMinedLoopEndNode : public IfNode {
+public:
+  OuterStripMinedLoopEndNode(Node *control, Node *test, float prob, float cnt)
+    : IfNode(control, test, prob, cnt) {
+    init_class_id(Class_OuterStripMinedLoopEnd);
+  }
+
+  virtual int Opcode() const;
+
+  virtual const Type* Value(PhaseGVN* phase) const;
+  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+};
+
 // -----------------------------IdealLoopTree----------------------------------
 class IdealLoopTree : public ResourceObj {
 public:
@@ -780,6 +833,7 @@
   void build_loop_early( VectorSet &visited, Node_List &worklist, Node_Stack &nstack );
   void build_loop_late ( VectorSet &visited, Node_List &worklist, Node_Stack &nstack );
   void build_loop_late_post ( Node* n );
+  void verify_strip_mined_scheduling(Node *n, Node* least);
 
   // Array of immediate dominance info for each CFG node indexed by node idx
 private:
@@ -877,7 +931,10 @@
   // Per-Node transform
   virtual Node *transform( Node *a_node ) { return 0; }
 
-  bool is_counted_loop( Node *x, IdealLoopTree *loop );
+  bool is_counted_loop(Node* x, IdealLoopTree*& loop);
+  IdealLoopTree* create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control,
+                                               IdealLoopTree* loop, float cl_prob, float le_fcnt,
+                                               Node*& entry_control, Node*& iffalse);
 
   Node* exact_limit( IdealLoopTree *loop );
 
@@ -908,8 +965,24 @@
   //   When nonnull, the clone and original are side-by-side, both are
   //      dominated by the passed in side_by_side_idom node.  Used in
   //      construction of unswitched loops.
+  enum CloneLoopMode {
+    IgnoreStripMined = 0,        // Only clone inner strip mined loop
+    CloneIncludesStripMined = 1, // clone both inner and outer strip mined loops
+    ControlAroundStripMined = 2  // Only clone inner strip mined loop,
+                                 // result control flow branches
+                                 // either to inner clone or outer
+                                 // strip mined loop.
+  };
   void clone_loop( IdealLoopTree *loop, Node_List &old_new, int dom_depth,
-                   Node* side_by_side_idom = NULL);
+                  CloneLoopMode mode, Node* side_by_side_idom = NULL);
+  void clone_loop_handle_data_uses(Node* old, Node_List &old_new,
+                                   IdealLoopTree* loop, IdealLoopTree* companion_loop,
+                                   Node_List*& split_if_set, Node_List*& split_bool_set,
+                                   Node_List*& split_cex_set, Node_List& worklist,
+                                   uint new_counter, CloneLoopMode mode);
+  void clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealLoopTree *loop,
+                        IdealLoopTree* outer_loop, int dd, Node_List &old_new,
+                        Node_List& extra_data_nodes);
 
   // If we got the effect of peeling, either by actually peeling or by
   // making a pre-loop which must execute at least once, we can remove
@@ -1020,7 +1093,8 @@
   // and inserting an if to select fast-slow versions.
   ProjNode* create_slow_version_of_loop(IdealLoopTree *loop,
                                         Node_List &old_new,
-                                        int opcode);
+                                        int opcode,
+                                        CloneLoopMode mode);
 
   // Clone a loop and return the clone head (clone_loop_head).
   // Added nodes include int(1), int(0) - disconnected, If, IfTrue, IfFalse,
@@ -1098,7 +1172,7 @@
   // "Nearly" because all Nodes have been cloned from the original in the loop,
   // but the fall-in edges to the Cmp are different.  Clone bool/Cmp pairs
   // through the Phi recursively, and return a Bool.
-  BoolNode *clone_iff( PhiNode *phi, IdealLoopTree *loop );
+  Node *clone_iff( PhiNode *phi, IdealLoopTree *loop );
   CmpNode *clone_bool( PhiNode *phi, IdealLoopTree *loop );
 
 
--- a/src/hotspot/share/opto/loopopts.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/loopopts.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "opto/addnode.hpp"
+#include "opto/callnode.hpp"
 #include "opto/castnode.hpp"
 #include "opto/connode.hpp"
 #include "opto/castnode.hpp"
@@ -306,7 +307,12 @@
           get_ctrl(m->in(2)) != n_ctrl &&
           get_ctrl(m->in(3)) != n_ctrl) {
         // Move the AddP up to dominating point
-        set_ctrl_and_loop(m, find_non_split_ctrl(idom(n_ctrl)));
+        Node* c = find_non_split_ctrl(idom(n_ctrl));
+        if (c->is_OuterStripMinedLoop()) {
+          c->as_Loop()->verify_strip_mined(1);
+          c = c->in(LoopNode::EntryControl);
+        }
+        set_ctrl_and_loop(m, c);
         continue;
       }
       return NULL;
@@ -750,14 +756,13 @@
       if (ctrl_ok) {
         // move the Store
         _igvn.replace_input_of(mem, LoopNode::LoopBackControl, mem);
-        _igvn.replace_input_of(n, 0, n_loop->_head->in(LoopNode::EntryControl));
+        _igvn.replace_input_of(n, 0, n_loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl));
         _igvn.replace_input_of(n, MemNode::Memory, mem->in(LoopNode::EntryControl));
         // Disconnect the phi now. An empty phi can confuse other
         // optimizations in this pass of loop opts.
         _igvn.replace_node(mem, mem->in(LoopNode::EntryControl));
         n_loop->_body.yank(mem);
 
-        IdealLoopTree* new_loop = get_loop(n->in(0));
         set_ctrl_and_loop(n, n->in(0));
 
         return n;
@@ -840,6 +845,16 @@
               _igvn.replace_node(hook, n);
               return;
             }
+#ifdef ASSERT
+            if (n_loop->_head->is_Loop() && n_loop->_head->as_Loop()->is_strip_mined()) {
+              assert(n_loop->_head->Opcode() == Op_CountedLoop, "outer loop is a strip mined");
+              n_loop->_head->as_Loop()->verify_strip_mined(1);
+              Node* outer = n_loop->_head->as_CountedLoop()->outer_loop();
+              IdealLoopTree* outer_loop = get_loop(outer);
+              assert(n_loop->_parent == outer_loop, "broken loop tree");
+              assert(get_loop(lca) == outer_loop, "safepoint in outer loop consume all memory state");
+            }
+#endif
 
             // Move store out of the loop
             _igvn.replace_node(hook, n->in(MemNode::Memory));
@@ -1016,7 +1031,7 @@
   IdealLoopTree *u_loop = get_loop( useblock );
   return (u_loop->_irreducible || u_loop->_child)
     ? useblock
-    : u_loop->_head->in(LoopNode::EntryControl);
+    : u_loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl);
 }
 
 
@@ -1407,47 +1422,56 @@
 // "Nearly" because all Nodes have been cloned from the original in the loop,
 // but the fall-in edges to the Cmp are different.  Clone bool/Cmp pairs
 // through the Phi recursively, and return a Bool.
-BoolNode *PhaseIdealLoop::clone_iff( PhiNode *phi, IdealLoopTree *loop ) {
+Node* PhaseIdealLoop::clone_iff(PhiNode *phi, IdealLoopTree *loop) {
 
   // Convert this Phi into a Phi merging Bools
   uint i;
-  for( i = 1; i < phi->req(); i++ ) {
+  for (i = 1; i < phi->req(); i++) {
     Node *b = phi->in(i);
-    if( b->is_Phi() ) {
-      _igvn.replace_input_of(phi, i, clone_iff( b->as_Phi(), loop ));
+    if (b->is_Phi()) {
+      _igvn.replace_input_of(phi, i, clone_iff(b->as_Phi(), loop));
     } else {
-      assert( b->is_Bool(), "" );
+      assert(b->is_Bool() || b->Opcode() == Op_Opaque4, "");
     }
   }
 
-  Node *sample_bool = phi->in(1);
-  Node *sample_cmp  = sample_bool->in(1);
+  Node* n = phi->in(1);
+  Node* sample_opaque = NULL;
+  Node *sample_bool = NULL;
+  if (n->Opcode() == Op_Opaque4) {
+    sample_opaque = n;
+    sample_bool = n->in(1);
+    assert(sample_bool->is_Bool(), "wrong type");
+  } else {
+    sample_bool = n;
+  }
+  Node *sample_cmp = sample_bool->in(1);
 
   // Make Phis to merge the Cmp's inputs.
-  PhiNode *phi1 = new PhiNode( phi->in(0), Type::TOP );
-  PhiNode *phi2 = new PhiNode( phi->in(0), Type::TOP );
-  for( i = 1; i < phi->req(); i++ ) {
-    Node *n1 = phi->in(i)->in(1)->in(1);
-    Node *n2 = phi->in(i)->in(1)->in(2);
-    phi1->set_req( i, n1 );
-    phi2->set_req( i, n2 );
-    phi1->set_type( phi1->type()->meet_speculative(n1->bottom_type()));
-    phi2->set_type( phi2->type()->meet_speculative(n2->bottom_type()));
+  PhiNode *phi1 = new PhiNode(phi->in(0), Type::TOP);
+  PhiNode *phi2 = new PhiNode(phi->in(0), Type::TOP);
+  for (i = 1; i < phi->req(); i++) {
+    Node *n1 = sample_opaque == NULL ? phi->in(i)->in(1)->in(1) : phi->in(i)->in(1)->in(1)->in(1);
+    Node *n2 = sample_opaque == NULL ? phi->in(i)->in(1)->in(2) : phi->in(i)->in(1)->in(1)->in(2);
+    phi1->set_req(i, n1);
+    phi2->set_req(i, n2);
+    phi1->set_type(phi1->type()->meet_speculative(n1->bottom_type()));
+    phi2->set_type(phi2->type()->meet_speculative(n2->bottom_type()));
   }
   // See if these Phis have been made before.
   // Register with optimizer
   Node *hit1 = _igvn.hash_find_insert(phi1);
-  if( hit1 ) {                  // Hit, toss just made Phi
+  if (hit1) {                   // Hit, toss just made Phi
     _igvn.remove_dead_node(phi1); // Remove new phi
-    assert( hit1->is_Phi(), "" );
+    assert(hit1->is_Phi(), "" );
     phi1 = (PhiNode*)hit1;      // Use existing phi
   } else {                      // Miss
     _igvn.register_new_node_with_optimizer(phi1);
   }
   Node *hit2 = _igvn.hash_find_insert(phi2);
-  if( hit2 ) {                  // Hit, toss just made Phi
+  if (hit2) {                   // Hit, toss just made Phi
     _igvn.remove_dead_node(phi2); // Remove new phi
-    assert( hit2->is_Phi(), "" );
+    assert(hit2->is_Phi(), "" );
     phi2 = (PhiNode*)hit2;      // Use existing phi
   } else {                      // Miss
     _igvn.register_new_node_with_optimizer(phi2);
@@ -1457,8 +1481,8 @@
   set_ctrl(phi2, phi->in(0));
   // Make a new Cmp
   Node *cmp = sample_cmp->clone();
-  cmp->set_req( 1, phi1 );
-  cmp->set_req( 2, phi2 );
+  cmp->set_req(1, phi1);
+  cmp->set_req(2, phi2);
   _igvn.register_new_node_with_optimizer(cmp);
   set_ctrl(cmp, phi->in(0));
 
@@ -1468,8 +1492,16 @@
   _igvn.register_new_node_with_optimizer(b);
   set_ctrl(b, phi->in(0));
 
-  assert( b->is_Bool(), "" );
-  return (BoolNode*)b;
+  if (sample_opaque != NULL) {
+    Node* opaque = sample_opaque->clone();
+    opaque->set_req(1, b);
+    _igvn.register_new_node_with_optimizer(opaque);
+    set_ctrl(opaque, phi->in(0));
+    return opaque;
+  }
+
+  assert(b->is_Bool(), "");
+  return b;
 }
 
 //------------------------------clone_bool-------------------------------------
@@ -1552,6 +1584,252 @@
   }
 }
 
+void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
+                                                 IdealLoopTree* loop, IdealLoopTree* outer_loop,
+                                                 Node_List*& split_if_set, Node_List*& split_bool_set,
+                                                 Node_List*& split_cex_set, Node_List& worklist,
+                                                 uint new_counter, CloneLoopMode mode) {
+  Node* nnn = old_new[old->_idx];
+  // Copy uses to a worklist, so I can munge the def-use info
+  // with impunity.
+  for (DUIterator_Fast jmax, j = old->fast_outs(jmax); j < jmax; j++)
+    worklist.push(old->fast_out(j));
+
+  while( worklist.size() ) {
+    Node *use = worklist.pop();
+    if (!has_node(use))  continue; // Ignore dead nodes
+    if (use->in(0) == C->top())  continue;
+    IdealLoopTree *use_loop = get_loop( has_ctrl(use) ? get_ctrl(use) : use );
+    // Check for data-use outside of loop - at least one of OLD or USE
+    // must not be a CFG node.
+#ifdef ASSERT
+    if (loop->_head->as_Loop()->is_strip_mined() && outer_loop->is_member(use_loop) && !loop->is_member(use_loop) && old_new[use->_idx] == NULL) {
+      Node* sfpt = loop->_head->as_CountedLoop()->outer_safepoint();
+      assert(mode == ControlAroundStripMined && use == sfpt, "missed a node");
+    }
+#endif
+    if (!loop->is_member(use_loop) && !outer_loop->is_member(use_loop) && (!old->is_CFG() || !use->is_CFG())) {
+
+      // If the Data use is an IF, that means we have an IF outside of the
+      // loop that is switching on a condition that is set inside of the
+      // loop.  Happens if people set a loop-exit flag; then test the flag
+      // in the loop to break the loop, then test is again outside of the
+      // loop to determine which way the loop exited.
+      // Loop predicate If node connects to Bool node through Opaque1 node.
+      if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use) || use->Opcode() == Op_Opaque4) {
+        // Since this code is highly unlikely, we lazily build the worklist
+        // of such Nodes to go split.
+        if (!split_if_set) {
+          ResourceArea *area = Thread::current()->resource_area();
+          split_if_set = new Node_List(area);
+        }
+        split_if_set->push(use);
+      }
+      if (use->is_Bool()) {
+        if (!split_bool_set) {
+          ResourceArea *area = Thread::current()->resource_area();
+          split_bool_set = new Node_List(area);
+        }
+        split_bool_set->push(use);
+      }
+      if (use->Opcode() == Op_CreateEx) {
+        if (!split_cex_set) {
+          ResourceArea *area = Thread::current()->resource_area();
+          split_cex_set = new Node_List(area);
+        }
+        split_cex_set->push(use);
+      }
+
+
+      // Get "block" use is in
+      uint idx = 0;
+      while( use->in(idx) != old ) idx++;
+      Node *prev = use->is_CFG() ? use : get_ctrl(use);
+      assert(!loop->is_member(get_loop(prev)) && !outer_loop->is_member(get_loop(prev)), "" );
+      Node *cfg = prev->_idx >= new_counter
+        ? prev->in(2)
+        : idom(prev);
+      if( use->is_Phi() )     // Phi use is in prior block
+        cfg = prev->in(idx);  // NOT in block of Phi itself
+      if (cfg->is_top()) {    // Use is dead?
+        _igvn.replace_input_of(use, idx, C->top());
+        continue;
+      }
+
+      while(!outer_loop->is_member(get_loop(cfg))) {
+        prev = cfg;
+        cfg = cfg->_idx >= new_counter ? cfg->in(2) : idom(cfg);
+      }
+      // If the use occurs after merging several exits from the loop, then
+      // old value must have dominated all those exits.  Since the same old
+      // value was used on all those exits we did not need a Phi at this
+      // merge point.  NOW we do need a Phi here.  Each loop exit value
+      // is now merged with the peeled body exit; each exit gets its own
+      // private Phi and those Phis need to be merged here.
+      Node *phi;
+      if( prev->is_Region() ) {
+        if( idx == 0 ) {      // Updating control edge?
+          phi = prev;         // Just use existing control
+        } else {              // Else need a new Phi
+          phi = PhiNode::make( prev, old );
+          // Now recursively fix up the new uses of old!
+          for( uint i = 1; i < prev->req(); i++ ) {
+            worklist.push(phi); // Onto worklist once for each 'old' input
+          }
+        }
+      } else {
+        // Get new RegionNode merging old and new loop exits
+        prev = old_new[prev->_idx];
+        assert( prev, "just made this in step 7" );
+        if( idx == 0) {      // Updating control edge?
+          phi = prev;         // Just use existing control
+        } else {              // Else need a new Phi
+          // Make a new Phi merging data values properly
+          phi = PhiNode::make( prev, old );
+          phi->set_req( 1, nnn );
+        }
+      }
+      // If inserting a new Phi, check for prior hits
+      if( idx != 0 ) {
+        Node *hit = _igvn.hash_find_insert(phi);
+        if( hit == NULL ) {
+          _igvn.register_new_node_with_optimizer(phi); // Register new phi
+        } else {                                      // or
+          // Remove the new phi from the graph and use the hit
+          _igvn.remove_dead_node(phi);
+          phi = hit;                                  // Use existing phi
+        }
+        set_ctrl(phi, prev);
+      }
+      // Make 'use' use the Phi instead of the old loop body exit value
+      _igvn.replace_input_of(use, idx, phi);
+      if( use->_idx >= new_counter ) { // If updating new phis
+        // Not needed for correctness, but prevents a weak assert
+        // in AddPNode from tripping (when we end up with different
+        // base & derived Phis that will become the same after
+        // IGVN does CSE).
+        Node *hit = _igvn.hash_find_insert(use);
+        if( hit )             // Go ahead and re-hash for hits.
+          _igvn.replace_node( use, hit );
+      }
+
+      // If 'use' was in the loop-exit block, it now needs to be sunk
+      // below the post-loop merge point.
+      sink_use( use, prev );
+    }
+  }
+}
+
+void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealLoopTree *loop,
+                                      IdealLoopTree* outer_loop, int dd, Node_List &old_new,
+                                      Node_List& extra_data_nodes) {
+  if (head->is_strip_mined() && mode != IgnoreStripMined) {
+    CountedLoopNode* cl = head->as_CountedLoop();
+    Node* l = cl->outer_loop();
+    Node* tail = cl->outer_loop_tail();
+    IfNode* le = cl->outer_loop_end();
+    Node* sfpt = cl->outer_safepoint();
+    CountedLoopEndNode* cle = cl->loopexit();
+    CountedLoopNode* new_cl = old_new[cl->_idx]->as_CountedLoop();
+    CountedLoopEndNode* new_cle = new_cl->as_CountedLoop()->loopexit();
+    Node* cle_out = cle->proj_out(false);
+
+    Node* new_sfpt = NULL;
+    Node* new_cle_out = cle_out->clone();
+    old_new.map(cle_out->_idx, new_cle_out);
+    if (mode == CloneIncludesStripMined) {
+      // clone outer loop body
+      Node* new_l = l->clone();
+      Node* new_tail = tail->clone();
+      IfNode* new_le = le->clone()->as_If();
+      new_sfpt = sfpt->clone();
+
+      set_loop(new_l, outer_loop->_parent);
+      set_idom(new_l, new_l->in(LoopNode::EntryControl), dd);
+      set_loop(new_cle_out, outer_loop->_parent);
+      set_idom(new_cle_out, new_cle, dd);
+      set_loop(new_sfpt, outer_loop->_parent);
+      set_idom(new_sfpt, new_cle_out, dd);
+      set_loop(new_le, outer_loop->_parent);
+      set_idom(new_le, new_sfpt, dd);
+      set_loop(new_tail, outer_loop->_parent);
+      set_idom(new_tail, new_le, dd);
+      set_idom(new_cl, new_l, dd);
+
+      old_new.map(l->_idx, new_l);
+      old_new.map(tail->_idx, new_tail);
+      old_new.map(le->_idx, new_le);
+      old_new.map(sfpt->_idx, new_sfpt);
+
+      new_l->set_req(LoopNode::LoopBackControl, new_tail);
+      new_l->set_req(0, new_l);
+      new_tail->set_req(0, new_le);
+      new_le->set_req(0, new_sfpt);
+      new_sfpt->set_req(0, new_cle_out);
+      new_cle_out->set_req(0, new_cle);
+      new_cl->set_req(LoopNode::EntryControl, new_l);
+
+      _igvn.register_new_node_with_optimizer(new_l);
+      _igvn.register_new_node_with_optimizer(new_tail);
+      _igvn.register_new_node_with_optimizer(new_le);
+    } else {
+      Node *newhead = old_new[loop->_head->_idx];
+      newhead->as_Loop()->clear_strip_mined();
+      _igvn.replace_input_of(newhead, LoopNode::EntryControl, newhead->in(LoopNode::EntryControl)->in(LoopNode::EntryControl));
+      set_idom(newhead, newhead->in(LoopNode::EntryControl), dd);
+    }
+    // Look at data node that were assigned a control in the outer
+    // loop: they are kept in the outer loop by the safepoint so start
+    // from the safepoint node's inputs.
+    IdealLoopTree* outer_loop = get_loop(l);
+    Node_Stack stack(2);
+    stack.push(sfpt, 1);
+    uint new_counter = C->unique();
+    while (stack.size() > 0) {
+      Node* n = stack.node();
+      uint i = stack.index();
+      while (i < n->req() &&
+             (n->in(i) == NULL ||
+              !has_ctrl(n->in(i)) ||
+              get_loop(get_ctrl(n->in(i))) != outer_loop ||
+              (old_new[n->in(i)->_idx] != NULL && old_new[n->in(i)->_idx]->_idx >= new_counter))) {
+        i++;
+      }
+      if (i < n->req()) {
+        stack.set_index(i+1);
+        stack.push(n->in(i), 0);
+      } else {
+        assert(old_new[n->_idx] == NULL || n == sfpt || old_new[n->_idx]->_idx < new_counter, "no clone yet");
+        Node* m = n == sfpt ? new_sfpt : n->clone();
+        if (m != NULL) {
+          for (uint i = 0; i < n->req(); i++) {
+            if (m->in(i) != NULL && old_new[m->in(i)->_idx] != NULL) {
+              m->set_req(i, old_new[m->in(i)->_idx]);
+            }
+          }
+        } else {
+          assert(n == sfpt && mode != CloneIncludesStripMined, "where's the safepoint clone?");
+        }
+        if (n != sfpt) {
+          extra_data_nodes.push(n);
+          _igvn.register_new_node_with_optimizer(m);
+          assert(get_ctrl(n) == cle_out, "what other control?");
+          set_ctrl(m, new_cle_out);
+          old_new.map(n->_idx, m);
+        }
+        stack.pop();
+      }
+    }
+    if (mode == CloneIncludesStripMined) {
+      _igvn.register_new_node_with_optimizer(new_sfpt);
+      _igvn.register_new_node_with_optimizer(new_cle_out);
+    }
+  } else {
+    Node *newhead = old_new[loop->_head->_idx];
+    set_idom(newhead, newhead->in(LoopNode::EntryControl), dd);
+  }
+}
+
 //------------------------------clone_loop-------------------------------------
 //
 //                   C L O N E   A   L O O P   B O D Y
@@ -1580,7 +1858,10 @@
 //      dominated by the side_by_side_idom node.  Used in construction of
 //      unswitched loops.
 void PhaseIdealLoop::clone_loop( IdealLoopTree *loop, Node_List &old_new, int dd,
-                                 Node* side_by_side_idom) {
+                                CloneLoopMode mode, Node* side_by_side_idom) {
+
+  LoopNode* head = loop->_head->as_Loop();
+  head->verify_strip_mined(1);
 
   if (C->do_vector_loop() && PrintOpto) {
     const char* mname = C->method()->name()->as_quoted_ascii();
@@ -1613,6 +1894,7 @@
     _igvn.register_new_node_with_optimizer(nnn);
   }
 
+  IdealLoopTree* outer_loop = (head->is_strip_mined() && mode != IgnoreStripMined) ? get_loop(head->as_CountedLoop()->outer_loop()) : loop;
 
   // Step 2: Fix the edges in the new body.  If the old input is outside the
   // loop use it.  If the old input is INside the loop, use the corresponding
@@ -1624,7 +1906,7 @@
     if (has_ctrl(old)) {
       set_ctrl(nnn, old_new[get_ctrl(old)->_idx]);
     } else {
-      set_loop(nnn, loop->_parent);
+      set_loop(nnn, outer_loop->_parent);
       if (old->outcnt() > 0) {
         set_idom( nnn, old_new[idom(old)->_idx], dd );
       }
@@ -1640,22 +1922,21 @@
     }
     _igvn.hash_find_insert(nnn);
   }
-  Node *newhead = old_new[loop->_head->_idx];
-  set_idom(newhead, newhead->in(LoopNode::EntryControl), dd);
 
+  ResourceArea *area = Thread::current()->resource_area();
+  Node_List extra_data_nodes(area);
+  clone_outer_loop(head, mode, loop, outer_loop, dd, old_new, extra_data_nodes);
 
   // Step 3: Now fix control uses.  Loop varying control uses have already
   // been fixed up (as part of all input edges in Step 2).  Loop invariant
   // control uses must be either an IfFalse or an IfTrue.  Make a merge
   // point to merge the old and new IfFalse/IfTrue nodes; make the use
   // refer to this.
-  ResourceArea *area = Thread::current()->resource_area();
   Node_List worklist(area);
   uint new_counter = C->unique();
   for( i = 0; i < loop->_body.size(); i++ ) {
     Node* old = loop->_body.at(i);
     if( !old->is_CFG() ) continue;
-    Node* nnn = old_new[old->_idx];
 
     // Copy uses to a worklist, so I can munge the def-use info
     // with impunity.
@@ -1669,9 +1950,29 @@
       if( !loop->is_member( use_loop ) && use->is_CFG() ) {
         // Both OLD and USE are CFG nodes here.
         assert( use->is_Proj(), "" );
+        Node* nnn = old_new[old->_idx];
+
+        Node* newuse = NULL;
+        if (head->is_strip_mined() && mode != IgnoreStripMined) {
+          CountedLoopNode* cl = head->as_CountedLoop();
+          CountedLoopEndNode* cle = cl->loopexit();
+          Node* cle_out = cle->proj_out(false);
+          if (use == cle_out) {
+            IfNode* le = cl->outer_loop_end();
+            use = le->proj_out(false);
+            use_loop = get_loop(use);
+            if (mode == CloneIncludesStripMined) {
+              nnn = old_new[le->_idx];
+            } else {
+              newuse = old_new[cle_out->_idx];
+            }
+          }
+        }
+        if (newuse == NULL) {
+          newuse = use->clone();
+        }
 
         // Clone the loop exit control projection
-        Node *newuse = use->clone();
         if (C->do_vector_loop()) {
           cm.verify_insert_and_clone(use, newuse, cm.clone_idx());
         }
@@ -1705,6 +2006,10 @@
             if( useuse->in(k) == use ) {
               useuse->set_req(k, r);
               uses_found++;
+              if (useuse->is_Loop() && k == LoopNode::EntryControl) {
+                assert(dom_depth(useuse) > dd_r , "");
+                set_idom(useuse, r, dom_depth(useuse));
+              }
             }
           }
           l -= uses_found;    // we deleted 1 or more copies of this edge
@@ -1728,123 +2033,16 @@
   Node_List *split_cex_set = NULL;
   for( i = 0; i < loop->_body.size(); i++ ) {
     Node* old = loop->_body.at(i);
-    Node* nnn = old_new[old->_idx];
-    // Copy uses to a worklist, so I can munge the def-use info
-    // with impunity.
-    for (DUIterator_Fast jmax, j = old->fast_outs(jmax); j < jmax; j++)
-      worklist.push(old->fast_out(j));
-
-    while( worklist.size() ) {
-      Node *use = worklist.pop();
-      if (!has_node(use))  continue; // Ignore dead nodes
-      if (use->in(0) == C->top())  continue;
-      IdealLoopTree *use_loop = get_loop( has_ctrl(use) ? get_ctrl(use) : use );
-      // Check for data-use outside of loop - at least one of OLD or USE
-      // must not be a CFG node.
-      if( !loop->is_member( use_loop ) && (!old->is_CFG() || !use->is_CFG())) {
-
-        // If the Data use is an IF, that means we have an IF outside of the
-        // loop that is switching on a condition that is set inside of the
-        // loop.  Happens if people set a loop-exit flag; then test the flag
-        // in the loop to break the loop, then test is again outside of the
-        // loop to determine which way the loop exited.
-        // Loop predicate If node connects to Bool node through Opaque1 node.
-        if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use)) {
-          // Since this code is highly unlikely, we lazily build the worklist
-          // of such Nodes to go split.
-          if( !split_if_set )
-            split_if_set = new Node_List(area);
-          split_if_set->push(use);
-        }
-        if( use->is_Bool() ) {
-          if( !split_bool_set )
-            split_bool_set = new Node_List(area);
-          split_bool_set->push(use);
-        }
-        if( use->Opcode() == Op_CreateEx ) {
-          if( !split_cex_set )
-            split_cex_set = new Node_List(area);
-          split_cex_set->push(use);
-        }
-
-
-        // Get "block" use is in
-        uint idx = 0;
-        while( use->in(idx) != old ) idx++;
-        Node *prev = use->is_CFG() ? use : get_ctrl(use);
-        assert( !loop->is_member( get_loop( prev ) ), "" );
-        Node *cfg = prev->_idx >= new_counter
-          ? prev->in(2)
-          : idom(prev);
-        if( use->is_Phi() )     // Phi use is in prior block
-          cfg = prev->in(idx);  // NOT in block of Phi itself
-        if (cfg->is_top()) {    // Use is dead?
-          _igvn.replace_input_of(use, idx, C->top());
-          continue;
-        }
+    clone_loop_handle_data_uses(old, old_new, loop, outer_loop, split_if_set,
+                                split_bool_set, split_cex_set, worklist, new_counter,
+                                mode);
+  }
 
-        while( !loop->is_member( get_loop( cfg ) ) ) {
-          prev = cfg;
-          cfg = cfg->_idx >= new_counter ? cfg->in(2) : idom(cfg);
-        }
-        // If the use occurs after merging several exits from the loop, then
-        // old value must have dominated all those exits.  Since the same old
-        // value was used on all those exits we did not need a Phi at this
-        // merge point.  NOW we do need a Phi here.  Each loop exit value
-        // is now merged with the peeled body exit; each exit gets its own
-        // private Phi and those Phis need to be merged here.
-        Node *phi;
-        if( prev->is_Region() ) {
-          if( idx == 0 ) {      // Updating control edge?
-            phi = prev;         // Just use existing control
-          } else {              // Else need a new Phi
-            phi = PhiNode::make( prev, old );
-            // Now recursively fix up the new uses of old!
-            for( uint i = 1; i < prev->req(); i++ ) {
-              worklist.push(phi); // Onto worklist once for each 'old' input
-            }
-          }
-        } else {
-          // Get new RegionNode merging old and new loop exits
-          prev = old_new[prev->_idx];
-          assert( prev, "just made this in step 7" );
-          if( idx == 0 ) {      // Updating control edge?
-            phi = prev;         // Just use existing control
-          } else {              // Else need a new Phi
-            // Make a new Phi merging data values properly
-            phi = PhiNode::make( prev, old );
-            phi->set_req( 1, nnn );
-          }
-        }
-        // If inserting a new Phi, check for prior hits
-        if( idx != 0 ) {
-          Node *hit = _igvn.hash_find_insert(phi);
-          if( hit == NULL ) {
-           _igvn.register_new_node_with_optimizer(phi); // Register new phi
-          } else {                                      // or
-            // Remove the new phi from the graph and use the hit
-            _igvn.remove_dead_node(phi);
-            phi = hit;                                  // Use existing phi
-          }
-          set_ctrl(phi, prev);
-        }
-        // Make 'use' use the Phi instead of the old loop body exit value
-        _igvn.replace_input_of(use, idx, phi);
-        if( use->_idx >= new_counter ) { // If updating new phis
-          // Not needed for correctness, but prevents a weak assert
-          // in AddPNode from tripping (when we end up with different
-          // base & derived Phis that will become the same after
-          // IGVN does CSE).
-          Node *hit = _igvn.hash_find_insert(use);
-          if( hit )             // Go ahead and re-hash for hits.
-            _igvn.replace_node( use, hit );
-        }
-
-        // If 'use' was in the loop-exit block, it now needs to be sunk
-        // below the post-loop merge point.
-        sink_use( use, prev );
-      }
-    }
+  for (i = 0; i < extra_data_nodes.size(); i++) {
+    Node* old = extra_data_nodes.at(i);
+    clone_loop_handle_data_uses(old, old_new, loop, outer_loop, split_if_set,
+                                split_bool_set, split_cex_set, worklist, new_counter,
+                                mode);
   }
 
   // Check for IFs that need splitting/cloning.  Happens if an IF outside of
@@ -1852,31 +2050,31 @@
   // takes control from one or more OLD Regions (which in turn get from NEW
   // Regions).  In any case, there will be a set of Phis for each merge point
   // from the IF up to where the original BOOL def exists the loop.
-  if( split_if_set ) {
-    while( split_if_set->size() ) {
+  if (split_if_set) {
+    while (split_if_set->size()) {
       Node *iff = split_if_set->pop();
-      if( iff->in(1)->is_Phi() ) {
-        BoolNode *b = clone_iff( iff->in(1)->as_Phi(), loop );
+      if (iff->in(1)->is_Phi()) {
+        Node *b = clone_iff(iff->in(1)->as_Phi(), loop);
         _igvn.replace_input_of(iff, 1, b);
       }
     }
   }
-  if( split_bool_set ) {
-    while( split_bool_set->size() ) {
+  if (split_bool_set) {
+    while (split_bool_set->size()) {
       Node *b = split_bool_set->pop();
       Node *phi = b->in(1);
-      assert( phi->is_Phi(), "" );
-      CmpNode *cmp = clone_bool( (PhiNode*)phi, loop );
+      assert(phi->is_Phi(), "");
+      CmpNode *cmp = clone_bool((PhiNode*)phi, loop);
       _igvn.replace_input_of(b, 1, cmp);
     }
   }
-  if( split_cex_set ) {
-    while( split_cex_set->size() ) {
+  if (split_cex_set) {
+    while (split_cex_set->size()) {
       Node *b = split_cex_set->pop();
-      assert( b->in(0)->is_Region(), "" );
-      assert( b->in(1)->is_Phi(), "" );
-      assert( b->in(0)->in(0) == b->in(1)->in(0), "" );
-      split_up( b, b->in(0), NULL );
+      assert(b->in(0)->is_Region(), "");
+      assert(b->in(1)->is_Phi(), "");
+      assert(b->in(0)->in(0) == b->in(1)->in(0), "");
+      split_up(b, b->in(0), NULL);
     }
   }
 
@@ -2936,7 +3134,7 @@
 
   assert(is_valid_loop_partition(loop, peel, peel_list, not_peel), "bad partition");
 
-  clone_loop( loop, old_new, dd );
+  clone_loop(loop, old_new, dd, IgnoreStripMined);
 
   const uint clone_exit_idx = 1;
   const uint orig_exit_idx  = 2;
--- a/src/hotspot/share/opto/macro.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/macro.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -282,7 +282,8 @@
         if (!this_region->in(ind)->is_IfFalse()) {
           ind = 2;
         }
-        if (this_region->in(ind)->is_IfFalse()) {
+        if (this_region->in(ind)->is_IfFalse() &&
+            this_region->in(ind)->in(0)->Opcode() == Op_If) {
           Node* bol = this_region->in(ind)->in(0)->in(1);
           assert(bol->is_Bool(), "");
           cmpx = bol->in(1);
@@ -2660,6 +2661,8 @@
         break;
       case Node::Class_ArrayCopy:
         break;
+      case Node::Class_OuterStripMinedLoop:
+        break;
       default:
         assert(n->Opcode() == Op_LoopLimit ||
                n->Opcode() == Op_Opaque1   ||
@@ -2733,6 +2736,10 @@
       } else if (n->Opcode() == Op_Opaque4) {
         _igvn.replace_node(n, n->in(2));
         success = true;
+      } else if (n->Opcode() == Op_OuterStripMinedLoop) {
+        n->as_OuterStripMinedLoop()->adjust_strip_mined_loop(&_igvn);
+        C->remove_macro_node(n);
+        success = true;
       }
       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
       progress = progress || success;
--- a/src/hotspot/share/opto/node.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/node.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -111,6 +111,8 @@
 class MultiNode;
 class MultiBranchNode;
 class NeverBranchNode;
+class OuterStripMinedLoopNode;
+class OuterStripMinedLoopEndNode;
 class Node;
 class Node_Array;
 class Node_List;
@@ -623,8 +625,9 @@
           DEFINE_CLASS_ID(Catch,       PCTable, 0)
           DEFINE_CLASS_ID(Jump,        PCTable, 1)
         DEFINE_CLASS_ID(If,          MultiBranch, 1)
-          DEFINE_CLASS_ID(CountedLoopEnd, If, 0)
-          DEFINE_CLASS_ID(RangeCheck, If, 1)
+          DEFINE_CLASS_ID(CountedLoopEnd,         If, 0)
+          DEFINE_CLASS_ID(RangeCheck,             If, 1)
+          DEFINE_CLASS_ID(OuterStripMinedLoopEnd, If, 2)
         DEFINE_CLASS_ID(NeverBranch, MultiBranch, 2)
       DEFINE_CLASS_ID(Start,       Multi, 2)
       DEFINE_CLASS_ID(MemBar,      Multi, 3)
@@ -684,8 +687,9 @@
 
     DEFINE_CLASS_ID(Region, Node, 5)
       DEFINE_CLASS_ID(Loop, Region, 0)
-        DEFINE_CLASS_ID(Root,        Loop, 0)
-        DEFINE_CLASS_ID(CountedLoop, Loop, 1)
+        DEFINE_CLASS_ID(Root,                Loop, 0)
+        DEFINE_CLASS_ID(CountedLoop,         Loop, 1)
+        DEFINE_CLASS_ID(OuterStripMinedLoop, Loop, 2)
 
     DEFINE_CLASS_ID(Sub,   Node, 6)
       DEFINE_CLASS_ID(Cmp,   Sub, 0)
@@ -841,6 +845,8 @@
   DEFINE_CLASS_QUERY(Mul)
   DEFINE_CLASS_QUERY(Multi)
   DEFINE_CLASS_QUERY(MultiBranch)
+  DEFINE_CLASS_QUERY(OuterStripMinedLoop)
+  DEFINE_CLASS_QUERY(OuterStripMinedLoopEnd)
   DEFINE_CLASS_QUERY(Parm)
   DEFINE_CLASS_QUERY(PCTable)
   DEFINE_CLASS_QUERY(Phi)
--- a/src/hotspot/share/opto/reg_split.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/reg_split.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 #include "libadt/vectset.hpp"
 #include "memory/allocation.inline.hpp"
-#include "memory/resourceArea.hpp"
+#include "memory/resourceArea.inline.hpp"
 #include "opto/addnode.hpp"
 #include "opto/c2compiler.hpp"
 #include "opto/callnode.hpp"
--- a/src/hotspot/share/opto/split_if.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/split_if.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -169,7 +169,7 @@
               assert(u->in(1) == bol, "");
               // Get control block of either the CMove or the If input
               Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u);
-              assert(u_ctrl != blk1 && u_ctrl != blk2, "won't converge");
+              assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge");
               Node *x = bol->clone();
               register_new_node(x, u_ctrl);
               _igvn.replace_input_of(u, 1, x);
--- a/src/hotspot/share/opto/subnode.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/subnode.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1595,3 +1595,12 @@
   if( d < 0.0 ) return Type::DOUBLE;
   return TypeD::make( sqrt( d ) );
 }
+
+const Type* SqrtFNode::Value(PhaseGVN* phase) const {
+  const Type *t1 = phase->type( in(1) );
+  if( t1 == Type::TOP ) return Type::TOP;
+  if( t1->base() != Type::FloatCon ) return Type::FLOAT;
+  float f = t1->getf();
+  if( f < 0.0f ) return Type::FLOAT;
+  return TypeF::make( (float)sqrt( (double)f ) );
+}
--- a/src/hotspot/share/opto/subnode.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/subnode.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -442,6 +442,20 @@
   virtual const Type* Value(PhaseGVN* phase) const;
 };
 
+//------------------------------SqrtFNode--------------------------------------
+// square root a float
+class SqrtFNode : public Node {
+public:
+  SqrtFNode(Compile* C, Node *c, Node *in1) : Node(c, in1) {
+    init_flags(Flag_is_expensive);
+    C->add_expensive_node(this);
+  }
+  virtual int Opcode() const;
+  const Type *bottom_type() const { return Type::FLOAT; }
+  virtual uint ideal_reg() const { return Op_RegF; }
+  virtual const Type* Value(PhaseGVN* phase) const;
+};
+
 //-------------------------------ReverseBytesINode--------------------------------
 // reverse bytes of an integer
 class ReverseBytesINode : public Node {
--- a/src/hotspot/share/opto/superword.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/superword.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1102,7 +1102,7 @@
   }
 
   if (isomorphic(s1, s2)) {
-    if (independent(s1, s2) || reduction(s1, s2)) {
+    if ((independent(s1, s2) && have_similar_inputs(s1, s2)) || reduction(s1, s2)) {
       if (!exists_at(s1, 0) && !exists_at(s2, 1)) {
         if (!s1->is_Mem() || are_adjacent_refs(s1, s2)) {
           int s1_align = alignment(s1);
@@ -1180,6 +1180,20 @@
   return independent_path(shallow, deep);
 }
 
+//--------------------------have_similar_inputs-----------------------
+// For a node pair (s1, s2) which is isomorphic and independent,
+// do s1 and s2 have similar input edges?
+bool SuperWord::have_similar_inputs(Node* s1, Node* s2) {
+  // assert(isomorphic(s1, s2) == true, "check isomorphic");
+  // assert(independent(s1, s2) == true, "check independent");
+  if (s1->req() > 1 && !s1->is_Store() && !s1->is_Load()) {
+    for (uint i = 1; i < s1->req(); i++) {
+      if (s1->in(i)->Opcode() != s2->in(i)->Opcode()) return false;
+    }
+  }
+  return true;
+}
+
 //------------------------------reduction---------------------------
 // Is there a data path between s1 and s2 and the nodes reductions?
 bool SuperWord::reduction(Node* s1, Node* s2) {
@@ -1339,6 +1353,7 @@
     for (DUIterator_Fast jmax, j = s2->fast_outs(jmax); j < jmax; j++) {
       Node* t2 = s2->fast_out(j);
       if (!in_bb(t2)) continue;
+      if (t2->Opcode() == Op_AddI && t2 == _lp->as_CountedLoop()->incr()) continue; // don't mess with the iv
       if (!opnd_positions_match(s1, t1, s2, t2))
         continue;
       if (stmts_can_pack(t1, t2, align)) {
@@ -2307,7 +2322,7 @@
           vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n));
           vlen_in_bytes = vn->as_Vector()->length_in_bytes();
         }
-      } else if (opc == Op_SqrtD || opc == Op_AbsF || opc == Op_AbsD || opc == Op_NegF || opc == Op_NegD) {
+      } else if (opc == Op_SqrtF || opc == Op_SqrtD || opc == Op_AbsF || opc == Op_AbsD || opc == Op_NegF || opc == Op_NegD) {
         // Promote operand to vector (Sqrt/Abs/Neg are 2 address instructions)
         Node* in = vector_opd(p, 1);
         vn = VectorNode::make(opc, in, NULL, vlen, velt_basic_type(n));
@@ -3299,7 +3314,7 @@
     return NULL;
   }
 
-  Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0);
+  Node* p_f = cl->skip_strip_mined()->in(LoopNode::EntryControl)->in(0)->in(0);
   if (!p_f->is_IfFalse()) return NULL;
   if (!p_f->in(0)->is_CountedLoopEnd()) return NULL;
   CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
--- a/src/hotspot/share/opto/superword.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/superword.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -442,6 +442,9 @@
   bool isomorphic(Node* s1, Node* s2);
   // Is there no data path from s1 to s2 or s2 to s1?
   bool independent(Node* s1, Node* s2);
+  // For a node pair (s1, s2) which is isomorphic and independent,
+  // do s1 and s2 have similar input edges?
+  bool have_similar_inputs(Node* s1, Node* s2);
   // Is there a data path between s1 and s2 and both are reductions?
   bool reduction(Node* s1, Node* s2);
   // Helper for independent
--- a/src/hotspot/share/opto/vectornode.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/vectornode.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -113,6 +113,9 @@
   case Op_NegD:
     assert(bt == T_DOUBLE, "must be");
     return Op_NegVD;
+  case Op_SqrtF:
+    assert(bt == T_FLOAT, "must be");
+    return Op_SqrtVF;
   case Op_SqrtD:
     assert(bt == T_DOUBLE, "must be");
     return Op_SqrtVD;
@@ -316,7 +319,7 @@
   case Op_NegVF: return new NegVFNode(n1, vt);
   case Op_NegVD: return new NegVDNode(n1, vt);
 
-  // Currently only supports double precision sqrt
+  case Op_SqrtVF: return new SqrtVFNode(n1, vt);
   case Op_SqrtVD: return new SqrtVDNode(n1, vt);
 
   case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt);
--- a/src/hotspot/share/opto/vectornode.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/opto/vectornode.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -373,6 +373,14 @@
   virtual int Opcode() const;
 };
 
+//------------------------------SqrtVFNode--------------------------------------
+// Vector Sqrt float
+class SqrtVFNode : public VectorNode {
+ public:
+  SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
+  virtual int Opcode() const;
+};
+
 //------------------------------SqrtVDNode--------------------------------------
 // Vector Sqrt double
 class SqrtVDNode : public VectorNode {
--- a/src/hotspot/share/precompiled/precompiled.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/precompiled/precompiled.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -131,7 +131,6 @@
 # include "jvmtifiles/jvmti.h"
 # include "logging/log.hpp"
 # include "memory/allocation.hpp"
-# include "memory/allocation.inline.hpp"
 # include "memory/arena.hpp"
 # include "memory/heap.hpp"
 # include "memory/iterator.hpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/prims/cdsoffsets.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_CDS
+#include "runtime/os.hpp"
+#include "memory/filemap.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "prims/cdsoffsets.hpp"
+
+CDSOffsets* CDSOffsets::_all = NULL;
+#define ADD_NEXT(list, name, value) \
+  list->add_end(new CDSOffsets(name, value, NULL))
+
+#define CREATE_OFFSET_MAPS                                                                                  \
+    _all = new CDSOffsets("size_t_size", sizeof(size_t), NULL);                                             \
+    ADD_NEXT(_all, "FileMapHeader::_magic", offset_of(FileMapInfo::FileMapHeader, _magic));                 \
+    ADD_NEXT(_all, "FileMapHeader::_crc", offset_of(FileMapInfo::FileMapHeader, _crc));                     \
+    ADD_NEXT(_all, "FileMapHeader::_version", offset_of(FileMapInfo::FileMapHeader, _version));             \
+    ADD_NEXT(_all, "FileMapHeader::_space[0]", offset_of(FileMapInfo::FileMapHeader, _space));              \
+    ADD_NEXT(_all, "space_info::_crc", offset_of(FileMapInfo::FileMapHeader::space_info, _crc));            \
+    ADD_NEXT(_all, "space_info::_used", offset_of(FileMapInfo::FileMapHeader::space_info, _used));          \
+    ADD_NEXT(_all, "FileMapHeader::_paths_misc_info_size", offset_of(FileMapInfo::FileMapHeader, _paths_misc_info_size)); \
+    ADD_NEXT(_all, "file_header_size", sizeof(FileMapInfo::FileMapHeader));                                 \
+    ADD_NEXT(_all, "space_info_size", sizeof(FileMapInfo::FileMapHeader::space_info));
+
+int CDSOffsets::find_offset(const char* name) {
+  if (_all == NULL) {
+    CREATE_OFFSET_MAPS
+  }
+  CDSOffsets* it = _all;
+  while(it) {
+    if (!strcmp(name, it->get_name())) {
+      return it->get_offset();
+    }
+    it = it->next();
+  }
+  return -1; // not found
+}
+
+void CDSOffsets::add_end(CDSOffsets* n) {
+  CDSOffsets* p = this;
+  while(p && p->_next) { p = p->_next; }
+  p->_next = n;
+}
+#endif // INCLUDE_CDS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/prims/cdsoffsets.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+#ifndef SHARE_PRIMS_CDSOFFSETS_HPP
+#define SHARE_PRIMS_CDSOFFSETS_HPP
+class CDSOffsets: public CHeapObj<mtInternal> {
+ private:
+  char* _name;
+  int   _offset;
+  CDSOffsets* _next;
+  static CDSOffsets* _all;  // sole list for cds
+ public:
+  CDSOffsets(const char* name, int offset, CDSOffsets* next) {
+     _name = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal);
+     strcpy(_name, name);
+     _offset = offset;
+     _next = next;
+  }
+
+  char* get_name() const { return _name; }
+  int   get_offset() const { return _offset; }
+  CDSOffsets* next() const { return _next; }
+  void add_end(CDSOffsets* n);
+
+  static int find_offset(const char* name);
+};
+#endif // SHARE_PRIMS_CDSOFFSETS_HPP
--- a/src/hotspot/share/prims/jni.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jni.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -4119,7 +4119,7 @@
   thread->initialize_thread_current();
 
   if (!os::create_attached_thread(thread)) {
-    delete thread;
+    thread->smr_delete();
     return JNI_ERR;
   }
   // Enable stack overflow checks
@@ -4250,7 +4250,7 @@
   // (platform-dependent) methods where we do alternate stack
   // maintenance work?)
   thread->exit(false, JavaThread::jni_detach);
-  delete thread;
+  thread->smr_delete();
 
   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
   return JNI_OK;
--- a/src/hotspot/share/prims/jvm.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvm.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -66,6 +66,7 @@
 #include "runtime/perfData.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vm_operations.hpp"
 #include "runtime/vm_version.hpp"
@@ -2737,16 +2738,12 @@
 
 // java.lang.Thread //////////////////////////////////////////////////////////////////////////////
 
-// In most of the JVM Thread support functions we need to be sure to lock the Threads_lock
-// to prevent the target thread from exiting after we have a pointer to the C++ Thread or
-// OSThread objects.  The exception to this rule is when the target object is the thread
-// doing the operation, in which case we know that the thread won't exit until the
-// operation is done (all exits being voluntary).  There are a few cases where it is
-// rather silly to do operations on yourself, like resuming yourself or asking whether
-// you are alive.  While these can still happen, they are not subject to deadlocks if
-// the lock is held while the operation occurs (this is not the case for suspend, for
-// instance), and are very unlikely.  Because IsAlive needs to be fast and its
-// implementation is local to this file, we always lock Threads_lock for that one.
+// In most of the JVM thread support functions we need to access the
+// thread through a ThreadsListHandle to prevent it from exiting and
+// being reclaimed while we try to operate on it. The exceptions to this
+// rule are when operating on the current thread, or if the monitor of
+// the target java.lang.Thread is locked at the Java level - in both
+// cases the target cannot exit.
 
 static void thread_entry(JavaThread* thread, TRAPS) {
   HandleMark hm(THREAD);
@@ -2821,7 +2818,7 @@
 
   if (native_thread->osthread() == NULL) {
     // No one should hold a reference to the 'native_thread'.
-    delete native_thread;
+    native_thread->smr_delete();
     if (JvmtiExport::should_post_resource_exhausted()) {
       JvmtiExport::post_resource_exhausted(
         JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,
@@ -2835,41 +2832,45 @@
 
 JVM_END
 
+
 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints
 // before the quasi-asynchronous exception is delivered.  This is a little obtrusive,
 // but is thought to be reliable and simple. In the case, where the receiver is the
-// same thread as the sender, no safepoint is needed.
+// same thread as the sender, no VM_Operation is needed.
 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))
   JVMWrapper("JVM_StopThread");
 
+  // A nested ThreadsListHandle will grab the Threads_lock so create
+  // tlh before we resolve throwable.
+  ThreadsListHandle tlh(thread);
   oop java_throwable = JNIHandles::resolve(throwable);
   if (java_throwable == NULL) {
     THROW(vmSymbols::java_lang_NullPointerException());
   }
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  JavaThread* receiver = java_lang_Thread::thread(java_thread);
-  Events::log_exception(JavaThread::current(),
+  oop java_thread = NULL;
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, &java_thread);
+  Events::log_exception(thread,
                         "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",
                         p2i(receiver), p2i((address)java_thread), p2i(throwable));
-  // First check if thread is alive
-  if (receiver != NULL) {
-    // Check if exception is getting thrown at self (use oop equality, since the
-    // target object might exit)
-    if (java_thread == thread->threadObj()) {
+
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    if (thread == receiver) {
+      // Exception is getting thrown at self so no VM_Operation needed.
       THROW_OOP(java_throwable);
     } else {
-      // Enques a VM_Operation to stop all threads and then deliver the exception...
-      Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));
+      // Use a VM_Operation to throw the exception.
+      Thread::send_async_exception(java_thread, java_throwable);
     }
-  }
-  else {
+  } else {
     // Either:
     // - target thread has not been started before being stopped, or
     // - target thread already terminated
     // We could read the threadStatus to determine which case it is
     // but that is overkill as it doesn't matter. We must set the
     // stillborn flag for the first case, and if the thread has already
-    // exited setting this flag has no affect
+    // exited setting this flag has no effect.
     java_lang_Thread::set_stillborn(java_thread);
   }
 JVM_END
@@ -2885,12 +2886,12 @@
 
 JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_SuspendThread");
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  JavaThread* receiver = java_lang_Thread::thread(java_thread);
-
-  if (receiver != NULL) {
-    // thread has run and has not exited (still on threads list)
-
+
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
     {
       MutexLockerEx ml(receiver->SR_lock(), Mutex::_no_safepoint_check_flag);
       if (receiver->is_external_suspend()) {
@@ -2922,30 +2923,49 @@
 
 JVM_ENTRY(void, JVM_ResumeThread(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_ResumeThread");
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate.
-  // We need to *always* get the threads lock here, since this operation cannot be allowed during
-  // a safepoint. The safepoint code relies on suspending a thread to examine its state. If other
-  // threads randomly resumes threads, then a thread might not be suspended when the safepoint code
-  // looks at it.
-  MutexLocker ml(Threads_lock);
-  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-  if (thr != NULL) {
-    // the thread has run and is not in the process of exiting
-    thr->java_resume();
+
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+
+    // This is the original comment for this Threads_lock grab:
+    //   We need to *always* get the threads lock here, since this operation cannot be allowed during
+    //   a safepoint. The safepoint code relies on suspending a thread to examine its state. If other
+    //   threads randomly resumes threads, then a thread might not be suspended when the safepoint code
+    //   looks at it.
+    //
+    // The above comment dates back to when we had both internal and
+    // external suspend APIs that shared a common underlying mechanism.
+    // External suspend is now entirely cooperative and doesn't share
+    // anything with internal suspend. That said, there are some
+    // assumptions in the VM that an external resume grabs the
+    // Threads_lock. We can't drop the Threads_lock grab here until we
+    // resolve the assumptions that exist elsewhere.
+    //
+    MutexLocker ml(Threads_lock);
+    receiver->java_resume();
   }
 JVM_END
 
 
 JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))
   JVMWrapper("JVM_SetThreadPriority");
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  MutexLocker ml(Threads_lock);
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
+
+  ThreadsListHandle tlh(thread);
+  oop java_thread = NULL;
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, &java_thread);
   java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);
-  JavaThread* thr = java_lang_Thread::thread(java_thread);
-  if (thr != NULL) {                  // Thread not yet started; priority pushed down when it is
-    Thread::set_priority(thr, (ThreadPriority)prio);
+
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    Thread::set_priority(receiver, (ThreadPriority)prio);
   }
+  // Implied else: If the JavaThread hasn't started yet, then the
+  // priority set in the java.lang.Thread object above will be pushed
+  // down when it does start.
 JVM_END
 
 
@@ -3016,67 +3036,39 @@
 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_CountStackFrames");
 
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  bool throw_illegal_thread_state = false;
+  uint32_t debug_bits = 0;
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
   int count = 0;
-
-  {
-    MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
-    // We need to re-resolve the java_thread, since a GC might have happened during the
-    // acquire of the lock
-    JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-
-    if (thr == NULL) {
-      // do nothing
-    } else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) {
-      // Check whether this java thread has been suspended already. If not, throws
-      // IllegalThreadStateException. We defer to throw that exception until
-      // Threads_lock is released since loading exception class has to leave VM.
-      // The correct way to test a thread is actually suspended is
-      // wait_for_ext_suspend_completion(), but we can't call that while holding
-      // the Threads_lock. The above tests are sufficient for our purposes
-      // provided the walkability of the stack is stable - which it isn't
-      // 100% but close enough for most practical purposes.
-      throw_illegal_thread_state = true;
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    if (receiver->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
+      // Count all java activation, i.e., number of vframes.
+      for (vframeStream vfst(receiver); !vfst.at_end(); vfst.next()) {
+        // Native frames are not counted.
+        if (!vfst.method()->is_native()) count++;
+      }
     } else {
-      // Count all java activation, i.e., number of vframes
-      for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) {
-        // Native frames are not counted
-        if (!vfst.method()->is_native()) count++;
-       }
+      THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
+                  "this thread is not suspended");
     }
   }
-
-  if (throw_illegal_thread_state) {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
-                "this thread is not suspended");
-  }
+  // Implied else: if JavaThread is not alive simply return a count of 0.
+
   return count;
 JVM_END
 
-// Consider: A better way to implement JVM_Interrupt() is to acquire
-// Threads_lock to resolve the jthread into a Thread pointer, fetch
-// Thread->platformevent, Thread->native_thr, Thread->parker, etc.,
-// drop Threads_lock, and the perform the unpark() and thr_kill() operations
-// outside the critical section.  Threads_lock is hot so we want to minimize
-// the hold-time.  A cleaner interface would be to decompose interrupt into
-// two steps.  The 1st phase, performed under Threads_lock, would return
-// a closure that'd be invoked after Threads_lock was dropped.
-// This tactic is safe as PlatformEvent and Parkers are type-stable (TSM) and
-// admit spurious wakeups.
 
 JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_Interrupt");
 
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
-  // We need to re-resolve the java_thread, since a GC might have happened during the
-  // acquire of the lock
-  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-  if (thr != NULL) {
-    Thread::interrupt(thr);
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    Thread::interrupt(receiver);
   }
 JVM_END
 
@@ -3084,16 +3076,14 @@
 JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
   JVMWrapper("JVM_IsInterrupted");
 
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
-  // We need to re-resolve the java_thread, since a GC might have happened during the
-  // acquire of the lock
-  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-  if (thr == NULL) {
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    return (jboolean) Thread::is_interrupted(receiver, clear_interrupted != 0);
+  } else {
     return JNI_FALSE;
-  } else {
-    return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);
   }
 JVM_END
 
@@ -3122,14 +3112,16 @@
 
 JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))
   JVMWrapper("JVM_SetNativeThreadName");
-  ResourceMark rm(THREAD);
+
+  // We don't use a ThreadsListHandle here because the current thread
+  // must be alive.
   oop java_thread = JNIHandles::resolve_non_null(jthread);
   JavaThread* thr = java_lang_Thread::thread(java_thread);
-  // Thread naming only supported for the current thread, doesn't work for
-  // target threads.
-  if (Thread::current() == thr && !thr->has_attached_via_jni()) {
+  if (thread == thr && !thr->has_attached_via_jni()) {
+    // Thread naming is only supported for the current thread and
     // we don't set the name of an attached thread to avoid stepping
-    // on other programs
+    // on other programs.
+    ResourceMark rm(thread);
     const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
     os::set_native_thread_name(thread_name);
   }
@@ -3561,6 +3553,8 @@
     thread_handle_array->append(h);
   }
 
+  // The JavaThread references in thread_handle_array are validated
+  // in VM_ThreadDump::doit().
   Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL);
   return (jobjectArray)JNIHandles::make_local(env, stacktraces());
 
--- a/src/hotspot/share/prims/jvmtiEnter.xsl	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnter.xsl	Thu Dec 07 11:54:55 2017 +0000
@@ -45,6 +45,7 @@
 # include "prims/jvmtiEnter.hpp"
 # include "prims/jvmtiRawMonitor.hpp"
 # include "prims/jvmtiUtil.hpp"
+# include "runtime/threadSMR.hpp"
 
 </xsl:text>
 
@@ -769,47 +770,27 @@
 
 <xsl:template match="jthread" mode="dochecksbody">
   <xsl:param name="name"/>
-    <xsl:text>    oop thread_oop = JNIHandles::resolve_external_guard(</xsl:text>
+    <xsl:text>    err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), </xsl:text>
     <xsl:value-of select="$name"/>
-    <xsl:text>);
-    if (thread_oop == NULL) {
+    <xsl:text>, &amp;java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
-      <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
-      <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="err">err</xsl:with-param>
+      <xsl:with-param name="comment"> - jthread did not convert to a JavaThread - jthread = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
     }
-    if (!thread_oop-&gt;is_a(SystemDictionary::Thread_klass())) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
-      <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
-      <xsl:with-param name="comment"> - oop is not a thread - jthread = " PTR_FORMAT "</xsl:with-param>
-      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
-    </xsl:apply-templates>
-    <xsl:text>
-    }
-    java_thread = java_lang_Thread::thread(thread_oop); 
-    if (java_thread == NULL) {
-</xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
-      <xsl:with-param name="err">
-        <xsl:text>JVMTI_ERROR_THREAD_NOT_ALIVE</xsl:text>
-      </xsl:with-param>
-      <xsl:with-param name="comment"> - not a Java thread - jthread = " PTR_FORMAT "</xsl:with-param>
-      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
-    </xsl:apply-templates>
-    <xsl:text>
-    }
-</xsl:text>  
 </xsl:template>
 
 <xsl:template match="jthread" mode="dochecks">
   <xsl:param name="name"/>
   <!-- If we convert and test threads -->
   <xsl:if test="count(@impl)=0 or not(contains(@impl,'noconvert'))">
-    <xsl:text>  JavaThread* java_thread;
+    <xsl:text>  JavaThread* java_thread = NULL;
+  ThreadsListHandle tlh(this_thread);
 </xsl:text>
     <xsl:choose>
       <xsl:when test="count(@null)=0">
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -62,6 +62,7 @@
 #include "runtime/reflectionUtils.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timerTrace.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
@@ -162,7 +163,6 @@
     *data_ptr = (state == NULL) ? NULL :
       state->env_thread_state(this)->get_agent_thread_local_storage_data();
   } else {
-
     // jvmti_GetThreadLocalStorage is "in native" and doesn't transition
     // the thread to _thread_in_vm. However, when the TLS for a thread
     // other than the current thread is required we need to transition
@@ -172,17 +172,13 @@
     VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
     debug_only(VMNativeEntryWrapper __vew;)
 
-    oop thread_oop = JNIHandles::resolve_external_guard(thread);
-    if (thread_oop == NULL) {
-      return JVMTI_ERROR_INVALID_THREAD;
+    JavaThread* java_thread = NULL;
+    ThreadsListHandle tlh(current_thread);
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      return err;
     }
-    if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
-      return JVMTI_ERROR_INVALID_THREAD;
-    }
-    JavaThread* java_thread = java_lang_Thread::thread(thread_oop);
-    if (java_thread == NULL) {
-      return JVMTI_ERROR_THREAD_NOT_ALIVE;
-    }
+
     JvmtiThreadState* state = java_thread->jvmti_thread_state();
     *data_ptr = (state == NULL) ? NULL :
       state->env_thread_state(this)->get_agent_thread_local_storage_data();
@@ -518,43 +514,61 @@
 // event_thread - NULL is a valid value, must be checked
 jvmtiError
 JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread,   ...) {
-  JavaThread* java_thread = NULL;
-  if (event_thread != NULL) {
-    oop thread_oop = JNIHandles::resolve_external_guard(event_thread);
-    if (thread_oop == NULL) {
-      return JVMTI_ERROR_INVALID_THREAD;
+  if (event_thread == NULL) {
+    // Can be called at Agent_OnLoad() time with event_thread == NULL
+    // when Thread::current() does not work yet so we cannot create a
+    // ThreadsListHandle that is common to both thread-specific and
+    // global code paths.
+
+    // event_type must be valid
+    if (!JvmtiEventController::is_valid_event_type(event_type)) {
+      return JVMTI_ERROR_INVALID_EVENT_TYPE;
+    }
+
+    bool enabled = (mode == JVMTI_ENABLE);
+
+    // assure that needed capabilities are present
+    if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
+      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+    }
+
+    if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
+      record_class_file_load_hook_enabled();
     }
-    if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
-      return JVMTI_ERROR_INVALID_THREAD;
+    JvmtiEventController::set_user_enabled(this, (JavaThread*) NULL, event_type, enabled);
+  } else {
+    // We have a specified event_thread.
+
+    JavaThread* java_thread = NULL;
+    ThreadsListHandle tlh;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), event_thread, &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      return err;
+    }
+
+    // event_type must be valid
+    if (!JvmtiEventController::is_valid_event_type(event_type)) {
+      return JVMTI_ERROR_INVALID_EVENT_TYPE;
     }
-    java_thread = java_lang_Thread::thread(thread_oop);
-    if (java_thread == NULL) {
-      return JVMTI_ERROR_THREAD_NOT_ALIVE;
+
+    // global events cannot be controlled at thread level.
+    if (JvmtiEventController::is_global_event(event_type)) {
+      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
     }
+
+    bool enabled = (mode == JVMTI_ENABLE);
+
+    // assure that needed capabilities are present
+    if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
+      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+    }
+
+    if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
+      record_class_file_load_hook_enabled();
+    }
+    JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
   }
 
-  // event_type must be valid
-  if (!JvmtiEventController::is_valid_event_type(event_type)) {
-    return JVMTI_ERROR_INVALID_EVENT_TYPE;
-  }
-
-  // global events cannot be controlled at thread level.
-  if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) {
-    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-  }
-
-  bool enabled = (mode == JVMTI_ENABLE);
-
-  // assure that needed capabilities are present
-  if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
-    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
-  }
-
-  if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
-    record_class_file_load_hook_enabled();
-  }
-  JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
-
   return JVMTI_ERROR_NONE;
 } /* end SetEventNotificationMode */
 
@@ -817,35 +831,45 @@
 // thread_state_ptr - pre-checked for NULL
 jvmtiError
 JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {
-  jint state;
-  oop thread_oop;
-  JavaThread* thr;
+  JavaThread* current_thread = JavaThread::current();
+  JavaThread* java_thread = NULL;
+  oop thread_oop = NULL;
+  ThreadsListHandle tlh(current_thread);
 
   if (thread == NULL) {
-    thread_oop = JavaThread::current()->threadObj();
+    java_thread = current_thread;
+    thread_oop = java_thread->threadObj();
+
+    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
+      return JVMTI_ERROR_INVALID_THREAD;
+    }
   } else {
-    thread_oop = JNIHandles::resolve_external_guard(thread);
-  }
-
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
-    return JVMTI_ERROR_INVALID_THREAD;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
+    if (err != JVMTI_ERROR_NONE) {
+      // We got an error code so we don't have a JavaThread *, but
+      // only return an error from here if we didn't get a valid
+      // thread_oop.
+      if (thread_oop == NULL) {
+        return err;
+      }
+      // We have a valid thread_oop so we can return some thread state.
+    }
   }
 
   // get most state bits
-  state = (jint)java_lang_Thread::get_thread_status(thread_oop);
-
-  // add more state bits
-  thr = java_lang_Thread::thread(thread_oop);
-  if (thr != NULL) {
-    JavaThreadState jts = thr->thread_state();
-
-    if (thr->is_being_ext_suspended()) {
+  jint state = (jint)java_lang_Thread::get_thread_status(thread_oop);
+
+  if (java_thread != NULL) {
+    // We have a JavaThread* so add more state bits.
+    JavaThreadState jts = java_thread->thread_state();
+
+    if (java_thread->is_being_ext_suspended()) {
       state |= JVMTI_THREAD_STATE_SUSPENDED;
     }
     if (jts == _thread_in_native) {
       state |= JVMTI_THREAD_STATE_IN_NATIVE;
     }
-    OSThread* osThread = thr->osthread();
+    OSThread* osThread = java_thread->osthread();
     if (osThread != NULL && osThread->interrupted()) {
       state |= JVMTI_THREAD_STATE_INTERRUPTED;
     }
@@ -891,7 +915,6 @@
     thread_objs[i] = Handle(tle.get_threadObj(i));
   }
 
-  // have to make global handles outside of Threads_lock
   jthread *jthreads  = new_jthreadArray(nthreads, thread_objs);
   NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);
 
@@ -935,19 +958,12 @@
 jvmtiError
 JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
   int needSafepoint = 0;  // > 0 if we need a safepoint
+  ThreadsListHandle tlh;
   for (int i = 0; i < request_count; i++) {
-    JavaThread *java_thread = get_JavaThread(request_list[i]);
-    if (java_thread == NULL) {
-      results[i] = JVMTI_ERROR_INVALID_THREAD;
-      continue;
-    }
-    // the thread has not yet run or has exited (not on threads list)
-    if (java_thread->threadObj() == NULL) {
-      results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
-      continue;
-    }
-    if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
-      results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
+    JavaThread *java_thread = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      results[i] = err;
       continue;
     }
     // don't allow hidden thread suspend request.
@@ -1018,10 +1034,12 @@
 // results - pre-checked for NULL
 jvmtiError
 JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
+  ThreadsListHandle tlh;
   for (int i = 0; i < request_count; i++) {
-    JavaThread *java_thread = get_JavaThread(request_list[i]);
-    if (java_thread == NULL) {
-      results[i] = JVMTI_ERROR_INVALID_THREAD;
+    JavaThread* java_thread = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      results[i] = err;
       continue;
     }
     // don't allow hidden thread resume request.
@@ -1039,7 +1057,7 @@
       continue;
     }
 
-    results[i] = JVMTI_ERROR_NONE;  // indicate successful suspend
+    results[i] = JVMTI_ERROR_NONE;  // indicate successful resume
   }
   // per-thread resume results returned via results parameter
   return JVMTI_ERROR_NONE;
@@ -1064,20 +1082,14 @@
 // thread - NOT pre-checked
 jvmtiError
 JvmtiEnv::InterruptThread(jthread thread) {
-  oop thread_oop = JNIHandles::resolve_external_guard(thread);
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))
-    return JVMTI_ERROR_INVALID_THREAD;
-
+  // TODO: this is very similar to JVM_Interrupt(); share code in future
   JavaThread* current_thread  = JavaThread::current();
-
-  // Todo: this is a duplicate of JVM_Interrupt; share code in future
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  MutexLockerEx ml(current_thread->threadObj() == thread_oop ? NULL : Threads_lock);
-  // We need to re-resolve the java_thread, since a GC might have happened during the
-  // acquire of the lock
-
-  JavaThread* java_thread = java_lang_Thread::thread(JNIHandles::resolve_external_guard(thread));
-  NULL_CHECK(java_thread, JVMTI_ERROR_THREAD_NOT_ALIVE);
+  JavaThread* java_thread = NULL;
+  ThreadsListHandle tlh(current_thread);
+  jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);
+  if (err != JVMTI_ERROR_NONE) {
+    return err;
+  }
 
   Thread::interrupt(java_thread);
 
@@ -1094,16 +1106,28 @@
   HandleMark hm;
 
   JavaThread* current_thread = JavaThread::current();
+  ThreadsListHandle tlh(current_thread);
 
   // if thread is NULL the current thread is used
-  oop thread_oop;
+  oop thread_oop = NULL;
   if (thread == NULL) {
     thread_oop = current_thread->threadObj();
+    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
+      return JVMTI_ERROR_INVALID_THREAD;
+    }
   } else {
-    thread_oop = JNIHandles::resolve_external_guard(thread);
+    JavaThread* java_thread = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
+    if (err != JVMTI_ERROR_NONE) {
+      // We got an error code so we don't have a JavaThread *, but
+      // only return an error from here if we didn't get a valid
+      // thread_oop.
+      if (thread_oop == NULL) {
+        return err;
+      }
+      // We have a valid thread_oop so we can return some thread info.
+    }
   }
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))
-    return JVMTI_ERROR_INVALID_THREAD;
 
   Handle thread_obj(current_thread, thread_oop);
   Handle name;
@@ -1272,17 +1296,31 @@
 // arg - NULL is a valid value, must be checked
 jvmtiError
 JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
-  oop thread_oop = JNIHandles::resolve_external_guard(thread);
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
+  JavaThread* current_thread = JavaThread::current();
+
+  JavaThread* java_thread = NULL;
+  oop thread_oop = NULL;
+  ThreadsListHandle tlh(current_thread);
+  jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
+  if (err != JVMTI_ERROR_NONE) {
+    // We got an error code so we don't have a JavaThread *, but
+    // only return an error from here if we didn't get a valid
+    // thread_oop.
+    if (thread_oop == NULL) {
+      return err;
+    }
+    // We have a valid thread_oop.
+  }
+
+  if (java_thread != NULL) {
+    // 'thread' refers to an existing JavaThread.
     return JVMTI_ERROR_INVALID_THREAD;
   }
+
   if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
     return JVMTI_ERROR_INVALID_PRIORITY;
   }
 
-  //Thread-self
-  JavaThread* current_thread = JavaThread::current();
-
   Handle thread_hndl(current_thread, thread_oop);
   {
     MutexLocker mu(Threads_lock); // grab Threads_lock
@@ -1292,7 +1330,9 @@
     // At this point it may be possible that no osthread was created for the
     // JavaThread due to lack of memory.
     if (new_thread == NULL || new_thread->osthread() == NULL) {
-      if (new_thread) delete new_thread;
+      if (new_thread != NULL) {
+        new_thread->smr_delete();
+      }
       return JVMTI_ERROR_OUT_OF_MEMORY;
     }
 
@@ -1394,36 +1434,53 @@
   int ngroups = 0;
   int hidden_threads = 0;
 
-  ResourceMark rm;
-  HandleMark hm;
+  ResourceMark rm(current_thread);
+  HandleMark hm(current_thread);
 
   Handle group_hdl(current_thread, group_obj);
 
-  { MutexLocker mu(Threads_lock);
+  { // Cannot allow thread or group counts to change.
+    MutexLocker mu(Threads_lock);
 
     nthreads = java_lang_ThreadGroup::nthreads(group_hdl());
     ngroups  = java_lang_ThreadGroup::ngroups(group_hdl());
 
     if (nthreads > 0) {
+      ThreadsListHandle tlh(current_thread);
       objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl());
       assert(nthreads <= threads->length(), "too many threads");
       thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads);
       for (int i=0, j=0; i<nthreads; i++) {
         oop thread_obj = threads->obj_at(i);
         assert(thread_obj != NULL, "thread_obj is NULL");
-        JavaThread *javathread = java_lang_Thread::thread(thread_obj);
-        // Filter out hidden java threads.
-        if (javathread != NULL && javathread->is_hidden_from_external_view()) {
-          hidden_threads++;
-          continue;
+        JavaThread *java_thread = NULL;
+        jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &java_thread);
+        if (err == JVMTI_ERROR_NONE) {
+          // Have a valid JavaThread*.
+          if (java_thread->is_hidden_from_external_view()) {
+            // Filter out hidden java threads.
+            hidden_threads++;
+            continue;
+          }
+        } else {
+          // We couldn't convert thread_obj into a JavaThread*.
+          if (err == JVMTI_ERROR_INVALID_THREAD) {
+            // The thread_obj does not refer to a java.lang.Thread object
+            // so skip it.
+            hidden_threads++;
+            continue;
+          }
+          // We have a valid thread_obj, but no JavaThread*; the caller
+          // can still have limited use for the thread_obj.
         }
         thread_objs[j++] = Handle(current_thread, thread_obj);
       }
       nthreads -= hidden_threads;
-    }
+    } // ThreadsListHandle is destroyed here.
+
     if (ngroups > 0) {
       objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl());
-      assert(ngroups <= groups->length(), "too many threads");
+      assert(ngroups <= groups->length(), "too many groups");
       group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups);
       for (int i=0; i<ngroups; i++) {
         oop group_obj = groups->obj_at(i);
@@ -1556,7 +1613,7 @@
   }
 
   // Check if java_thread is fully suspended
-  if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) {
+  if (!java_thread->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
     return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
   // Check to see if a PopFrame was already in progress
@@ -1686,8 +1743,8 @@
     return JVMTI_ERROR_THREAD_NOT_ALIVE;
   }
 
-  if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) {
-      return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
+  if (!java_thread->is_thread_fully_suspended(true, &debug_bits)) {
+    return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
 
   if (TraceJVMTICalls) {
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -44,6 +44,7 @@
 #include "runtime/objectMonitor.inline.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframe_hp.hpp"
 #include "runtime/vmThread.hpp"
@@ -487,37 +488,6 @@
   }
 }
 
-// Called from JVMTI entry points which perform stack walking. If the
-// associated JavaThread is the current thread, then wait_for_suspend
-// is not used. Otherwise, it determines if we should wait for the
-// "other" thread to complete external suspension. (NOTE: in future
-// releases the suspension mechanism should be reimplemented so this
-// is not necessary.)
-//
-bool
-JvmtiEnvBase::is_thread_fully_suspended(JavaThread* thr, bool wait_for_suspend, uint32_t *bits) {
-  // "other" threads require special handling
-  if (thr != JavaThread::current()) {
-    if (wait_for_suspend) {
-      // We are allowed to wait for the external suspend to complete
-      // so give the other thread a chance to get suspended.
-      if (!thr->wait_for_ext_suspend_completion(SuspendRetryCount,
-          SuspendRetryDelay, bits)) {
-        // didn't make it so let the caller know
-        return false;
-      }
-    }
-    // We aren't allowed to wait for the external suspend to complete
-    // so if the other thread isn't externally suspended we need to
-    // let the caller know.
-    else if (!thr->is_ext_suspend_completed_with_lock(bits)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 
 // In the fullness of time, all users of the method should instead
 // directly use allocate, besides being cleaner and faster, this will
@@ -560,19 +530,6 @@
   return (jthreadGroup *) new_jobjectArray(length,handles);
 }
 
-
-JavaThread *
-JvmtiEnvBase::get_JavaThread(jthread jni_thread) {
-  oop t = JNIHandles::resolve_external_guard(jni_thread);
-  if (t == NULL || !t->is_a(SystemDictionary::Thread_klass())) {
-    return NULL;
-  }
-  // The following returns NULL if the thread has not yet run or is in
-  // process of exiting
-  return java_lang_Thread::thread(t);
-}
-
-
 // return the vframe on the specified thread and depth, NULL if no such frame
 vframe*
 JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) {
@@ -670,7 +627,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
   oop obj = NULL;
   ObjectMonitor *mon = java_thread->current_waiting_monitor();
@@ -709,7 +666,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
 
   if (java_thread->has_last_Java_frame()) {
@@ -831,7 +788,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
   int count = 0;
   if (java_thread->has_last_Java_frame()) {
@@ -914,7 +871,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
   Thread* current_thread = Thread::current();
   ResourceMark rm(current_thread);
@@ -976,7 +933,7 @@
   // first derive the object's owner and entry_count (if any)
   {
     // Revoke any biases before querying the mark word
-    if (SafepointSynchronize::is_at_safepoint()) {
+    if (at_safepoint) {
       BiasedLocking::revoke_at_safepoint(hobj);
     } else {
       BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
@@ -1008,11 +965,11 @@
     }
 
     if (owner != NULL) {
+      // Use current thread since function can be called from a
+      // JavaThread or the VMThread.
+      ThreadsListHandle tlh;
       // This monitor is owned so we have to find the owning JavaThread.
-      // Since owning_thread_from_monitor_owner() grabs a lock, GC can
-      // move our object at this point. However, our owner value is safe
-      // since it is either the Lock word on a stack or a JavaThread *.
-      owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
+      owning_thread = Threads::owning_thread_from_monitor_owner(tlh.list(), owner);
       // Cannot assume (owning_thread != NULL) here because this function
       // may not have been called at a safepoint and the owning_thread
       // might not be suspended.
@@ -1021,7 +978,7 @@
         // or it has to be suspended. Any of these conditions will prevent both
         // contending and waiting threads from modifying the state of
         // the monitor.
-        if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) {
+        if (!at_safepoint && !owning_thread->is_thread_fully_suspended(true, &debug_bits)) {
           // Don't worry! This return of JVMTI_ERROR_THREAD_NOT_SUSPENDED
           // will not make it back to the JVM/TI agent. The error code will
           // get intercepted in JvmtiEnv::GetObjectMonitorUsage() which
@@ -1033,7 +990,7 @@
         ret.owner = (jthread)jni_reference(calling_thread, th);
       }
       // implied else: no owner
-    }
+    } // ThreadsListHandle is destroyed here.
 
     if (owning_thread != NULL) {  // monitor is owned
       // The recursions field of a monitor does not reflect recursions
@@ -1084,13 +1041,15 @@
     if (ret.waiter_count > 0) {
       // we have contending and/or waiting threads
       HandleMark hm;
+      // Use current thread since function can be called from a
+      // JavaThread or the VMThread.
+      ThreadsListHandle tlh;
       if (nWant > 0) {
         // we have contending threads
         ResourceMark rm;
         // get_pending_threads returns only java thread so we do not need to
-        // check for  non java threads.
-        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(
-          nWant, (address)mon, !at_safepoint);
+        // check for non java threads.
+        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(tlh.list(), nWant, (address)mon);
         if (wantList->length() < nWant) {
           // robustness: the pending list has gotten smaller
           nWant = wantList->length();
@@ -1101,7 +1060,7 @@
           // thread could potentially change the state of the monitor by
           // entering it. The JVM/TI spec doesn't allow this.
           if (owning_thread == NULL && !at_safepoint &
-              !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) {
+              !pending_thread->is_thread_fully_suspended(true, &debug_bits)) {
             if (ret.owner != NULL) {
               destroy_jni_reference(calling_thread, ret.owner);
             }
@@ -1139,7 +1098,7 @@
           waiter = mon->next_waiter(waiter);
         }
       }
-    }
+    } // ThreadsListHandle is destroyed here.
 
     // Adjust count. nWant and nWait count values may be less than original.
     ret.waiter_count = nWant + nWait;
@@ -1291,14 +1250,23 @@
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
   ResourceMark rm;
+  ThreadsListHandle tlh;
   for (int i = 0; i < _thread_count; ++i) {
     jthread jt = _thread_list[i];
-    oop thread_oop = JNIHandles::resolve_external_guard(jt);
-    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
-      set_result(JVMTI_ERROR_INVALID_THREAD);
-      return;
+    JavaThread* java_thread = NULL;
+    oop thread_oop = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), jt, &java_thread, &thread_oop);
+    if (err != JVMTI_ERROR_NONE) {
+      // We got an error code so we don't have a JavaThread *, but
+      // only return an error from here if we didn't get a valid
+      // thread_oop.
+      if (thread_oop == NULL) {
+        set_result(err);
+        return;
+      }
+      // We have a valid thread_oop.
     }
-    fill_frames(jt, java_lang_Thread::thread(thread_oop), thread_oop);
+    fill_frames(jt, java_thread, thread_oop);
   }
   allocate_and_fill_stacks(_thread_count);
 }
@@ -1309,7 +1277,7 @@
 
   ResourceMark rm;
   _final_thread_count = 0;
-  for (JavaThread *jt = Threads::first(); jt != NULL; jt = jt->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
     oop thread_oop = jt->threadObj();
     if (thread_oop != NULL &&
         !jt->is_exiting() &&
@@ -1404,9 +1372,7 @@
   }
 
   // Check if java_thread is fully suspended
-  if (!is_thread_fully_suspended(java_thread,
-                                 true /* wait for suspend completion */,
-                                 &debug_bits)) {
+  if (!java_thread->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
     return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
 
@@ -1521,3 +1487,79 @@
   return JVMTI_ERROR_NONE;
 }
 
+void
+VM_UpdateForPopTopFrame::doit() {
+  JavaThread* jt = _state->get_thread();
+  ThreadsListHandle tlh;
+  if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+    _state->update_for_pop_top_frame();
+  } else {
+    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+}
+
+void
+VM_SetFramePop::doit() {
+  JavaThread* jt = _state->get_thread();
+  ThreadsListHandle tlh;
+  if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+    int frame_number = _state->count_frames() - _depth;
+    _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
+  } else {
+    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+}
+
+void
+VM_GetOwnedMonitorInfo::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,
+                                                          _owned_monitors_list);
+  }
+}
+
+void
+VM_GetCurrentContendedMonitor::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
+  }
+}
+
+void
+VM_GetStackTrace::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,
+                                                      _start_depth, _max_count,
+                                                      _frame_buffer, _count_ptr);
+  }
+}
+
+void
+VM_GetFrameCount::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  JavaThread* jt = _state->get_thread();
+  ThreadsListHandle tlh;
+  if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);
+  }
+}
+
+void
+VM_GetFrameLocation::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,
+                                                        _method_ptr, _location_ptr);
+  }
+}
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -280,9 +280,6 @@
   jthread * new_jthreadArray(int length, Handle *handles);
   jthreadGroup * new_jthreadGroupArray(int length, Handle *handles);
 
-  // convert from JNIHandle to JavaThread *
-  JavaThread  * get_JavaThread(jthread jni_thread);
-
   // convert to a jni jclass from a non-null Klass*
   jclass get_jni_class_non_null(Klass* k);
 
@@ -297,11 +294,6 @@
  public:
   // get a field descriptor for the specified class and field
   static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);
-  // test for suspend - most (all?) of these should go away
-  static bool is_thread_fully_suspended(JavaThread *thread,
-                                        bool wait_for_suspend,
-                                        uint32_t *bits);
-
 
   // JVMTI API helper functions which are called at safepoint or thread is suspended.
   jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);
@@ -360,14 +352,7 @@
   }
   VMOp_Type type() const { return VMOp_UpdateForPopTopFrame; }
   jvmtiError result() { return _result; }
-  void doit() {
-    JavaThread* jt = _state->get_thread();
-    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
-      _state->update_for_pop_top_frame();
-    } else {
-      _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    }
-  }
+  void doit();
 };
 
 // VM operation to set frame pop.
@@ -390,15 +375,7 @@
   bool allow_nested_vm_operations() const { return true; }
   VMOp_Type type() const { return VMOp_SetFramePop; }
   jvmtiError result() { return _result; }
-  void doit() {
-    JavaThread* jt = _state->get_thread();
-    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
-      int frame_number = _state->count_frames() - _depth;
-      _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
-    } else {
-      _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    }
-  }
+  void doit();
 };
 
 
@@ -422,14 +399,7 @@
     _result = JVMTI_ERROR_NONE;
   }
   VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting()
-                                        && _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,
-                                                            _owned_monitors_list);
-    }
-  }
+  void doit();
   jvmtiError result() { return _result; }
 };
 
@@ -476,13 +446,7 @@
   }
   VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }
   jvmtiError result() { return _result; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
-        _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
-    }
-  }
+  void doit();
 };
 
 // VM operation to get stack trace at safepoint.
@@ -509,15 +473,7 @@
   }
   jvmtiError result() { return _result; }
   VMOp_Type type() const { return VMOp_GetStackTrace; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting()
-                                        && _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,
-                                                        _start_depth, _max_count,
-                                                        _frame_buffer, _count_ptr);
-    }
-  }
+  void doit();
 };
 
 // forward declaration
@@ -607,13 +563,7 @@
   }
   VMOp_Type type() const { return VMOp_GetFrameCount; }
   jvmtiError result()    { return _result; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    JavaThread* jt = _state->get_thread();
-    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);
-    }
-  }
+  void doit();
 };
 
 // VM operation to frame location at safepoint.
@@ -637,14 +587,7 @@
   }
   VMOp_Type type() const { return VMOp_GetFrameLocation; }
   jvmtiError result()    { return _result; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
-        _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,
-                                                          _method_ptr, _location_ptr);
-    }
-  }
+  void doit();
 };
 
 
--- a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -35,6 +35,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vm_operations.hpp"
 
--- a/src/hotspot/share/prims/jvmtiEnvThreadState.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvThreadState.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,7 +27,6 @@
 
 #include "jvmtifiles/jvmti.h"
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "prims/jvmtiEventController.hpp"
 #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/prims/jvmtiEventController.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEventController.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -33,7 +33,8 @@
 #include "prims/jvmtiImpl.hpp"
 #include "prims/jvmtiThreadState.inline.hpp"
 #include "runtime/frame.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframe_hp.hpp"
 #include "runtime/vmThread.hpp"
@@ -580,13 +581,10 @@
   // filtered events and there weren't last time
   if (    (any_env_thread_enabled & THREAD_FILTERED_EVENT_BITS) != 0 &&
       (was_any_env_thread_enabled & THREAD_FILTERED_EVENT_BITS) == 0) {
-    {
-      MutexLocker mu(Threads_lock);   //hold the Threads_lock for the iteration
-      for (JavaThread *tp = Threads::first(); tp != NULL; tp = tp->next()) {
-        // state_for_while_locked() makes tp->is_exiting() check
-        JvmtiThreadState::state_for_while_locked(tp);  // create the thread state if missing
-      }
-    }// release Threads_lock
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *tp = jtiwh.next(); ) {
+      // state_for_while_locked() makes tp->is_exiting() check
+      JvmtiThreadState::state_for_while_locked(tp);  // create the thread state if missing
+    }
   }
 
   // compute and set thread-filtered events
--- a/src/hotspot/share/prims/jvmtiEventController.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEventController.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,7 +27,6 @@
 
 #include "jvmtifiles/jvmti.h"
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
 
 // forward declaration
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -53,6 +53,7 @@
 #include "runtime/objectMonitor.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "services/serviceUtil.hpp"
 #include "utilities/macros.hpp"
@@ -721,6 +722,108 @@
   }
 }
 
+// Convert an external thread reference to a JavaThread found on the
+// specified ThreadsList. The ThreadsListHandle in the caller "protects"
+// the returned JavaThread *.
+//
+// If thread_oop_p is not NULL, then the caller wants to use the oop
+// after this call so the oop is returned. On success, *jt_pp is set
+// to the converted JavaThread * and JVMTI_ERROR_NONE is returned.
+// On error, returns various JVMTI_ERROR_* values.
+//
+jvmtiError
+JvmtiExport::cv_external_thread_to_JavaThread(ThreadsList * t_list,
+                                              jthread thread,
+                                              JavaThread ** jt_pp,
+                                              oop * thread_oop_p) {
+  assert(t_list != NULL, "must have a ThreadsList");
+  assert(jt_pp != NULL, "must have a return JavaThread pointer");
+  // thread_oop_p is optional so no assert()
+
+  oop thread_oop = JNIHandles::resolve_external_guard(thread);
+  if (thread_oop == NULL) {
+    // NULL jthread, GC'ed jthread or a bad JNI handle.
+    return JVMTI_ERROR_INVALID_THREAD;
+  }
+  // Looks like an oop at this point.
+
+  if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
+    // The oop is not a java.lang.Thread.
+    return JVMTI_ERROR_INVALID_THREAD;
+  }
+  // Looks like a java.lang.Thread oop at this point.
+
+  if (thread_oop_p != NULL) {
+    // Return the oop to the caller; the caller may still want
+    // the oop even if this function returns an error.
+    *thread_oop_p = thread_oop;
+  }
+
+  JavaThread * java_thread = java_lang_Thread::thread(thread_oop);
+  if (java_thread == NULL) {
+    // The java.lang.Thread does not contain a JavaThread * so it has
+    // not yet run or it has died.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+  // Looks like a live JavaThread at this point.
+
+  // We do not check the EnableThreadSMRExtraValidityChecks option
+  // for this includes() call because JVM/TI's spec is tighter.
+  if (!t_list->includes(java_thread)) {
+    // Not on the JavaThreads list so it is not alive.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+
+  // Return a live JavaThread that is "protected" by the
+  // ThreadsListHandle in the caller.
+  *jt_pp = java_thread;
+
+  return JVMTI_ERROR_NONE;
+}
+
+// Convert an oop to a JavaThread found on the specified ThreadsList.
+// The ThreadsListHandle in the caller "protects" the returned
+// JavaThread *.
+//
+// On success, *jt_pp is set to the converted JavaThread * and
+// JVMTI_ERROR_NONE is returned. On error, returns various
+// JVMTI_ERROR_* values.
+//
+jvmtiError
+JvmtiExport::cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop,
+                                  JavaThread ** jt_pp) {
+  assert(t_list != NULL, "must have a ThreadsList");
+  assert(thread_oop != NULL, "must have an oop");
+  assert(jt_pp != NULL, "must have a return JavaThread pointer");
+
+  if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
+    // The oop is not a java.lang.Thread.
+    return JVMTI_ERROR_INVALID_THREAD;
+  }
+  // Looks like a java.lang.Thread oop at this point.
+
+  JavaThread * java_thread = java_lang_Thread::thread(thread_oop);
+  if (java_thread == NULL) {
+    // The java.lang.Thread does not contain a JavaThread * so it has
+    // not yet run or it has died.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+  // Looks like a live JavaThread at this point.
+
+  // We do not check the EnableThreadSMRExtraValidityChecks option
+  // for this includes() call because JVM/TI's spec is tighter.
+  if (!t_list->includes(java_thread)) {
+    // Not on the JavaThreads list so it is not alive.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+
+  // Return a live JavaThread that is "protected" by the
+  // ThreadsListHandle in the caller.
+  *jt_pp = java_thread;
+
+  return JVMTI_ERROR_NONE;
+}
+
 class JvmtiClassFileLoadHookPoster : public StackObj {
  private:
   Symbol*            _h_name;
@@ -2475,7 +2578,7 @@
 
 jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,
                                      const char *options, outputStream* st) {
-  char ebuf[1024];
+  char ebuf[1024] = {0};
   char buffer[JVM_MAXPATHLEN];
   void* library = NULL;
   jint result = JNI_ERR;
@@ -2525,6 +2628,8 @@
       if (!agent_lib->is_static_lib()) {
         os::dll_unload(library);
       }
+      st->print_cr("%s is not available in %s",
+                   on_attach_symbols[0], agent_lib->name());
       delete agent_lib;
     } else {
       // Invoke the Agent_OnAttach function
@@ -2551,9 +2656,14 @@
       }
 
       // Agent_OnAttach executed so completion status is JNI_OK
-      st->print_cr("%d", result);
+      st->print_cr("return code: %d", result);
       result = JNI_OK;
     }
+  } else {
+    st->print_cr("%s was not loaded.", agent);
+    if (*ebuf != '\0') {
+      st->print_cr("%s", ebuf);
+    }
   }
   return result;
 }
@@ -2685,8 +2795,7 @@
     return;
   }
 
-  // Runs at safepoint. So no need to acquire Threads_lock.
-  for (JavaThread *jthr = Threads::first(); jthr != NULL; jthr = jthr->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jthr = jtiwh.next(); ) {
     JvmtiThreadState *state = jthr->jvmti_thread_state();
     if (state != NULL) {
       JvmtiVMObjectAllocEventCollector *collector;
--- a/src/hotspot/share/prims/jvmtiExport.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiExport.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -399,6 +399,14 @@
 
   // SetNativeMethodPrefix support
   static char** get_all_native_method_prefixes(int* count_ptr) NOT_JVMTI_RETURN_(NULL);
+
+  // JavaThread lifecycle support:
+  static jvmtiError cv_external_thread_to_JavaThread(ThreadsList * t_list,
+                                                     jthread thread,
+                                                     JavaThread ** jt_pp,
+                                                     oop * thread_oop_p);
+  static jvmtiError cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop,
+                                         JavaThread ** jt_pp);
 };
 
 // Support class used by JvmtiDynamicCodeEventCollector and others. It
--- a/src/hotspot/share/prims/jvmtiImpl.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -46,6 +46,7 @@
 #include "runtime/serviceThread.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframe_hp.hpp"
 #include "runtime/vm_operations.hpp"
@@ -878,10 +879,9 @@
 
 void JvmtiSuspendControl::print() {
 #ifndef PRODUCT
-  MutexLocker mu(Threads_lock);
   LogStreamHandle(Trace, jvmti) log_stream;
   log_stream.print("Suspended Threads: [");
-  for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
 #ifdef JVMTI_TRACE
     const char *name   = JvmtiTrace::safe_get_thread_name(thread);
 #else
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -43,6 +43,7 @@
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiImpl.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
+#include "prims/jvmtiThreadState.inline.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "prims/methodComparator.hpp"
 #include "runtime/deoptimization.hpp"
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -45,6 +45,8 @@
 #include "runtime/mutex.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/reflectionUtils.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
@@ -3174,7 +3176,7 @@
 // stack to find all references and local JNI refs.
 inline bool VM_HeapWalkOperation::collect_stack_roots() {
   JNILocalRootsClosure blk;
-  for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     oop threadObj = thread->threadObj();
     if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
       // Collect the simple root for this thread before we
--- a/src/hotspot/share/prims/jvmtiThreadState.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiThreadState.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,7 +27,6 @@
 
 #include "jvmtifiles/jvmti.h"
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "prims/jvmtiEventController.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/growableArray.hpp"
@@ -336,34 +335,10 @@
 
   // already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState
   // Can return NULL if JavaThread is exiting.
-  inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) {
-    assert(JvmtiThreadState_lock->is_locked(), "sanity check");
-
-    JvmtiThreadState *state = thread->jvmti_thread_state();
-    if (state == NULL) {
-      if (thread->is_exiting()) {
-        // don't add a JvmtiThreadState to a thread that is exiting
-        return NULL;
-      }
-
-      state = new JvmtiThreadState(thread);
-    }
-    return state;
-  }
-
+  static JvmtiThreadState *state_for_while_locked(JavaThread *thread);
   // retrieve or create JvmtiThreadState
   // Can return NULL if JavaThread is exiting.
-  inline static JvmtiThreadState *state_for(JavaThread *thread) {
-    JvmtiThreadState *state = thread->jvmti_thread_state();
-    if (state == NULL) {
-      MutexLocker mu(JvmtiThreadState_lock);
-      // check again with the lock held
-      state = state_for_while_locked(thread);
-    } else {
-      CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
-    }
-    return state;
-  }
+  static JvmtiThreadState *state_for(JavaThread *thread);
 
   // JVMTI ForceEarlyReturn support
 
--- a/src/hotspot/share/prims/jvmtiThreadState.inline.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiThreadState.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -68,4 +68,31 @@
   _head_env_thread_state = ets;
 }
 
+inline JvmtiThreadState* JvmtiThreadState::state_for_while_locked(JavaThread *thread) {
+  assert(JvmtiThreadState_lock->is_locked(), "sanity check");
+
+  JvmtiThreadState *state = thread->jvmti_thread_state();
+  if (state == NULL) {
+    if (thread->is_exiting()) {
+      // don't add a JvmtiThreadState to a thread that is exiting
+      return NULL;
+    }
+
+    state = new JvmtiThreadState(thread);
+  }
+  return state;
+}
+
+inline JvmtiThreadState* JvmtiThreadState::state_for(JavaThread *thread) {
+  JvmtiThreadState *state = thread->jvmti_thread_state();
+  if (state == NULL) {
+    MutexLocker mu(JvmtiThreadState_lock);
+    // check again with the lock held
+    state = state_for_while_locked(thread);
+  } else {
+    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
+  }
+  return state;
+}
+
 #endif // SHARE_VM_PRIMS_JVMTITHREADSTATE_INLINE_HPP
--- a/src/hotspot/share/prims/methodHandles.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/methodHandles.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1029,6 +1029,26 @@
   }
 }
 
+void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
+  if (TraceMethodHandles) {
+    const char* name = vmIntrinsics::name_at(iid);
+    if (*name == '_')  name += 1;
+    const size_t len = strlen(name) + 50;
+    char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+    const char* suffix = "";
+    if (is_signature_polymorphic(iid)) {
+      if (is_signature_polymorphic_static(iid))
+        suffix = "/static";
+      else
+        suffix = "/private";
+    }
+    jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
+    trace_method_handle(_masm, qname);
+    // Note:  Don't free the allocated char array because it's used
+    // during runtime.
+  }
+}
+
 //
 // Here are the native methods in java.lang.invoke.MethodHandleNatives
 // They are the private interface between this JVM and the HotSpot-specific
--- a/src/hotspot/share/prims/methodHandles.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/methodHandles.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -195,25 +195,7 @@
 
   // Tracing
   static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
-  static void trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
-    if (TraceMethodHandles) {
-      const char* name = vmIntrinsics::name_at(iid);
-      if (*name == '_')  name += 1;
-      const size_t len = strlen(name) + 50;
-      char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal);
-      const char* suffix = "";
-      if (is_signature_polymorphic(iid)) {
-        if (is_signature_polymorphic_static(iid))
-          suffix = "/static";
-        else
-          suffix = "/private";
-      }
-      jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
-      trace_method_handle(_masm, qname);
-      // Note:  Don't free the allocated char array because it's used
-      // during runtime.
-    }
-  }
+  static void trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid);
 };
 
 //------------------------------------------------------------------------------
--- a/src/hotspot/share/prims/perf.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/perf.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -30,7 +30,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
-#include "runtime/perfData.hpp"
+#include "runtime/perfData.inline.hpp"
 #include "runtime/perfMemory.hpp"
 
 /*
--- a/src/hotspot/share/prims/unsafe.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/unsafe.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,8 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/reflection.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/threadService.hpp"
 #include "trace/tracing.hpp"
@@ -144,18 +146,25 @@
  * Normalizes values and wraps accesses in
  * JavaThread::doing_unsafe_access() if needed.
  */
+template <typename T>
 class MemoryAccess : StackObj {
   JavaThread* _thread;
   oop _obj;
   ptrdiff_t _offset;
 
-  // Resolves and returns the address of the memory access
-  void* addr() {
-    return index_oop_from_field_offset_long(_obj, _offset);
+  // Resolves and returns the address of the memory access.
+  // This raw memory access may fault, so we make sure it happens within the
+  // guarded scope by making the access volatile at least. Since the store
+  // of Thread::set_doing_unsafe_access() is also volatile, these accesses
+  // can not be reordered by the compiler. Therefore, if the access triggers
+  // a fault, we will know that Thread::doing_unsafe_access() returns true.
+  volatile T* addr() {
+    void* addr = index_oop_from_field_offset_long(_obj, _offset);
+    return static_cast<volatile T*>(addr);
   }
 
-  template <typename T>
-  T normalize_for_write(T x) {
+  template <typename U>
+  U normalize_for_write(U x) {
     return x;
   }
 
@@ -163,8 +172,8 @@
     return x & 1;
   }
 
-  template <typename T>
-  T normalize_for_read(T x) {
+  template <typename U>
+  U normalize_for_read(U x) {
     return x;
   }
 
@@ -197,11 +206,10 @@
     assert_field_offset_sane(_obj, offset);
   }
 
-  template <typename T>
   T get() {
     if (oopDesc::is_null(_obj)) {
       GuardUnsafeAccess guard(_thread);
-      T ret = RawAccess<>::load((T*)addr());
+      T ret = RawAccess<>::load(addr());
       return normalize_for_read(ret);
     } else {
       T ret = HeapAccess<>::load_at(_obj, _offset);
@@ -209,22 +217,20 @@
     }
   }
 
-  template <typename T>
   void put(T x) {
     if (oopDesc::is_null(_obj)) {
       GuardUnsafeAccess guard(_thread);
-      RawAccess<>::store((T*)addr(), normalize_for_write(x));
+      RawAccess<>::store(addr(), normalize_for_write(x));
     } else {
       HeapAccess<>::store_at(_obj, _offset, normalize_for_write(x));
     }
   }
 
 
-  template <typename T>
   T get_volatile() {
     if (oopDesc::is_null(_obj)) {
       GuardUnsafeAccess guard(_thread);
-      volatile T ret = RawAccess<MO_SEQ_CST>::load((volatile T*)addr());
+      volatile T ret = RawAccess<MO_SEQ_CST>::load(addr());
       return normalize_for_read(ret);
     } else {
       T ret = HeapAccess<MO_SEQ_CST>::load_at(_obj, _offset);
@@ -232,11 +238,10 @@
     }
   }
 
-  template <typename T>
   void put_volatile(T x) {
     if (oopDesc::is_null(_obj)) {
       GuardUnsafeAccess guard(_thread);
-      RawAccess<MO_SEQ_CST>::store((volatile T*)addr(), normalize_for_write(x));
+      RawAccess<MO_SEQ_CST>::store(addr(), normalize_for_write(x));
     } else {
       HeapAccess<MO_SEQ_CST>::store_at(_obj, _offset, normalize_for_write(x));
     }
@@ -294,11 +299,11 @@
 #define DEFINE_GETSETOOP(java_type, Type) \
  \
 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
-  return MemoryAccess(thread, obj, offset).get<java_type>(); \
+  return MemoryAccess<java_type>(thread, obj, offset).get(); \
 } UNSAFE_END \
  \
 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
-  MemoryAccess(thread, obj, offset).put<java_type>(x); \
+  MemoryAccess<java_type>(thread, obj, offset).put(x); \
 } UNSAFE_END \
  \
 // END DEFINE_GETSETOOP.
@@ -317,11 +322,11 @@
 #define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
  \
 UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
-  return MemoryAccess(thread, obj, offset).get_volatile<java_type>(); \
+  return MemoryAccess<java_type>(thread, obj, offset).get_volatile(); \
 } UNSAFE_END \
  \
 UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
-  MemoryAccess(thread, obj, offset).put_volatile<java_type>(x); \
+  MemoryAccess<java_type>(thread, obj, offset).put_volatile(x); \
 } UNSAFE_END \
  \
 // END DEFINE_GETSETOOP_VOLATILE.
@@ -937,8 +942,12 @@
   Parker* p = NULL;
 
   if (jthread != NULL) {
-    oop java_thread = JNIHandles::resolve_non_null(jthread);
+    ThreadsListHandle tlh;
+    JavaThread* thr = NULL;
+    oop java_thread = NULL;
+    (void) tlh.cv_internal_thread_to_JavaThread(jthread, &thr, &java_thread);
     if (java_thread != NULL) {
+      // This is a valid oop.
       jlong lp = java_lang_Thread::park_event(java_thread);
       if (lp != 0) {
         // This cast is OK even though the jlong might have been read
@@ -946,22 +955,19 @@
         // always be zero anyway and the value set is always the same
         p = (Parker*)addr_from_java(lp);
       } else {
-        // Grab lock if apparently null or using older version of library
-        MutexLocker mu(Threads_lock);
-        java_thread = JNIHandles::resolve_non_null(jthread);
-
-        if (java_thread != NULL) {
-          JavaThread* thr = java_lang_Thread::thread(java_thread);
-          if (thr != NULL) {
-            p = thr->parker();
-            if (p != NULL) { // Bind to Java thread for next time.
-              java_lang_Thread::set_park_event(java_thread, addr_to_java(p));
-            }
+        // Not cached in the java.lang.Thread oop yet (could be an
+        // older version of library).
+        if (thr != NULL) {
+          // The JavaThread is alive.
+          p = thr->parker();
+          if (p != NULL) {
+            // Cache the Parker in the java.lang.Thread oop for next time.
+            java_lang_Thread::set_park_event(java_thread, addr_to_java(p));
           }
         }
       }
     }
-  }
+  } // ThreadsListHandle is destroyed here.
 
   if (p != NULL) {
     HOTSPOT_THREAD_UNPARK((uintptr_t) p);
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/prims/whitebox.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -55,11 +55,15 @@
 #include "runtime/os.hpp"
 #include "runtime/sweeper.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/macros.hpp"
+#if INCLUDE_CDS
+#include "prims/cdsoffsets.hpp"
+#endif // INCLUDE_CDS
 #if INCLUDE_ALL_GCS
 #include "gc/g1/concurrentMarkThread.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
@@ -665,7 +669,7 @@
   int  result() const { return _result; }
 
   void doit() {
-    for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
       if (t->has_last_Java_frame()) {
         for (StackFrameStream fst(t, UseBiasedLocking); !fst.is_done(); fst.next()) {
           frame* f = fst.current();
@@ -1729,6 +1733,18 @@
 #endif
 WB_END
 
+
+#if INCLUDE_CDS
+
+WB_ENTRY(jint, WB_GetOffsetForName(JNIEnv* env, jobject o, jstring name))
+  ResourceMark rm;
+  char* c_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
+  int result = CDSOffsets::find_offset(c_name);
+  return (jint)result;
+WB_END
+
+#endif // INCLUDE_CDS
+
 WB_ENTRY(jint, WB_HandshakeWalkStack(JNIEnv* env, jobject wb, jobject thread_handle, jboolean all_threads))
   class TraceSelfClosure : public ThreadClosure {
     jint _num_threads_completed;
@@ -1917,6 +1933,9 @@
   {CC"runMemoryUnitTests", CC"()V",                   (void*)&WB_RunMemoryUnitTests},
   {CC"readFromNoaccessArea",CC"()V",                  (void*)&WB_ReadFromNoaccessArea},
   {CC"stressVirtualSpaceResize",CC"(JJJ)I",           (void*)&WB_StressVirtualSpaceResize},
+#if INCLUDE_CDS
+  {CC"getOffsetForName0", CC"(Ljava/lang/String;)I",  (void*)&WB_GetOffsetForName},
+#endif
 #if INCLUDE_ALL_GCS
   {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
   {CC"g1IsHumongous0",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/arguments.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -114,6 +114,108 @@
 
 char* Arguments::_ext_dirs = NULL;
 
+bool PathString::set_value(const char *value) {
+  if (_value != NULL) {
+    FreeHeap(_value);
+  }
+  _value = AllocateHeap(strlen(value)+1, mtArguments);
+  assert(_value != NULL, "Unable to allocate space for new path value");
+  if (_value != NULL) {
+    strcpy(_value, value);
+  } else {
+    // not able to allocate
+    return false;
+  }
+  return true;
+}
+
+void PathString::append_value(const char *value) {
+  char *sp;
+  size_t len = 0;
+  if (value != NULL) {
+    len = strlen(value);
+    if (_value != NULL) {
+      len += strlen(_value);
+    }
+    sp = AllocateHeap(len+2, mtArguments);
+    assert(sp != NULL, "Unable to allocate space for new append path value");
+    if (sp != NULL) {
+      if (_value != NULL) {
+        strcpy(sp, _value);
+        strcat(sp, os::path_separator());
+        strcat(sp, value);
+        FreeHeap(_value);
+      } else {
+        strcpy(sp, value);
+      }
+      _value = sp;
+    }
+  }
+}
+
+PathString::PathString(const char* value) {
+  if (value == NULL) {
+    _value = NULL;
+  } else {
+    _value = AllocateHeap(strlen(value)+1, mtArguments);
+    strcpy(_value, value);
+  }
+}
+
+PathString::~PathString() {
+  if (_value != NULL) {
+    FreeHeap(_value);
+    _value = NULL;
+  }
+}
+
+ModulePatchPath::ModulePatchPath(const char* module_name, const char* path) {
+  assert(module_name != NULL && path != NULL, "Invalid module name or path value");
+  size_t len = strlen(module_name) + 1;
+  _module_name = AllocateHeap(len, mtInternal);
+  strncpy(_module_name, module_name, len); // copy the trailing null
+  _path =  new PathString(path);
+}
+
+ModulePatchPath::~ModulePatchPath() {
+  if (_module_name != NULL) {
+    FreeHeap(_module_name);
+    _module_name = NULL;
+  }
+  if (_path != NULL) {
+    delete _path;
+    _path = NULL;
+  }
+}
+
+SystemProperty::SystemProperty(const char* key, const char* value, bool writeable, bool internal) : PathString(value) {
+  if (key == NULL) {
+    _key = NULL;
+  } else {
+    _key = AllocateHeap(strlen(key)+1, mtArguments);
+    strcpy(_key, key);
+  }
+  _next = NULL;
+  _internal = internal;
+  _writeable = writeable;
+}
+
+AgentLibrary::AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
+  _name = AllocateHeap(strlen(name)+1, mtArguments);
+  strcpy(_name, name);
+  if (options == NULL) {
+    _options = NULL;
+  } else {
+    _options = AllocateHeap(strlen(options)+1, mtArguments);
+    strcpy(_options, options);
+  }
+  _is_absolute_path = is_absolute_path;
+  _os_lib = os_lib;
+  _next = NULL;
+  _state = agent_invalid;
+  _is_static_lib = false;
+}
+
 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
 // part of the option string.
 static bool match_option(const JavaVMOption *option, const char* name,
@@ -180,6 +282,23 @@
 #define UPGRADE_PATH "upgrade.path"
 #define UPGRADE_PATH_LEN 12
 
+void Arguments::add_init_library(const char* name, char* options) {
+  _libraryList.add(new AgentLibrary(name, options, false, NULL));
+}
+
+void Arguments::add_init_agent(const char* name, char* options, bool absolute_path) {
+  _agentList.add(new AgentLibrary(name, options, absolute_path, NULL));
+}
+
+// Late-binding agents not started via arguments
+void Arguments::add_loaded_agent(AgentLibrary *agentLib) {
+  _agentList.add(agentLib);
+}
+
+void Arguments::add_loaded_agent(const char* name, char* options, bool absolute_path, void* os_lib) {
+  _agentList.add(new AgentLibrary(name, options, absolute_path, os_lib));
+}
+
 // Return TRUE if option matches 'property', or 'property=', or 'property.'.
 static bool matches_property_suffix(const char* option, const char* property, size_t len) {
   return ((strncmp(option, property, len) == 0) &&
@@ -2152,12 +2271,7 @@
   // Check lower bounds of the code cache
   // Template Interpreter code is approximately 3X larger in debug builds.
   uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
-  if (InitialCodeCacheSize < (uintx)os::vm_page_size()) {
-    jio_fprintf(defaultStream::error_stream(),
-                "Invalid InitialCodeCacheSize=%dK. Must be at least %dK.\n", InitialCodeCacheSize/K,
-                os::vm_page_size()/K);
-    status = false;
-  } else if (ReservedCodeCacheSize < InitialCodeCacheSize) {
+  if (ReservedCodeCacheSize < InitialCodeCacheSize) {
     jio_fprintf(defaultStream::error_stream(),
                 "Invalid ReservedCodeCacheSize: %dK. Must be at least InitialCodeCacheSize=%dK.\n",
                 ReservedCodeCacheSize/K, InitialCodeCacheSize/K);
@@ -2212,7 +2326,27 @@
     }
     FLAG_SET_CMDLINE(bool, PostLoopMultiversioning, false);
   }
+  if (UseCountedLoopSafepoints && LoopStripMiningIter == 0) {
+    if (!FLAG_IS_DEFAULT(UseCountedLoopSafepoints) || !FLAG_IS_DEFAULT(LoopStripMiningIter)) {
+      warning("When counted loop safepoints are enabled, LoopStripMiningIter must be at least 1 (a safepoint every 1 iteration): setting it to 1");
+    }
+    LoopStripMiningIter = 1;
+  } else if (!UseCountedLoopSafepoints && LoopStripMiningIter > 0) {
+    if (!FLAG_IS_DEFAULT(UseCountedLoopSafepoints) || !FLAG_IS_DEFAULT(LoopStripMiningIter)) {
+      warning("Disabling counted safepoints implies no loop strip mining: setting LoopStripMiningIter to 0");
+    }
+    LoopStripMiningIter = 0;
+  }
+  if (FLAG_IS_DEFAULT(LoopStripMiningIterShortLoop)) {
+    // blind guess
+    LoopStripMiningIterShortLoop = LoopStripMiningIter / 10;
+  }
 #endif
+  if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
+    if ((UseNUMAInterleaving && !FLAG_IS_DEFAULT(UseNUMAInterleaving)) || (UseNUMA && !FLAG_IS_DEFAULT(UseNUMA))) {
+      log_warning(arguments) ("NUMA support for Heap depends on the file system when AllocateHeapAt option is used.\n");
+    }
+  }
   return status;
 }
 
@@ -2770,18 +2904,6 @@
       if (FLAG_SET_CMDLINE(intx, ThreadStackSize, value) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
-    } else if (match_option(option, "-XX:CodeCacheExpansionSize=", &tail)) {
-      julong long_CodeCacheExpansionSize = 0;
-      ArgsRange errcode = parse_memory_size(tail, &long_CodeCacheExpansionSize, os::vm_page_size());
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                   "Invalid argument: %s. Must be at least %luK.\n", option->optionString,
-                   os::vm_page_size()/K);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, CodeCacheExpansionSize, (uintx)long_CodeCacheExpansionSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
     } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
                match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
       julong long_ReservedCodeCacheSize = 0;
@@ -2795,45 +2917,6 @@
       if (FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
-      // -XX:NonNMethodCodeHeapSize=
-    } else if (match_option(option, "-XX:NonNMethodCodeHeapSize=", &tail)) {
-      julong long_NonNMethodCodeHeapSize = 0;
-
-      ArgsRange errcode = parse_memory_size(tail, &long_NonNMethodCodeHeapSize, 1);
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum non-nmethod code heap size: %s.\n", option->optionString);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, NonNMethodCodeHeapSize, (uintx)long_NonNMethodCodeHeapSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
-      // -XX:ProfiledCodeHeapSize=
-    } else if (match_option(option, "-XX:ProfiledCodeHeapSize=", &tail)) {
-      julong long_ProfiledCodeHeapSize = 0;
-
-      ArgsRange errcode = parse_memory_size(tail, &long_ProfiledCodeHeapSize, 1);
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum profiled code heap size: %s.\n", option->optionString);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, ProfiledCodeHeapSize, (uintx)long_ProfiledCodeHeapSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
-      // -XX:NonProfiledCodeHeapSizee=
-    } else if (match_option(option, "-XX:NonProfiledCodeHeapSize=", &tail)) {
-      julong long_NonProfiledCodeHeapSize = 0;
-
-      ArgsRange errcode = parse_memory_size(tail, &long_NonProfiledCodeHeapSize, 1);
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum non-profiled code heap size: %s.\n", option->optionString);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, NonProfiledCodeHeapSize, (uintx)long_NonProfiledCodeHeapSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
     // -green
     } else if (match_option(option, "-green")) {
       jio_fprintf(defaultStream::error_stream(),
@@ -3936,6 +4019,14 @@
       vm_exit(0);
     }
 #endif
+
+    if (match_option(option, "-XX:+UseAppCDS")) {
+      Flag* flag = Flag::find_flag("SharedArchiveFile", 17, true, true);
+      if (flag->is_diagnostic()) {
+        flag->clear_diagnostic();
+      }
+      continue;
+    }
   }
   return JNI_OK;
 }
@@ -4306,26 +4397,7 @@
   }
 #endif
 
-  bool aot_enabled = UseAOT && AOTLibrary != NULL;
-  bool jvmci_enabled = NOT_JVMCI(false) JVMCI_ONLY(EnableJVMCI || UseJVMCICompiler);
-  bool handshakes_supported = SafepointMechanism::supports_thread_local_poll() && !aot_enabled && !jvmci_enabled && ThreadLocalHandshakes;
   // ThreadLocalHandshakesConstraintFunc handles the constraints.
-  // Here we try to figure out if a mutual exclusive option have been set that conflict with a default.
-  if (handshakes_supported) {
-    FLAG_SET_DEFAULT(UseAOT, false); // Clear the AOT flag to make sure it doesn't try to initialize.
-  } else {
-    if (FLAG_IS_DEFAULT(ThreadLocalHandshakes) && ThreadLocalHandshakes) {
-      if (aot_enabled) {
-        // If user enabled AOT but ThreadLocalHandshakes is at default set it to false.
-        log_debug(ergo)("Disabling ThreadLocalHandshakes for UseAOT.");
-        FLAG_SET_DEFAULT(ThreadLocalHandshakes, false);
-      } else if (jvmci_enabled){
-        // If user enabled JVMCI but ThreadLocalHandshakes is at default set it to false.
-        log_debug(ergo)("Disabling ThreadLocalHandshakes for EnableJVMCI/UseJVMCICompiler.");
-        FLAG_SET_DEFAULT(ThreadLocalHandshakes, false);
-      }
-    }
-  }
   if (FLAG_IS_DEFAULT(ThreadLocalHandshakes) || !SafepointMechanism::supports_thread_local_poll()) {
     log_debug(ergo)("ThreadLocalHandshakes %s", ThreadLocalHandshakes ? "enabled." : "disabled.");
   } else {
@@ -4337,7 +4409,9 @@
 
 jint Arguments::adjust_after_os() {
   if (UseNUMA) {
-    if (UseParallelGC || UseParallelOldGC) {
+    if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
+      FLAG_SET_ERGO(bool, UseNUMA, false);
+    } else if (UseParallelGC || UseParallelOldGC) {
       if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
          FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
       }
--- a/src/hotspot/share/runtime/arguments.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/arguments.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 
 #include "logging/logLevel.hpp"
 #include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/perfData.hpp"
@@ -59,60 +60,11 @@
  public:
   char* value() const { return _value; }
 
-  bool set_value(const char *value) {
-    if (_value != NULL) {
-      FreeHeap(_value);
-    }
-    _value = AllocateHeap(strlen(value)+1, mtArguments);
-    assert(_value != NULL, "Unable to allocate space for new path value");
-    if (_value != NULL) {
-      strcpy(_value, value);
-    } else {
-      // not able to allocate
-      return false;
-    }
-    return true;
-  }
+  bool set_value(const char *value);
+  void append_value(const char *value);
 
-  void append_value(const char *value) {
-    char *sp;
-    size_t len = 0;
-    if (value != NULL) {
-      len = strlen(value);
-      if (_value != NULL) {
-        len += strlen(_value);
-      }
-      sp = AllocateHeap(len+2, mtArguments);
-      assert(sp != NULL, "Unable to allocate space for new append path value");
-      if (sp != NULL) {
-        if (_value != NULL) {
-          strcpy(sp, _value);
-          strcat(sp, os::path_separator());
-          strcat(sp, value);
-          FreeHeap(_value);
-        } else {
-          strcpy(sp, value);
-        }
-        _value = sp;
-      }
-    }
-  }
-
-  PathString(const char* value) {
-    if (value == NULL) {
-      _value = NULL;
-    } else {
-      _value = AllocateHeap(strlen(value)+1, mtArguments);
-      strcpy(_value, value);
-    }
-  }
-
-  ~PathString() {
-    if (_value != NULL) {
-      FreeHeap(_value);
-      _value = NULL;
-    }
-  }
+  PathString(const char* value);
+  ~PathString();
 };
 
 // ModulePatchPath records the module/path pair as specified to --patch-module.
@@ -121,24 +73,8 @@
   char* _module_name;
   PathString* _path;
 public:
-  ModulePatchPath(const char* module_name, const char* path) {
-    assert(module_name != NULL && path != NULL, "Invalid module name or path value");
-    size_t len = strlen(module_name) + 1;
-    _module_name = AllocateHeap(len, mtInternal);
-    strncpy(_module_name, module_name, len); // copy the trailing null
-    _path =  new PathString(path);
-  }
-
-  ~ModulePatchPath() {
-    if (_module_name != NULL) {
-      FreeHeap(_module_name);
-      _module_name = NULL;
-    }
-    if (_path != NULL) {
-      delete _path;
-      _path = NULL;
-    }
-  }
+  ModulePatchPath(const char* module_name, const char* path);
+  ~ModulePatchPath();
 
   inline void set_path(const char* path) { _path->set_value(path); }
   inline const char* module_name() const { return _module_name; }
@@ -185,17 +121,7 @@
   }
 
   // Constructor
-  SystemProperty(const char* key, const char* value, bool writeable, bool internal = false) : PathString(value) {
-    if (key == NULL) {
-      _key = NULL;
-    } else {
-      _key = AllocateHeap(strlen(key)+1, mtArguments);
-      strcpy(_key, key);
-    }
-    _next = NULL;
-    _internal = internal;
-    _writeable = writeable;
-  }
+  SystemProperty(const char* key, const char* value, bool writeable, bool internal = false);
 };
 
 
@@ -234,21 +160,7 @@
   void set_invalid()                        { _state = agent_invalid; }
 
   // Constructor
-  AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
-    _name = AllocateHeap(strlen(name)+1, mtArguments);
-    strcpy(_name, name);
-    if (options == NULL) {
-      _options = NULL;
-    } else {
-      _options = AllocateHeap(strlen(options)+1, mtArguments);
-      strcpy(_options, options);
-    }
-    _is_absolute_path = is_absolute_path;
-    _os_lib = os_lib;
-    _next = NULL;
-    _state = agent_invalid;
-    _is_static_lib = false;
-  }
+  AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib);
 };
 
 // maintain an order of entry list of AgentLibrary
@@ -420,19 +332,15 @@
 
   // -Xrun arguments
   static AgentLibraryList _libraryList;
-  static void add_init_library(const char* name, char* options)
-    { _libraryList.add(new AgentLibrary(name, options, false, NULL)); }
+  static void add_init_library(const char* name, char* options);
 
   // -agentlib and -agentpath arguments
   static AgentLibraryList _agentList;
-  static void add_init_agent(const char* name, char* options, bool absolute_path)
-    { _agentList.add(new AgentLibrary(name, options, absolute_path, NULL)); }
+  static void add_init_agent(const char* name, char* options, bool absolute_path);
 
   // Late-binding agents not started via arguments
-  static void add_loaded_agent(AgentLibrary *agentLib)
-    { _agentList.add(agentLib); }
-  static void add_loaded_agent(const char* name, char* options, bool absolute_path, void* os_lib)
-    { _agentList.add(new AgentLibrary(name, options, absolute_path, os_lib)); }
+  static void add_loaded_agent(AgentLibrary *agentLib);
+  static void add_loaded_agent(const char* name, char* options, bool absolute_path, void* os_lib);
 
   // Operation modi
   static Mode _mode;
--- a/src/hotspot/share/runtime/arguments_ext.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/arguments_ext.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -36,7 +36,6 @@
   // Otherwise returns false.
   static inline bool process_options(const JavaVMOption *option) { return false; }
   static inline void report_unsupported_options() { }
-  static inline bool using_AppCDS() { return false; }
 };
 
 void ArgumentsExt::set_gc_specific_flags() {
--- a/src/hotspot/share/runtime/biasedLocking.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/biasedLocking.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/task.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
@@ -214,12 +215,8 @@
   if (requesting_thread == biased_thread) {
     thread_is_alive = true;
   } else {
-    for (JavaThread* cur_thread = Threads::first(); cur_thread != NULL; cur_thread = cur_thread->next()) {
-      if (cur_thread == biased_thread) {
-        thread_is_alive = true;
-        break;
-      }
-    }
+    ThreadsListHandle tlh;
+    thread_is_alive = tlh.includes(biased_thread);
   }
   if (!thread_is_alive) {
     if (allow_rebias) {
@@ -390,72 +387,76 @@
   Klass* k_o = o->klass();
   Klass* klass = k_o;
 
-  if (bulk_rebias) {
-    // Use the epoch in the klass of the object to implicitly revoke
-    // all biases of objects of this data type and force them to be
-    // reacquired. However, we also need to walk the stacks of all
-    // threads and update the headers of lightweight locked objects
-    // with biases to have the current epoch.
+  {
+    JavaThreadIteratorWithHandle jtiwh;
+
+    if (bulk_rebias) {
+      // Use the epoch in the klass of the object to implicitly revoke
+      // all biases of objects of this data type and force them to be
+      // reacquired. However, we also need to walk the stacks of all
+      // threads and update the headers of lightweight locked objects
+      // with biases to have the current epoch.
+
+      // If the prototype header doesn't have the bias pattern, don't
+      // try to update the epoch -- assume another VM operation came in
+      // and reset the header to the unbiased state, which will
+      // implicitly cause all existing biases to be revoked
+      if (klass->prototype_header()->has_bias_pattern()) {
+        int prev_epoch = klass->prototype_header()->bias_epoch();
+        klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch());
+        int cur_epoch = klass->prototype_header()->bias_epoch();
 
-    // If the prototype header doesn't have the bias pattern, don't
-    // try to update the epoch -- assume another VM operation came in
-    // and reset the header to the unbiased state, which will
-    // implicitly cause all existing biases to be revoked
-    if (klass->prototype_header()->has_bias_pattern()) {
-      int prev_epoch = klass->prototype_header()->bias_epoch();
-      klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch());
-      int cur_epoch = klass->prototype_header()->bias_epoch();
+        // Now walk all threads' stacks and adjust epochs of any biased
+        // and locked objects of this data type we encounter
+        for (; JavaThread *thr = jtiwh.next(); ) {
+          GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
+          for (int i = 0; i < cached_monitor_info->length(); i++) {
+            MonitorInfo* mon_info = cached_monitor_info->at(i);
+            oop owner = mon_info->owner();
+            markOop mark = owner->mark();
+            if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
+              // We might have encountered this object already in the case of recursive locking
+              assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
+              owner->set_mark(mark->set_bias_epoch(cur_epoch));
+            }
+          }
+        }
+      }
 
-      // Now walk all threads' stacks and adjust epochs of any biased
-      // and locked objects of this data type we encounter
-      for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
+      // At this point we're done. All we have to do is potentially
+      // adjust the header of the given object to revoke its bias.
+      revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
+    } else {
+      if (log_is_enabled(Info, biasedlocking)) {
+        ResourceMark rm;
+        log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
+      }
+
+      // Disable biased locking for this data type. Not only will this
+      // cause future instances to not be biased, but existing biased
+      // instances will notice that this implicitly caused their biases
+      // to be revoked.
+      klass->set_prototype_header(markOopDesc::prototype());
+
+      // Now walk all threads' stacks and forcibly revoke the biases of
+      // any locked and biased objects of this data type we encounter.
+      for (; JavaThread *thr = jtiwh.next(); ) {
         GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
         for (int i = 0; i < cached_monitor_info->length(); i++) {
           MonitorInfo* mon_info = cached_monitor_info->at(i);
           oop owner = mon_info->owner();
           markOop mark = owner->mark();
           if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
-            // We might have encountered this object already in the case of recursive locking
-            assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
-            owner->set_mark(mark->set_bias_epoch(cur_epoch));
+            revoke_bias(owner, false, true, requesting_thread, NULL);
           }
         }
       }
-    }
 
-    // At this point we're done. All we have to do is potentially
-    // adjust the header of the given object to revoke its bias.
-    revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
-  } else {
-    if (log_is_enabled(Info, biasedlocking)) {
-      ResourceMark rm;
-      log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
+      // Must force the bias of the passed object to be forcibly revoked
+      // as well to ensure guarantees to callers
+      revoke_bias(o, false, true, requesting_thread, NULL);
     }
-
-    // Disable biased locking for this data type. Not only will this
-    // cause future instances to not be biased, but existing biased
-    // instances will notice that this implicitly caused their biases
-    // to be revoked.
-    klass->set_prototype_header(markOopDesc::prototype());
-
-    // Now walk all threads' stacks and forcibly revoke the biases of
-    // any locked and biased objects of this data type we encounter.
-    for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
-      GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
-      for (int i = 0; i < cached_monitor_info->length(); i++) {
-        MonitorInfo* mon_info = cached_monitor_info->at(i);
-        oop owner = mon_info->owner();
-        markOop mark = owner->mark();
-        if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
-          revoke_bias(owner, false, true, requesting_thread, NULL);
-        }
-      }
-    }
-
-    // Must force the bias of the passed object to be forcibly revoked
-    // as well to ensure guarantees to callers
-    revoke_bias(o, false, true, requesting_thread, NULL);
-  }
+  } // ThreadsListHandle is destroyed here.
 
   log_info(biasedlocking)("* Ending bulk revocation");
 
@@ -481,7 +482,7 @@
 
 static void clean_up_cached_monitor_info() {
   // Walk the thread list clearing out the cached monitors
-  for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
     thr->set_cached_monitor_info(NULL);
   }
 }
@@ -768,7 +769,7 @@
 
   ResourceMark rm;
   Thread* cur = Thread::current();
-  for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     if (thread->has_last_Java_frame()) {
       RegisterMap rm(thread);
       for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) {
--- a/src/hotspot/share/runtime/commandLineFlagConstraintsRuntime.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/commandLineFlagConstraintsRuntime.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -138,10 +138,6 @@
       CommandLineError::print(verbose, "ThreadLocalHandshakes not yet supported on this platform\n");
       return Flag::VIOLATES_CONSTRAINT;
     }
-    if (UseAOT JVMCI_ONLY(|| EnableJVMCI || UseJVMCICompiler)) {
-      CommandLineError::print(verbose, "ThreadLocalHandshakes not yet supported in combination with AOT or JVMCI\n");
-      return Flag::VIOLATES_CONSTRAINT;
-    }
   }
   return Flag::SUCCESS;
 }
--- a/src/hotspot/share/runtime/deoptimization.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -50,6 +50,7 @@
 #include "runtime/signature.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
 #include "runtime/vframe_hp.hpp"
@@ -1297,7 +1298,7 @@
 
   assert(SafepointSynchronize::is_at_safepoint(), "must only be called from safepoint");
   GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-  for (JavaThread* jt = Threads::first(); jt != NULL ; jt = jt->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
     if (jt->has_last_Java_frame()) {
       StackFrameStream sfs(jt, true);
       while (!sfs.is_done()) {
--- a/src/hotspot/share/runtime/globals.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/globals.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -917,9 +917,6 @@
   notproduct(bool, ZapVMHandleArea, trueInDebug,                            \
           "Zap freed VM handle space with 0xBCBCBCBC")                      \
                                                                             \
-  develop(bool, ZapJNIHandleArea, trueInDebug,                              \
-          "Zap freed JNI handle space with 0xFEFEFEFE")                     \
-                                                                            \
   notproduct(bool, ZapStackSegments, trueInDebug,                           \
           "Zap allocated/freed stack segments with 0xFADFADED")             \
                                                                             \
@@ -2271,6 +2268,10 @@
   diagnostic(bool, VerifyDuringGC, false,                                   \
           "Verify memory system during GC (between phases)")                \
                                                                             \
+  diagnostic(ccstrlist, VerifyGCType, "",                                   \
+             "GC type(s) to verify when Verify*GC is enabled."              \
+             "Available types are collector specific.")                     \
+                                                                            \
   diagnostic(ccstrlist, VerifySubSet, "",                                   \
           "Memory sub-systems to verify when Verify*GC flag(s) "            \
           "are enabled. One or more sub-systems can be specified "          \
@@ -2484,6 +2485,12 @@
   LP64_ONLY(range(-1, max_intx/MICROUNITS))                                 \
   NOT_LP64(range(-1, max_intx))                                             \
                                                                             \
+  diagnostic(bool, EnableThreadSMRExtraValidityChecks, true,                \
+             "Enable Thread SMR extra validity checks")                     \
+                                                                            \
+  diagnostic(bool, EnableThreadSMRStatistics, trueInDebug,                  \
+             "Enable Thread SMR Statistics")                                \
+                                                                            \
   product(bool, Inline, true,                                               \
           "Enable inlining")                                                \
                                                                             \
@@ -3359,7 +3366,7 @@
                                                                             \
   product_pd(uintx, InitialCodeCacheSize,                                   \
           "Initial code cache size (in bytes)")                             \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   develop_pd(uintx, CodeCacheMinimumUseSpace,                               \
           "Minimum code cache size (in bytes) required to start VM.")       \
@@ -3370,7 +3377,7 @@
                                                                             \
   product_pd(uintx, ReservedCodeCacheSize,                                  \
           "Reserved code cache size (in bytes) - maximum code cache size")  \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   product_pd(uintx, NonProfiledCodeHeapSize,                                \
           "Size of code heap with non-profiled methods (in bytes)")         \
@@ -3382,11 +3389,11 @@
                                                                             \
   product_pd(uintx, NonNMethodCodeHeapSize,                                 \
           "Size of code heap with non-nmethods (in bytes)")                 \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   product_pd(uintx, CodeCacheExpansionSize,                                 \
           "Code cache expansion size (in bytes)")                           \
-          range(0, max_uintx)                                               \
+          range(32*K, max_uintx)                                            \
                                                                             \
   diagnostic_pd(uintx, CodeCacheMinBlockLength,                             \
           "Minimum number of segments in a code cache block")               \
@@ -3926,6 +3933,13 @@
           "Address to allocate shared memory region for class data")        \
           range(0, SIZE_MAX)                                                \
                                                                             \
+  product(bool, UseAppCDS, false,                                           \
+          "Enable Application Class Data Sharing when using shared spaces") \
+          writeable(CommandLineOnly)                                        \
+                                                                            \
+  product(ccstr, SharedArchiveConfigFile, NULL,                             \
+          "Data to add to the CDS archive file")                            \
+                                                                            \
   product(uintx, SharedSymbolTableBucketSize, 4,                            \
           "Average number of symbols per bucket in shared table")           \
           range(2, 246)                                                     \
@@ -4073,7 +4087,11 @@
   diagnostic(bool, CompilerDirectivesPrint, false,                          \
              "Print compiler directives on installation.")                  \
   diagnostic(int,  CompilerDirectivesLimit, 50,                             \
-             "Limit on number of compiler directives.")
+             "Limit on number of compiler directives.")                     \
+                                                                            \
+  product(ccstr, AllocateHeapAt, NULL,                                      \
+          "Path to the directoy where a temporary file will be created "    \
+          "to use as the backing store for Java Heap.")
 
 
 /*
--- a/src/hotspot/share/runtime/handshake.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/handshake.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -37,8 +37,6 @@
 #include "utilities/formatBuffer.hpp"
 #include "utilities/preserveException.hpp"
 
-#define ALL_JAVA_THREADS(X) for (JavaThread* X = Threads::first(); X; X = X->next())
-
 class HandshakeOperation: public StackObj {
 public:
   virtual void do_handshake(JavaThread* thread) = 0;
@@ -94,8 +92,7 @@
 
 void VM_Handshake::handle_timeout() {
   LogStreamHandle(Warning, handshake) log_stream;
-  MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-  ALL_JAVA_THREADS(thr) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
     if (thr->has_handshake()) {
       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
       thr->print_thread_state_on(&log_stream);
@@ -117,8 +114,8 @@
     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 
     {
-      MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-      if (Threads::includes(_target)) {
+      ThreadsListHandle tlh;
+      if (tlh.includes(_target)) {
         set_handshake(_target);
         _thread_alive = true;
       }
@@ -139,9 +136,24 @@
         handle_timeout();
       }
 
+      // We need to re-think this with SMR ThreadsList.
+      // There is an assumption in the code that the Threads_lock should be
+      // locked during certain phases.
       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-      _target->handshake_process_by_vmthread();
-
+      ThreadsListHandle tlh;
+      if (tlh.includes(_target)) {
+        // Warning _target's address might be re-used.
+        // handshake_process_by_vmthread will check the semaphore for us again.
+        // Since we can't have more then one handshake in flight a reuse of
+        // _target's address should be okay since the new thread will not have
+        // an operation.
+        _target->handshake_process_by_vmthread();
+      } else {
+        // We can't warn here since the thread does cancel_handshake after
+        // it has been removed from the ThreadsList. So we should just keep
+        // looping here until while below returns false. If we have a bug,
+        // then we hang here, which is good for debugging.
+      }
     } while (!poll_for_completed_thread());
   }
 
@@ -157,15 +169,15 @@
   void doit() {
     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 
-    int number_of_threads_issued = -1;
-    int number_of_threads_completed = 0;
-    {
-      MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-      number_of_threads_issued = Threads::number_of_threads();
+    int number_of_threads_issued = 0;
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+      set_handshake(thr);
+      number_of_threads_issued++;
+    }
 
-      ALL_JAVA_THREADS(thr) {
-        set_handshake(thr);
-      }
+    if (number_of_threads_issued < 1) {
+      log_debug(handshake)("No threads to handshake.");
+      return;
     }
 
     if (!UseMembar) {
@@ -174,6 +186,7 @@
 
     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
     const jlong start_time = os::elapsed_counter();
+    int number_of_threads_completed = 0;
     do {
       // Check if handshake operation has timed out
       if (handshake_has_timed_out(start_time)) {
@@ -184,13 +197,19 @@
       // Observing a blocked state may of course be transient but the processing is guarded
       // by semaphores and we optimistically begin by working on the blocked threads
       {
+          // We need to re-think this with SMR ThreadsList.
+          // There is an assumption in the code that the Threads_lock should
+          // be locked during certain phases.
           MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-          ALL_JAVA_THREADS(thr) {
+          for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+            // A new thread on the ThreadsList will not have an operation,
+            // hence it is skipped in handshake_process_by_vmthread.
             thr->handshake_process_by_vmthread();
           }
       }
 
       while (poll_for_completed_thread()) {
+        // Includes canceled operations by exiting threads.
         number_of_threads_completed++;
       }
 
@@ -212,7 +231,7 @@
       _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
 
   void doit() {
-    ALL_JAVA_THREADS(t) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
       if (_all_threads || t == _target_thread) {
         if (t == _target_thread) {
           _thread_alive = true;
@@ -298,8 +317,8 @@
   assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
 #ifdef DEBUG
   {
-    MutexLockerEx ml(Threads_lock,  Mutex::_no_safepoint_check_flag);
-    assert(!Threads::includes(thread), "java thread must not be on threads list");
+    ThreadsListHandle tlh;
+    assert(!tlh.includes(_target), "java thread must not be on threads list");
   }
 #endif
   HandshakeOperation* op = _operation;
--- a/src/hotspot/share/runtime/java.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/java.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -356,6 +356,8 @@
   if (PrintNMTStatistics) {
     MemTracker::final_report(tty);
   }
+
+  Threads::log_smr_statistics();
 }
 
 #else // PRODUCT MODE STATISTICS
@@ -396,6 +398,8 @@
   if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
     Method::print_touched_methods(tty);
   }
+
+  Threads::log_smr_statistics();
 }
 
 #endif
--- a/src/hotspot/share/runtime/jniHandles.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/jniHandles.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -279,13 +279,15 @@
 #endif
 
 
+#ifdef ASSERT
 void JNIHandleBlock::zap() {
   // Zap block values
   _top = 0;
   for (int index = 0; index < block_size_in_oops; index++) {
-    _handles[index] = badJNIHandle;
+    _handles[index] = NULL;
   }
 }
+#endif // ASSERT
 
 JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread)  {
   assert(thread == NULL || thread == Thread::current(), "sanity check");
@@ -307,7 +309,7 @@
       // Allocate new block
       block = new JNIHandleBlock();
       _blocks_allocated++;
-      if (ZapJNIHandleArea) block->zap();
+      block->zap();
       #ifndef PRODUCT
       // Link new block to list of all allocated blocks
       block->_block_list_link = _block_list;
@@ -339,7 +341,7 @@
   // we _don't_ want the block to be kept on the free_handle_block.
   // See for instance JavaThread::exit().
   if (thread != NULL ) {
-    if (ZapJNIHandleArea) block->zap();
+    block->zap();
     JNIHandleBlock* freelist = thread->free_handle_block();
     block->_pop_frame_link = NULL;
     thread->set_free_handle_block(block);
@@ -360,7 +362,7 @@
     MutexLockerEx ml(JNIHandleBlockFreeList_lock,
                      Mutex::_no_safepoint_check_flag);
     while (block != NULL) {
-      if (ZapJNIHandleArea) block->zap();
+      block->zap();
       JNIHandleBlock* next = block->_next;
       block->_next = _block_free_list;
       _block_free_list = block;
@@ -453,13 +455,13 @@
         break;
       }
       current->_top = 0;
-      if (ZapJNIHandleArea) current->zap();
+      current->zap();
     }
     // Clear initial block
     _free_list = NULL;
     _allocate_before_rebuild = 0;
     _last = this;
-    if (ZapJNIHandleArea) zap();
+    zap();
   }
 
   // Try last block
--- a/src/hotspot/share/runtime/jniHandles.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/jniHandles.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -148,7 +148,7 @@
   static int      _blocks_allocated;            // For debugging/printing
 
   // Fill block with bad_handle values
-  void zap();
+  void zap() NOT_DEBUG_RETURN;
 
   // Free list computation
   void rebuild_free_list();
@@ -219,9 +219,8 @@
 template<bool external_guard>
 inline oop JNIHandles::guard_value(oop value) {
   if (!external_guard) {
-    assert(value != badJNIHandle, "Pointing to zapped jni handle area");
     assert(value != deleted_handle(), "Used a deleted global handle");
-  } else if ((value == badJNIHandle) || (value == deleted_handle())) {
+  } else if (value == deleted_handle()) {
     value = NULL;
   }
   return value;
--- a/src/hotspot/share/runtime/memprofiler.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/memprofiler.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 #include "runtime/os.hpp"
 #include "runtime/task.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 
 #ifndef PRODUCT
@@ -51,8 +52,6 @@
 
 
 void MemProfilerTask::task() {
-  // Get thread lock to provide mutual exclusion, and so we can iterate safely over the thread list.
-  MutexLocker mu(Threads_lock);
   MemProfiler::do_trace();
 }
 
@@ -109,20 +108,21 @@
   // Calculate thread local sizes
   size_t handles_memory_usage    = VMThread::vm_thread()->handle_area()->size_in_bytes();
   size_t resource_memory_usage   = VMThread::vm_thread()->resource_area()->size_in_bytes();
-  JavaThread *cur = Threads::first();
-  while (cur != NULL) {
-    handles_memory_usage  += cur->handle_area()->size_in_bytes();
-    resource_memory_usage += cur->resource_area()->size_in_bytes();
-    cur = cur->next();
-  }
+  {
+    JavaThreadIteratorWithHandle jtiwh;
+    for (; JavaThread *cur = jtiwh.next(); ) {
+      handles_memory_usage  += cur->handle_area()->size_in_bytes();
+      resource_memory_usage += cur->resource_area()->size_in_bytes();
+    }
 
-  // Print trace line in log
-  fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
-          os::elapsedTime(),
-          Threads::number_of_threads(),
-          InstanceKlass::number_of_instance_classes(),
-          Universe::heap()->used() / K,
-          Universe::heap()->capacity() / K);
+    // Print trace line in log
+    fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
+            os::elapsedTime(),
+            jtiwh.length(),
+            InstanceKlass::number_of_instance_classes(),
+            Universe::heap()->used() / K,
+            Universe::heap()->capacity() / K);
+  }
 
   fprintf(_log_fp, UINTX_FORMAT_W(6) ",", CodeCache::capacity() / K);
 
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -242,6 +243,19 @@
 // * See also http://blogs.sun.com/dave
 
 
+void* ObjectMonitor::operator new (size_t size) throw() {
+  return AllocateHeap(size, mtInternal);
+}
+void* ObjectMonitor::operator new[] (size_t size) throw() {
+  return operator new (size);
+}
+void ObjectMonitor::operator delete(void* p) {
+  FreeHeap(p);
+}
+void ObjectMonitor::operator delete[] (void *p) {
+  operator delete(p);
+}
+
 // -----------------------------------------------------------------------------
 // Enter support
 
@@ -2138,6 +2152,7 @@
   _next     = NULL;
   _prev     = NULL;
   _notified = 0;
+  _notifier_tid = 0;
   TState    = TS_RUN;
   _thread   = thread;
   _event    = thread->_ParkEvent;
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
 #define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
 
+#include "memory/allocation.hpp"
 #include "memory/padded.hpp"
 #include "runtime/os.hpp"
 #include "runtime/park.hpp"
@@ -212,18 +213,10 @@
   static int Knob_VerifyMatch;
   static int Knob_SpinLimit;
 
-  void* operator new (size_t size) throw() {
-    return AllocateHeap(size, mtInternal);
-  }
-  void* operator new[] (size_t size) throw() {
-    return operator new (size);
-  }
-  void operator delete(void* p) {
-    FreeHeap(p);
-  }
-  void operator delete[] (void *p) {
-    operator delete(p);
-  }
+  void* operator new (size_t size) throw();
+  void* operator new[] (size_t size) throw();
+  void operator delete(void* p);
+  void operator delete[] (void *p);
 
   // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
   // ByteSize would also be an appropriate type.
--- a/src/hotspot/share/runtime/os.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/os.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -54,6 +54,7 @@
 #include "runtime/os.inline.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/attachListener.hpp"
 #include "services/mallocTracker.hpp"
@@ -197,15 +198,7 @@
 }
 
 OSReturn os::set_priority(Thread* thread, ThreadPriority p) {
-#ifdef ASSERT
-  if (!(!thread->is_Java_thread() ||
-         Thread::current() == thread  ||
-         Threads_lock->owned_by_self()
-         || thread->is_Compiler_thread()
-        )) {
-    assert(false, "possibility of dangling Thread pointer");
-  }
-#endif
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   if (p >= MinPriority && p <= MaxPriority) {
     int priority = java_to_os_priority[p];
@@ -1100,7 +1093,7 @@
   }
 #endif
 
-  for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     // Check for privilege stack
     if (thread->privileged_stack_top() != NULL &&
         thread->privileged_stack_top()->contains(addr)) {
@@ -1126,7 +1119,6 @@
       if (verbose) thread->print_on(st);
       return;
     }
-
   }
 
   // Check if in metaspace and print types that have vptrs (only method now)
@@ -1665,7 +1657,6 @@
 }
 
 void os::SuspendedThreadTask::run() {
-  assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
   internal_do_task();
   _done = true;
 }
@@ -1674,10 +1665,21 @@
   return os::pd_create_stack_guard_pages(addr, bytes);
 }
 
-char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
-  char* result = pd_reserve_memory(bytes, addr, alignment_hint);
-  if (result != NULL) {
-    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint, int file_desc) {
+  char* result = NULL;
+
+  if (file_desc != -1) {
+    // Could have called pd_reserve_memory() followed by replace_existing_mapping_with_file_mapping(),
+    // but AIX may use SHM in which case its more trouble to detach the segment and remap memory to the file.
+    result = os::map_memory_to_file(addr, bytes, file_desc);
+    if (result != NULL) {
+      MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
+    }
+  } else {
+    result = pd_reserve_memory(bytes, addr, alignment_hint);
+    if (result != NULL) {
+      MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+    }
   }
 
   return result;
@@ -1694,10 +1696,18 @@
   return result;
 }
 
-char* os::attempt_reserve_memory_at(size_t bytes, char* addr) {
-  char* result = pd_attempt_reserve_memory_at(bytes, addr);
-  if (result != NULL) {
-    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+char* os::attempt_reserve_memory_at(size_t bytes, char* addr, int file_desc) {
+  char* result = NULL;
+  if (file_desc != -1) {
+    result = pd_attempt_reserve_memory_at(bytes, addr, file_desc);
+    if (result != NULL) {
+      MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
+    }
+  } else {
+    result = pd_attempt_reserve_memory_at(bytes, addr);
+    if (result != NULL) {
+      MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
+    }
   }
   return result;
 }
--- a/src/hotspot/share/runtime/os.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/os.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -108,8 +108,9 @@
   }
 
   static char*  pd_reserve_memory(size_t bytes, char* addr = 0,
-                               size_t alignment_hint = 0);
+                                  size_t alignment_hint = 0);
   static char*  pd_attempt_reserve_memory_at(size_t bytes, char* addr);
+  static char*  pd_attempt_reserve_memory_at(size_t bytes, char* addr, int file_desc);
   static void   pd_split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc);
   static bool   pd_commit_memory(char* addr, size_t bytes, bool executable);
@@ -310,11 +311,11 @@
 
   static int    vm_allocation_granularity();
   static char*  reserve_memory(size_t bytes, char* addr = 0,
-                               size_t alignment_hint = 0);
+                               size_t alignment_hint = 0, int file_desc = -1);
   static char*  reserve_memory(size_t bytes, char* addr,
                                size_t alignment_hint, MEMFLAGS flags);
-  static char*  reserve_memory_aligned(size_t size, size_t alignment);
-  static char*  attempt_reserve_memory_at(size_t bytes, char* addr);
+  static char*  reserve_memory_aligned(size_t size, size_t alignment, int file_desc = -1);
+  static char*  attempt_reserve_memory_at(size_t bytes, char* addr, int file_desc = -1);
   static void   split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc);
   static bool   commit_memory(char* addr, size_t bytes, bool executable);
@@ -345,6 +346,14 @@
   static bool   create_stack_guard_pages(char* addr, size_t bytes);
   static bool   pd_create_stack_guard_pages(char* addr, size_t bytes);
   static bool   remove_stack_guard_pages(char* addr, size_t bytes);
+  // Helper function to create a new file with template jvmheap.XXXXXX.
+  // Returns a valid fd on success or else returns -1
+  static int create_file_for_heap(const char* dir);
+  // Map memory to the file referred by fd. This function is slightly different from map_memory()
+  // and is added to be used for implementation of -XX:AllocateHeapAt
+  static char* map_memory_to_file(char* base, size_t size, int fd);
+  // Replace existing reserved memory with file mapping
+  static char* replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd);
 
   static char*  map_memory(int fd, const char* file_name, size_t file_offset,
                            char *addr, size_t bytes, bool read_only = false,
--- a/src/hotspot/share/runtime/park.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/park.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,10 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/allocation.inline.hpp"
 #include "runtime/thread.hpp"
 
-
-
 // Lifecycle management for TSM ParkEvents.
 // ParkEvents are type-stable (TSM).
 // In our particular implementation they happen to be immortal.
--- a/src/hotspot/share/runtime/perfData.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/perfData.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,7 +32,7 @@
 #include "runtime/mutex.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
-#include "runtime/perfData.hpp"
+#include "runtime/perfData.inline.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -611,3 +611,10 @@
 
   return copy;
 }
+
+PerfTraceTime::~PerfTraceTime() {
+  if (!UsePerfData || (_recursion_counter != NULL &&
+      --(*_recursion_counter) > 0)) return;
+  _t.stop();
+  _timerp->inc(_t.ticks());
+}
--- a/src/hotspot/share/runtime/perfData.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/perfData.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,10 +25,11 @@
 #ifndef SHARE_VM_RUNTIME_PERFDATA_HPP
 #define SHARE_VM_RUNTIME_PERFDATA_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/perfMemory.hpp"
 #include "runtime/timer.hpp"
-#include "utilities/growableArray.hpp"
+
+template <typename T> class GrowableArray;
 
 /* jvmstat global and subsystem counter name space - enumeration value
  * serve as an index into the PerfDataManager::_name_space[] array
@@ -244,6 +245,7 @@
 
   friend class StatSampler;      // for access to protected void sample()
   friend class PerfDataManager;  // for access to protected destructor
+  friend class VMStructs;
 
   public:
 
@@ -629,10 +631,10 @@
     bool contains(const char* name) { return find_by_name(name) != NULL; }
 
     // return the number of PerfData items in this list
-    int length() { return _set->length(); }
+    inline int length();
 
     // add a PerfData item to this list
-    void append(PerfData *p) { _set->append(p); }
+    inline void append(PerfData *p);
 
     // remove the given PerfData item from this list. When called
     // while iterating over the list, this method will result in a
@@ -640,7 +642,7 @@
     // method is also impacted by this method as elements with an
     // index greater than the index of the element removed by this
     // method will be shifted down by one.
-    void remove(PerfData *p) { _set->remove(p); }
+    inline void remove(PerfData *p);
 
     // create a new PerfDataList from this list. The new list is
     // a shallow copy of the original list and care should be taken
@@ -651,7 +653,7 @@
     // for backward compatibility with GrowableArray - need to implement
     // some form of iterator to provide a cleaner abstraction for
     // iteration over the container.
-    PerfData* at(int index) { return _set->at(index); }
+    inline PerfData* at(int index);
 };
 
 
@@ -677,23 +679,23 @@
   protected:
     // return the list of all known PerfData items
     static PerfDataList* all();
-    static int count() { return _all->length(); }
+    static inline int count();
 
     // return the list of all known PerfData items that are to be
     // sampled by the StatSampler.
     static PerfDataList* sampled();
-    static int sampled_count() { return _sampled->length(); }
+    static inline int sampled_count();
 
     // return the list of all known PerfData items that have a
     // variability classification of type Constant
     static PerfDataList* constants();
-    static int constants_count() { return _constants->length(); }
+    static inline int constants_count();
 
   public:
 
     // method to check for the existence of a PerfData item with
     // the given name.
-    static bool exists(const char* name) { return _all->contains(name); }
+    static inline bool exists(const char* name);
 
     // method to search for a instrumentation object by name
     static PerfData* find_by_name(const char* name);
@@ -929,12 +931,7 @@
     inline void suspend() { if (!UsePerfData) return; _t.stop(); }
     inline void resume() { if (!UsePerfData) return; _t.start(); }
 
-    inline ~PerfTraceTime() {
-      if (!UsePerfData || (_recursion_counter != NULL &&
-                           --(*_recursion_counter) > 0)) return;
-      _t.stop();
-      _timerp->inc(_t.ticks());
-    }
+    ~PerfTraceTime();
 };
 
 /* The PerfTraceTimedEvent class is responsible for counting the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/perfData.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2002, 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_PERFDATA_INLINE_HPP
+#define SHARE_VM_RUNTIME_PERFDATA_INLINE_HPP
+
+#include "runtime/perfData.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
+
+inline int PerfDataList::length() {
+  return _set->length();
+}
+
+inline void PerfDataList::append(PerfData *p) {
+  _set->append(p);
+}
+
+inline void PerfDataList::remove(PerfData *p) {
+  _set->remove(p);
+}
+
+inline PerfData* PerfDataList::at(int index) {
+  return _set->at(index);
+}
+
+inline int PerfDataManager::count() {
+  return _all->length();
+}
+
+inline int PerfDataManager::sampled_count() {
+  return _sampled->length();
+}
+
+inline int PerfDataManager::constants_count() {
+  return _constants->length();
+}
+
+inline bool PerfDataManager::exists(const char* name) {
+  return _all->contains(name);
+}
+
+#endif // SHARE_VM_RUNTIME_PERFDATA_INLINE_HPP
--- a/src/hotspot/share/runtime/safepoint.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/safepoint.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -59,6 +59,7 @@
 #include "runtime/sweeper.hpp"
 #include "runtime/synchronizer.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timerTrace.hpp"
 #include "services/runtimeService.hpp"
 #include "trace/tracing.hpp"
@@ -174,7 +175,7 @@
     if (SafepointMechanism::uses_thread_local_poll()) {
       // Arming the per thread poll while having _state != _not_synchronized means safepointing
       log_trace(safepoint)("Setting thread local yield flag for threads");
-      for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
+      for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
         // Make sure the threads start polling, it is time to yield.
         SafepointMechanism::arm_local_poll(cur); // release store, global state -> local state
       }
@@ -200,133 +201,137 @@
 
     // Consider using active_processor_count() ... but that call is expensive.
     int ncpus = os::processor_count() ;
+    unsigned int iterations = 0;
 
+    {
+      JavaThreadIteratorWithHandle jtiwh;
 #ifdef ASSERT
-    for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
-      assert(cur->safepoint_state()->is_running(), "Illegal initial state");
-      // Clear the visited flag to ensure that the critical counts are collected properly.
-      cur->set_visited_for_critical_count(false);
-    }
+      for (; JavaThread *cur = jtiwh.next(); ) {
+        assert(cur->safepoint_state()->is_running(), "Illegal initial state");
+        // Clear the visited flag to ensure that the critical counts are collected properly.
+        cur->set_visited_for_critical_count(false);
+      }
 #endif // ASSERT
 
-    if (SafepointTimeout)
-      safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
+      if (SafepointTimeout)
+        safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
 
-    // Iterate through all threads until it have been determined how to stop them all at a safepoint
-    unsigned int iterations = 0;
-    int steps = 0 ;
-    while(still_running > 0) {
-      for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
-        assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
-        ThreadSafepointState *cur_state = cur->safepoint_state();
-        if (cur_state->is_running()) {
-          cur_state->examine_state_of_thread();
-          if (!cur_state->is_running()) {
-            still_running--;
-            // consider adjusting steps downward:
-            //   steps = 0
-            //   steps -= NNN
-            //   steps >>= 1
-            //   steps = MIN(steps, 2000-100)
-            //   if (iterations != 0) steps -= NNN
-          }
-          LogTarget(Trace, safepoint) lt;
-          if (lt.is_enabled()) {
-            ResourceMark rm;
-            LogStream ls(lt);
-            cur_state->print_on(&ls);
+      // Iterate through all threads until it have been determined how to stop them all at a safepoint
+      int steps = 0 ;
+      while(still_running > 0) {
+        jtiwh.rewind();
+        for (; JavaThread *cur = jtiwh.next(); ) {
+          assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
+          ThreadSafepointState *cur_state = cur->safepoint_state();
+          if (cur_state->is_running()) {
+            cur_state->examine_state_of_thread();
+            if (!cur_state->is_running()) {
+              still_running--;
+              // consider adjusting steps downward:
+              //   steps = 0
+              //   steps -= NNN
+              //   steps >>= 1
+              //   steps = MIN(steps, 2000-100)
+              //   if (iterations != 0) steps -= NNN
+            }
+            LogTarget(Trace, safepoint) lt;
+            if (lt.is_enabled()) {
+              ResourceMark rm;
+              LogStream ls(lt);
+              cur_state->print_on(&ls);
+            }
           }
         }
-      }
 
-      if (iterations == 0) {
-        initial_running = still_running;
-        if (PrintSafepointStatistics) {
-          begin_statistics(nof_threads, still_running);
-        }
-      }
-
-      if (still_running > 0) {
-        // Check for if it takes to long
-        if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
-          print_safepoint_timeout(_spinning_timeout);
+        if (iterations == 0) {
+          initial_running = still_running;
+          if (PrintSafepointStatistics) {
+            begin_statistics(nof_threads, still_running);
+          }
         }
 
-        // Spin to avoid context switching.
-        // There's a tension between allowing the mutators to run (and rendezvous)
-        // vs spinning.  As the VM thread spins, wasting cycles, it consumes CPU that
-        // a mutator might otherwise use profitably to reach a safepoint.  Excessive
-        // spinning by the VM thread on a saturated system can increase rendezvous latency.
-        // Blocking or yielding incur their own penalties in the form of context switching
-        // and the resultant loss of $ residency.
-        //
-        // Further complicating matters is that yield() does not work as naively expected
-        // on many platforms -- yield() does not guarantee that any other ready threads
-        // will run.   As such we revert to naked_short_sleep() after some number of iterations.
-        // nakes_short_sleep() is implemented as a short unconditional sleep.
-        // Typical operating systems round a "short" sleep period up to 10 msecs, so sleeping
-        // can actually increase the time it takes the VM thread to detect that a system-wide
-        // stop-the-world safepoint has been reached.  In a pathological scenario such as that
-        // described in CR6415670 the VMthread may sleep just before the mutator(s) become safe.
-        // In that case the mutators will be stalled waiting for the safepoint to complete and the
-        // the VMthread will be sleeping, waiting for the mutators to rendezvous.  The VMthread
-        // will eventually wake up and detect that all mutators are safe, at which point
-        // we'll again make progress.
-        //
-        // Beware too that that the VMThread typically runs at elevated priority.
-        // Its default priority is higher than the default mutator priority.
-        // Obviously, this complicates spinning.
-        //
-        // Note too that on Windows XP SwitchThreadTo() has quite different behavior than Sleep(0).
-        // Sleep(0) will _not yield to lower priority threads, while SwitchThreadTo() will.
-        //
-        // See the comments in synchronizer.cpp for additional remarks on spinning.
-        //
-        // In the future we might:
-        // 1. Modify the safepoint scheme to avoid potentially unbounded spinning.
-        //    This is tricky as the path used by a thread exiting the JVM (say on
-        //    on JNI call-out) simply stores into its state field.  The burden
-        //    is placed on the VM thread, which must poll (spin).
-        // 2. Find something useful to do while spinning.  If the safepoint is GC-related
-        //    we might aggressively scan the stacks of threads that are already safe.
-        // 3. Use Solaris schedctl to examine the state of the still-running mutators.
-        //    If all the mutators are ONPROC there's no reason to sleep or yield.
-        // 4. YieldTo() any still-running mutators that are ready but OFFPROC.
-        // 5. Check system saturation.  If the system is not fully saturated then
-        //    simply spin and avoid sleep/yield.
-        // 6. As still-running mutators rendezvous they could unpark the sleeping
-        //    VMthread.  This works well for still-running mutators that become
-        //    safe.  The VMthread must still poll for mutators that call-out.
-        // 7. Drive the policy on time-since-begin instead of iterations.
-        // 8. Consider making the spin duration a function of the # of CPUs:
-        //    Spin = (((ncpus-1) * M) + K) + F(still_running)
-        //    Alternately, instead of counting iterations of the outer loop
-        //    we could count the # of threads visited in the inner loop, above.
-        // 9. On windows consider using the return value from SwitchThreadTo()
-        //    to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
-
-        if (SafepointMechanism::uses_global_page_poll() && int(iterations) == DeferPollingPageLoopCount) {
-          guarantee (PageArmed == 0, "invariant") ;
-          PageArmed = 1 ;
-          os::make_polling_page_unreadable();
-        }
-
-        // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or
-        // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus)
-        ++steps ;
-        if (ncpus > 1 && steps < SafepointSpinBeforeYield) {
-          SpinPause() ;     // MP-Polite spin
-        } else
-          if (steps < DeferThrSuspendLoopCount) {
-            os::naked_yield() ;
-          } else {
-            os::naked_short_sleep(1);
+        if (still_running > 0) {
+          // Check for if it takes to long
+          if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
+            print_safepoint_timeout(_spinning_timeout);
           }
 
-        iterations ++ ;
+          // Spin to avoid context switching.
+          // There's a tension between allowing the mutators to run (and rendezvous)
+          // vs spinning.  As the VM thread spins, wasting cycles, it consumes CPU that
+          // a mutator might otherwise use profitably to reach a safepoint.  Excessive
+          // spinning by the VM thread on a saturated system can increase rendezvous latency.
+          // Blocking or yielding incur their own penalties in the form of context switching
+          // and the resultant loss of $ residency.
+          //
+          // Further complicating matters is that yield() does not work as naively expected
+          // on many platforms -- yield() does not guarantee that any other ready threads
+          // will run.   As such we revert to naked_short_sleep() after some number of iterations.
+          // nakes_short_sleep() is implemented as a short unconditional sleep.
+          // Typical operating systems round a "short" sleep period up to 10 msecs, so sleeping
+          // can actually increase the time it takes the VM thread to detect that a system-wide
+          // stop-the-world safepoint has been reached.  In a pathological scenario such as that
+          // described in CR6415670 the VMthread may sleep just before the mutator(s) become safe.
+          // In that case the mutators will be stalled waiting for the safepoint to complete and the
+          // the VMthread will be sleeping, waiting for the mutators to rendezvous.  The VMthread
+          // will eventually wake up and detect that all mutators are safe, at which point
+          // we'll again make progress.
+          //
+          // Beware too that that the VMThread typically runs at elevated priority.
+          // Its default priority is higher than the default mutator priority.
+          // Obviously, this complicates spinning.
+          //
+          // Note too that on Windows XP SwitchThreadTo() has quite different behavior than Sleep(0).
+          // Sleep(0) will _not yield to lower priority threads, while SwitchThreadTo() will.
+          //
+          // See the comments in synchronizer.cpp for additional remarks on spinning.
+          //
+          // In the future we might:
+          // 1. Modify the safepoint scheme to avoid potentially unbounded spinning.
+          //    This is tricky as the path used by a thread exiting the JVM (say on
+          //    on JNI call-out) simply stores into its state field.  The burden
+          //    is placed on the VM thread, which must poll (spin).
+          // 2. Find something useful to do while spinning.  If the safepoint is GC-related
+          //    we might aggressively scan the stacks of threads that are already safe.
+          // 3. Use Solaris schedctl to examine the state of the still-running mutators.
+          //    If all the mutators are ONPROC there's no reason to sleep or yield.
+          // 4. YieldTo() any still-running mutators that are ready but OFFPROC.
+          // 5. Check system saturation.  If the system is not fully saturated then
+          //    simply spin and avoid sleep/yield.
+          // 6. As still-running mutators rendezvous they could unpark the sleeping
+          //    VMthread.  This works well for still-running mutators that become
+          //    safe.  The VMthread must still poll for mutators that call-out.
+          // 7. Drive the policy on time-since-begin instead of iterations.
+          // 8. Consider making the spin duration a function of the # of CPUs:
+          //    Spin = (((ncpus-1) * M) + K) + F(still_running)
+          //    Alternately, instead of counting iterations of the outer loop
+          //    we could count the # of threads visited in the inner loop, above.
+          // 9. On windows consider using the return value from SwitchThreadTo()
+          //    to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
+
+          if (SafepointMechanism::uses_global_page_poll() && int(iterations) == DeferPollingPageLoopCount) {
+            guarantee (PageArmed == 0, "invariant") ;
+            PageArmed = 1 ;
+            os::make_polling_page_unreadable();
+          }
+
+          // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or
+          // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus)
+          ++steps ;
+          if (ncpus > 1 && steps < SafepointSpinBeforeYield) {
+            SpinPause() ;     // MP-Polite spin
+          } else
+            if (steps < DeferThrSuspendLoopCount) {
+              os::naked_yield() ;
+            } else {
+              os::naked_short_sleep(1);
+            }
+
+          iterations ++ ;
+        }
+        assert(iterations < (uint)max_jint, "We have been iterating in the safepoint loop too long");
       }
-      assert(iterations < (uint)max_jint, "We have been iterating in the safepoint loop too long");
-    }
+    } // ThreadsListHandle destroyed here.
     assert(still_running == 0, "sanity check");
 
     if (PrintSafepointStatistics) {
@@ -341,7 +346,7 @@
       sync_event.set_iterations(iterations);
       sync_event.commit();
     }
-  } //EventSafepointStateSync
+  } // EventSafepointStateSynchronization destroyed here.
 
   // wait until all threads are stopped
   {
@@ -393,8 +398,8 @@
   } // EventSafepointWaitBlocked
 
 #ifdef ASSERT
-  for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
-    // make sure all the threads were visited
+  // Make sure all the threads were visited.
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
     assert(cur->was_visited_for_critical_count(), "missed a thread");
   }
 #endif // ASSERT
@@ -452,81 +457,86 @@
     end_statistics(os::javaTimeNanos());
   }
 
+  {
+    JavaThreadIteratorWithHandle jtiwh;
 #ifdef ASSERT
-  // A pending_exception cannot be installed during a safepoint.  The threads
-  // may install an async exception after they come back from a safepoint into
-  // pending_exception after they unblock.  But that should happen later.
-  for (JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
-    assert (!(cur->has_pending_exception() &&
-              cur->safepoint_state()->is_at_poll_safepoint()),
-            "safepoint installed a pending exception");
-  }
+    // A pending_exception cannot be installed during a safepoint.  The threads
+    // may install an async exception after they come back from a safepoint into
+    // pending_exception after they unblock.  But that should happen later.
+    for (; JavaThread *cur = jtiwh.next(); ) {
+      assert (!(cur->has_pending_exception() &&
+                cur->safepoint_state()->is_at_poll_safepoint()),
+              "safepoint installed a pending exception");
+    }
 #endif // ASSERT
 
-  if (PageArmed) {
-    assert(SafepointMechanism::uses_global_page_poll(), "sanity");
-    // Make polling safepoint aware
-    os::make_polling_page_readable();
-    PageArmed = 0 ;
-  }
-
-  if (SafepointMechanism::uses_global_page_poll()) {
-    // Remove safepoint check from interpreter
-    Interpreter::ignore_safepoints();
-  }
-
-  {
-    MutexLocker mu(Safepoint_lock);
-
-    assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
+    if (PageArmed) {
+      assert(SafepointMechanism::uses_global_page_poll(), "sanity");
+      // Make polling safepoint aware
+      os::make_polling_page_readable();
+      PageArmed = 0 ;
+    }
 
-    if (SafepointMechanism::uses_thread_local_poll()) {
-      _state = _not_synchronized;
-      OrderAccess::storestore(); // global state -> local state
-      for (JavaThread *current = Threads::first(); current; current = current->next()) {
-        ThreadSafepointState* cur_state = current->safepoint_state();
-        cur_state->restart(); // TSS _running
-        SafepointMechanism::disarm_local_poll(current); // release store, local state -> polling page
-      }
-      log_debug(safepoint)("Leaving safepoint region");
-    } else {
-      // Set to not synchronized, so the threads will not go into the signal_thread_blocked method
-      // when they get restarted.
-      _state = _not_synchronized;
-      OrderAccess::fence();
-
-      log_debug(safepoint)("Leaving safepoint region");
-
-      // Start suspended threads
-      for (JavaThread *current = Threads::first(); current; current = current->next()) {
-        // A problem occurring on Solaris is when attempting to restart threads
-        // the first #cpus - 1 go well, but then the VMThread is preempted when we get
-        // to the next one (since it has been running the longest).  We then have
-        // to wait for a cpu to become available before we can continue restarting
-        // threads.
-        // FIXME: This causes the performance of the VM to degrade when active and with
-        // large numbers of threads.  Apparently this is due to the synchronous nature
-        // of suspending threads.
-        //
-        // TODO-FIXME: the comments above are vestigial and no longer apply.
-        // Furthermore, using solaris' schedctl in this particular context confers no benefit
-        if (VMThreadHintNoPreempt) {
-          os::hint_no_preempt();
-        }
-        ThreadSafepointState* cur_state = current->safepoint_state();
-        assert(cur_state->type() != ThreadSafepointState::_running, "Thread not suspended at safepoint");
-        cur_state->restart();
-        assert(cur_state->is_running(), "safepoint state has not been reset");
-      }
+    if (SafepointMechanism::uses_global_page_poll()) {
+      // Remove safepoint check from interpreter
+      Interpreter::ignore_safepoints();
     }
 
-    RuntimeService::record_safepoint_end();
+    {
+      MutexLocker mu(Safepoint_lock);
+
+      assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
+
+      if (SafepointMechanism::uses_thread_local_poll()) {
+        _state = _not_synchronized;
+        OrderAccess::storestore(); // global state -> local state
+        jtiwh.rewind();
+        for (; JavaThread *current = jtiwh.next(); ) {
+          ThreadSafepointState* cur_state = current->safepoint_state();
+          cur_state->restart(); // TSS _running
+          SafepointMechanism::disarm_local_poll(current); // release store, local state -> polling page
+        }
+        log_debug(safepoint)("Leaving safepoint region");
+      } else {
+        // Set to not synchronized, so the threads will not go into the signal_thread_blocked method
+        // when they get restarted.
+        _state = _not_synchronized;
+        OrderAccess::fence();
+
+        log_debug(safepoint)("Leaving safepoint region");
 
-    // Release threads lock, so threads can be created/destroyed again. It will also starts all threads
-    // blocked in signal_thread_blocked
-    Threads_lock->unlock();
+        // Start suspended threads
+        jtiwh.rewind();
+        for (; JavaThread *current = jtiwh.next(); ) {
+          // A problem occurring on Solaris is when attempting to restart threads
+          // the first #cpus - 1 go well, but then the VMThread is preempted when we get
+          // to the next one (since it has been running the longest).  We then have
+          // to wait for a cpu to become available before we can continue restarting
+          // threads.
+          // FIXME: This causes the performance of the VM to degrade when active and with
+          // large numbers of threads.  Apparently this is due to the synchronous nature
+          // of suspending threads.
+          //
+          // TODO-FIXME: the comments above are vestigial and no longer apply.
+          // Furthermore, using solaris' schedctl in this particular context confers no benefit
+          if (VMThreadHintNoPreempt) {
+            os::hint_no_preempt();
+          }
+          ThreadSafepointState* cur_state = current->safepoint_state();
+          assert(cur_state->type() != ThreadSafepointState::_running, "Thread not suspended at safepoint");
+          cur_state->restart();
+          assert(cur_state->is_running(), "safepoint state has not been reset");
+        }
+      }
 
-  }
+      RuntimeService::record_safepoint_end();
+
+      // Release threads lock, so threads can be created/destroyed again.
+      // It will also release all threads blocked in signal_thread_blocked.
+      Threads_lock->unlock();
+    }
+  } // ThreadsListHandle destroyed here.
+
   Universe::heap()->safepoint_synchronize_end();
   // record this time so VMThread can keep track how much time has elapsed
   // since last safepoint.
@@ -915,12 +925,11 @@
     tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
     ThreadSafepointState *cur_state;
     ResourceMark rm;
-    for (JavaThread *cur_thread = Threads::first(); cur_thread;
-        cur_thread = cur_thread->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) {
       cur_state = cur_thread->safepoint_state();
 
       if (cur_thread->thread_state() != _thread_blocked &&
-          ((reason == _spinning_timeout && cur_state->is_running()) ||
+        ((reason == _spinning_timeout && cur_state->is_running()) ||
            (reason == _blocking_timeout && !cur_state->has_called_back()))) {
         tty->print("# ");
         cur_thread->print();
@@ -1427,7 +1436,7 @@
     tty->print_cr("State: %s", (_state == _synchronizing) ? "synchronizing" :
                   "synchronized");
 
-    for (JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
        cur->safepoint_state()->print();
     }
   }
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -970,7 +970,7 @@
 {
   // We return a bad value here to make sure that the exception is
   // forwarded before we look at the return value.
-  THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badJNIHandle);
+  THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badAddress);
 }
 JNI_END
 
--- a/src/hotspot/share/runtime/statSampler.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/statSampler.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"
+#include "runtime/perfData.inline.hpp"
 #include "runtime/statSampler.hpp"
 #include "runtime/vm_version.hpp"
 
--- a/src/hotspot/share/runtime/synchronizer.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -894,7 +894,7 @@
 }
 
 // FIXME: jvmti should call this
-JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) {
+JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) {
   if (UseBiasedLocking) {
     if (SafepointSynchronize::is_at_safepoint()) {
       BiasedLocking::revoke_at_safepoint(h_obj);
@@ -923,7 +923,7 @@
 
   if (owner != NULL) {
     // owning_thread_from_monitor_owner() may also return NULL here
-    return Threads::owning_thread_from_monitor_owner(owner, doLock);
+    return Threads::owning_thread_from_monitor_owner(t_list, owner);
   }
 
   // Unlocked case, header in place
--- a/src/hotspot/share/runtime/synchronizer.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/synchronizer.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/perfData.hpp"
 
 class ObjectMonitor;
+class ThreadsList;
 
 struct DeflateMonitorCounters {
   int nInuse;          // currently associated with objects
@@ -125,7 +126,7 @@
   static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
   static LockOwnership query_lock_ownership(JavaThread * self, Handle h_obj);
 
-  static JavaThread* get_lock_owner(Handle h_obj, bool doLock);
+  static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
 
   // JNI detach support
   static void release_monitors_owned_by_thread(TRAPS);
--- a/src/hotspot/share/runtime/thread.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/thread.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -71,12 +71,12 @@
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniPeriodicChecker.hpp"
-#include "runtime/timerTrace.hpp"
 #include "runtime/memprofiler.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/objectMonitor.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/osThread.hpp"
+#include "runtime/prefetch.inline.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/safepointMechanism.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -86,6 +86,9 @@
 #include "runtime/task.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
+#include "runtime/threadSMR.inline.hpp"
+#include "runtime/timer.hpp"
+#include "runtime/timerTrace.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
 #include "runtime/vframe_hp.hpp"
@@ -104,6 +107,7 @@
 #include "utilities/events.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/preserveException.hpp"
+#include "utilities/resourceHash.hpp"
 #include "utilities/vmError.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/cms/concurrentMarkSweepThread.hpp"
@@ -195,13 +199,19 @@
 
 void Thread::operator delete(void* p) {
   if (UseBiasedLocking) {
-    void* real_malloc_addr = ((Thread*) p)->_real_malloc_address;
-    FreeHeap(real_malloc_addr);
+    FreeHeap(((Thread*) p)->_real_malloc_address);
   } else {
     FreeHeap(p);
   }
 }
 
+void JavaThread::smr_delete() {
+  if (_on_thread_list) {
+    Threads::smr_delete(this);
+  } else {
+    delete this;
+  }
+}
 
 // Base class for all threads: VMThread, WatcherThread, ConcurrentMarkSweepThread,
 // JavaThread
@@ -227,6 +237,9 @@
 
   // This initial value ==> never claimed.
   _oops_do_parity = 0;
+  _threads_hazard_ptr = NULL;
+  _nested_threads_hazard_ptr = NULL;
+  _nested_threads_hazard_ptr_cnt = 0;
 
   // the handle mark links itself to last_handle_mark
   new HandleMark(this);
@@ -398,9 +411,15 @@
 }
 
 #ifdef ASSERT
-// Private method to check for dangling thread pointer
-void check_for_dangling_thread_pointer(Thread *thread) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
+// A JavaThread is considered "dangling" if it is not the current
+// thread, has been added the Threads list, the system is not at a
+// safepoint and the Thread is not "protected".
+//
+void Thread::check_for_dangling_thread_pointer(Thread *thread) {
+  assert(!thread->is_Java_thread() || Thread::current() == thread ||
+         !((JavaThread *) thread)->on_thread_list() ||
+         SafepointSynchronize::is_at_safepoint() ||
+         Threads::is_a_protected_JavaThread_with_lock((JavaThread *) thread),
          "possibility of dangling Thread pointer");
 }
 #endif
@@ -732,6 +751,37 @@
   return false;
 }
 
+// Called from API entry points which perform stack walking. If the
+// associated JavaThread is the current thread, then wait_for_suspend
+// is not used. Otherwise, it determines if we should wait for the
+// "other" thread to complete external suspension. (NOTE: in future
+// releases the suspension mechanism should be reimplemented so this
+// is not necessary.)
+//
+bool
+JavaThread::is_thread_fully_suspended(bool wait_for_suspend, uint32_t *bits) {
+  if (this != JavaThread::current()) {
+    // "other" threads require special handling.
+    if (wait_for_suspend) {
+      // We are allowed to wait for the external suspend to complete
+      // so give the other thread a chance to get suspended.
+      if (!wait_for_ext_suspend_completion(SuspendRetryCount,
+                                           SuspendRetryDelay, bits)) {
+        // Didn't make it so let the caller know.
+        return false;
+      }
+    }
+    // We aren't allowed to wait for the external suspend to complete
+    // so if the other thread isn't externally suspended we need to
+    // let the caller know.
+    else if (!is_ext_suspend_completed_with_lock(bits)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 #ifndef PRODUCT
 void JavaThread::record_jump(address target, address instr, const char* file,
                              int line) {
@@ -810,9 +860,33 @@
     ext().print_on(st);
     osthread()->print_on(st);
   }
+  if (_threads_hazard_ptr != NULL) {
+    st->print("_threads_hazard_ptr=" INTPTR_FORMAT, p2i(_threads_hazard_ptr));
+  }
+  if (_nested_threads_hazard_ptr != NULL) {
+    print_nested_threads_hazard_ptrs_on(st);
+  }
+  st->print(" ");
   debug_only(if (WizardMode) print_owned_locks_on(st);)
 }
 
+void Thread::print_nested_threads_hazard_ptrs_on(outputStream* st) const {
+  assert(_nested_threads_hazard_ptr != NULL, "must be set to print");
+
+  if (EnableThreadSMRStatistics) {
+    st->print(", _nested_threads_hazard_ptr_cnt=%u", _nested_threads_hazard_ptr_cnt);
+  }
+  st->print(", _nested_threads_hazard_ptrs=");
+  for (NestedThreadsList* node = _nested_threads_hazard_ptr; node != NULL;
+       node = node->next()) {
+    if (node != _nested_threads_hazard_ptr) {
+      // First node does not need a comma-space separator.
+      st->print(", ");
+    }
+    st->print(INTPTR_FORMAT, p2i(node->t_list()));
+  }
+}
+
 // Thread::print_on_error() is called by fatal error handler. Don't use
 // any lock or allocate memory.
 void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
@@ -834,6 +908,13 @@
   if (osthread()) {
     st->print(" [id=%d]", osthread()->thread_id());
   }
+
+  if (_threads_hazard_ptr != NULL) {
+    st->print(" _threads_hazard_ptr=" INTPTR_FORMAT, p2i(_threads_hazard_ptr));
+  }
+  if (_nested_threads_hazard_ptr != NULL) {
+    print_nested_threads_hazard_ptrs_on(st);
+  }
 }
 
 void Thread::print_value_on(outputStream* st) const {
@@ -871,8 +952,8 @@
 
 #ifndef PRODUCT
 
-// The flag: potential_vm_operation notifies if this particular safepoint state could potential
-// invoke the vm-thread (i.e., and oop allocation). In that case, we also have to make sure that
+// The flag: potential_vm_operation notifies if this particular safepoint state could potentially
+// invoke the vm-thread (e.g., an oop allocation). In that case, we also have to make sure that
 // no threads which allow_vm_block's are held
 void Thread::check_for_valid_safepoint_state(bool potential_vm_operation) {
   // Check if current thread is allowed to block at a safepoint
@@ -1399,10 +1480,11 @@
 void JavaThread::collect_counters(typeArrayOop array) {
   if (JVMCICounterSize > 0) {
     MutexLocker tl(Threads_lock);
+    JavaThreadIteratorWithHandle jtiwh;
     for (int i = 0; i < array->length(); i++) {
       array->long_at_put(i, _jvmci_old_thread_counters[i]);
     }
-    for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
+    for (; JavaThread *tp = jtiwh.next(); ) {
       if (jvmci_counters_include(tp)) {
         for (int i = 0; i < array->length(); i++) {
           array->long_at_put(i, array->long_at(i) + tp->_jvmci_counters[i]);
@@ -1435,6 +1517,7 @@
   clear_must_deopt_id();
   set_monitor_chunks(NULL);
   set_next(NULL);
+  _on_thread_list = false;
   set_thread_state(_thread_new);
   _terminated = _not_terminated;
   _privileged_stack_top = NULL;
@@ -1715,12 +1798,12 @@
   DTRACE_THREAD_PROBE(stop, this);
 
   this->exit(false);
-  delete this;
+  this->smr_delete();
 }
 
 
 static void ensure_join(JavaThread* thread) {
-  // We do not need to grap the Threads_lock, since we are operating on ourself.
+  // We do not need to grab the Threads_lock, since we are operating on ourself.
   Handle threadObj(thread, thread->threadObj());
   assert(threadObj.not_null(), "java thread object must exist");
   ObjectLocker lock(threadObj, thread);
@@ -1742,6 +1825,15 @@
 void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
   assert(this == JavaThread::current(), "thread consistency check");
 
+  elapsedTimer _timer_exit_phase1;
+  elapsedTimer _timer_exit_phase2;
+  elapsedTimer _timer_exit_phase3;
+  elapsedTimer _timer_exit_phase4;
+
+  if (log_is_enabled(Debug, os, thread, timer)) {
+    _timer_exit_phase1.start();
+  }
+
   HandleMark hm(this);
   Handle uncaught_exception(this, this->pending_exception());
   this->clear_pending_exception();
@@ -1841,12 +1933,20 @@
     // before_exit() has already posted JVMTI THREAD_END events
   }
 
+  if (log_is_enabled(Debug, os, thread, timer)) {
+    _timer_exit_phase1.stop();
+    _timer_exit_phase2.start();
+  }
   // Notify waiters on thread object. This has to be done after exit() is called
   // on the thread (if the thread is the last thread in a daemon ThreadGroup the
   // group should have the destroyed bit set before waiters are notified).
   ensure_join(this);
   assert(!this->has_pending_exception(), "ensure_join should have cleared");
 
+  if (log_is_enabled(Debug, os, thread, timer)) {
+    _timer_exit_phase2.stop();
+    _timer_exit_phase3.start();
+  }
   // 6282335 JNI DetachCurrentThread spec states that all Java monitors
   // held by this thread must be released. The spec does not distinguish
   // between JNI-acquired and regular Java monitors. We can only see
@@ -1914,12 +2014,26 @@
     exit_type == JavaThread::normal_exit ? "exiting" : "detaching",
     os::current_thread_id());
 
+  if (log_is_enabled(Debug, os, thread, timer)) {
+    _timer_exit_phase3.stop();
+    _timer_exit_phase4.start();
+  }
   // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
   Threads::remove(this);
 
-  // If someone set a handshake on us just as we entered exit path, we simple cancel it.
-  if (ThreadLocalHandshakes) {
-    cancel_handshake();
+  if (log_is_enabled(Debug, os, thread, timer)) {
+    _timer_exit_phase4.stop();
+    ResourceMark rm(this);
+    log_debug(os, thread, timer)("name='%s'"
+                                 ", exit-phase1=" JLONG_FORMAT
+                                 ", exit-phase2=" JLONG_FORMAT
+                                 ", exit-phase3=" JLONG_FORMAT
+                                 ", exit-phase4=" JLONG_FORMAT,
+                                 get_thread_name(),
+                                 _timer_exit_phase1.milliseconds(),
+                                 _timer_exit_phase2.milliseconds(),
+                                 _timer_exit_phase3.milliseconds(),
+                                 _timer_exit_phase4.milliseconds());
   }
 }
 
@@ -1980,7 +2094,7 @@
 #endif // INCLUDE_ALL_GCS
 
   Threads::remove(this);
-  delete this;
+  this->smr_delete();
 }
 
 
@@ -2235,10 +2349,9 @@
 //   + Target thread will not enter any new monitors
 //
 void JavaThread::java_suspend() {
-  { MutexLocker mu(Threads_lock);
-    if (!Threads::includes(this) || is_exiting() || this->threadObj() == NULL) {
-      return;
-    }
+  ThreadsListHandle tlh;
+  if (!tlh.includes(this) || threadObj() == NULL || is_exiting()) {
+    return;
   }
 
   { MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
@@ -2327,14 +2440,8 @@
 // verify the JavaThread has not yet been published in the Threads::list, and
 // hence doesn't need protection from concurrent access at this stage
 void JavaThread::verify_not_published() {
-  if (!Threads_lock->owned_by_self()) {
-    MutexLockerEx ml(Threads_lock,  Mutex::_no_safepoint_check_flag);
-    assert(!Threads::includes(this),
-           "java thread shouldn't have been published yet!");
-  } else {
-    assert(!Threads::includes(this),
-           "java thread shouldn't have been published yet!");
-  }
+  ThreadsListHandle tlh;
+  assert(!tlh.includes(this), "JavaThread shouldn't have been published yet!");
 }
 #endif
 
@@ -2451,7 +2558,8 @@
 
   // Sanity check: thread is gone, has started exiting or the thread
   // was not externally suspended.
-  if (!Threads::includes(this) || is_exiting() || !is_external_suspend()) {
+  ThreadsListHandle tlh;
+  if (!tlh.includes(this) || is_exiting() || !is_external_suspend()) {
     return;
   }
 
@@ -2925,6 +3033,13 @@
   st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
             p2i(stack_end()), p2i(stack_base()));
   st->print("]");
+
+  if (_threads_hazard_ptr != NULL) {
+    st->print(" _threads_hazard_ptr=" INTPTR_FORMAT, p2i(_threads_hazard_ptr));
+  }
+  if (_nested_threads_hazard_ptr != NULL) {
+    print_nested_threads_hazard_ptrs_on(st);
+  }
   return;
 }
 
@@ -3318,23 +3433,140 @@
 // ======= Threads ========
 
 // The Threads class links together all active threads, and provides
-// operations over all threads.  It is protected by its own Mutex
-// lock, which is also used in other contexts to protect thread
-// operations from having the thread being operated on from exiting
-// and going away unexpectedly (e.g., safepoint synchronization)
-
-JavaThread* Threads::_thread_list = NULL;
-int         Threads::_number_of_threads = 0;
-int         Threads::_number_of_non_daemon_threads = 0;
-int         Threads::_return_code = 0;
-int         Threads::_thread_claim_parity = 0;
-size_t      JavaThread::_stack_size_at_create = 0;
+// operations over all threads. It is protected by the Threads_lock,
+// which is also used in other global contexts like safepointing.
+// ThreadsListHandles are used to safely perform operations on one
+// or more threads without the risk of the thread exiting during the
+// operation.
+//
+// Note: The Threads_lock is currently more widely used than we
+// would like. We are actively migrating Threads_lock uses to other
+// mechanisms in order to reduce Threads_lock contention.
+
+JavaThread*           Threads::_thread_list = NULL;
+int                   Threads::_number_of_threads = 0;
+int                   Threads::_number_of_non_daemon_threads = 0;
+int                   Threads::_return_code = 0;
+int                   Threads::_thread_claim_parity = 0;
+size_t                JavaThread::_stack_size_at_create = 0;
+// Safe Memory Reclamation (SMR) support:
+Monitor*              Threads::_smr_delete_lock =
+                          new Monitor(Monitor::special, "smr_delete_lock",
+                                      false /* allow_vm_block */,
+                                      Monitor::_safepoint_check_never);
+// The '_cnt', '_max' and '_times" fields are enabled via
+// -XX:+EnableThreadSMRStatistics:
+
+// # of parallel threads in _smr_delete_lock->wait().
+// Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit,
+// but there is no nice 16-bit _FORMAT support.
+uint                  Threads::_smr_delete_lock_wait_cnt = 0;
+
+// Max # of parallel threads in _smr_delete_lock->wait().
+// Impl note: See _smr_delete_lock_wait_cnt note.
+uint                  Threads::_smr_delete_lock_wait_max = 0;
+
+// Flag to indicate when an _smr_delete_lock->notify() is needed.
+// Impl note: See _smr_delete_lock_wait_cnt note.
+volatile uint         Threads::_smr_delete_notify = 0;
+
+// # of threads deleted over VM lifetime.
+// Impl note: Atomically incremented over VM lifetime so use unsigned for more
+// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
+// isn't available everywhere (or is it?).
+volatile uint         Threads::_smr_deleted_thread_cnt = 0;
+
+// Max time in millis to delete a thread.
+// Impl note: 16-bit might be too small on an overloaded machine. Use
+// unsigned since this is a time value. Set via Atomic::cmpxchg() in a
+// loop for correctness.
+volatile uint         Threads::_smr_deleted_thread_time_max = 0;
+
+// Cumulative time in millis to delete threads.
+// Impl note: Atomically added to over VM lifetime so use unsigned for more
+// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
+// isn't available everywhere (or is it?).
+volatile uint         Threads::_smr_deleted_thread_times = 0;
+
+ThreadsList* volatile Threads::_smr_java_thread_list = new ThreadsList(0);
+
+// # of ThreadsLists allocated over VM lifetime.
+// Impl note: We allocate a new ThreadsList for every thread create and
+// every thread delete so we need a bigger type than the
+// _smr_deleted_thread_cnt field.
+uint64_t              Threads::_smr_java_thread_list_alloc_cnt = 1;
+
+// # of ThreadsLists freed over VM lifetime.
+// Impl note: See _smr_java_thread_list_alloc_cnt note.
+uint64_t              Threads::_smr_java_thread_list_free_cnt = 0;
+
+// Max size ThreadsList allocated.
+// Impl note: Max # of threads alive at one time should fit in unsigned 32-bit.
+uint                  Threads::_smr_java_thread_list_max = 0;
+
+// Max # of nested ThreadsLists for a thread.
+// Impl note: Hard to imagine > 64K nested ThreadsLists so this could be
+// 16-bit, but there is no nice 16-bit _FORMAT support.
+uint                  Threads::_smr_nested_thread_list_max = 0;
+
+// # of ThreadsListHandles deleted over VM lifetime.
+// Impl note: Atomically incremented over VM lifetime so use unsigned for
+// more range. There will be fewer ThreadsListHandles than threads so
+// unsigned 32-bit should be fine.
+volatile uint         Threads::_smr_tlh_cnt = 0;
+
+// Max time in millis to delete a ThreadsListHandle.
+// Impl note: 16-bit might be too small on an overloaded machine. Use
+// unsigned since this is a time value. Set via Atomic::cmpxchg() in a
+// loop for correctness.
+volatile uint         Threads::_smr_tlh_time_max = 0;
+
+// Cumulative time in millis to delete ThreadsListHandles.
+// Impl note: Atomically added to over VM lifetime so use unsigned for more
+// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
+// isn't available everywhere (or is it?).
+volatile uint         Threads::_smr_tlh_times = 0;
+
+ThreadsList*          Threads::_smr_to_delete_list = NULL;
+
+// # of parallel ThreadsLists on the to-delete list.
+// Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so
+// this could be 16-bit, but there is no nice 16-bit _FORMAT support.
+uint                  Threads::_smr_to_delete_list_cnt = 0;
+
+// Max # of parallel ThreadsLists on the to-delete list.
+// Impl note: See _smr_to_delete_list_cnt note.
+uint                  Threads::_smr_to_delete_list_max = 0;
+
 #ifdef ASSERT
-bool        Threads::_vm_complete = false;
+bool                  Threads::_vm_complete = false;
 #endif
 
+static inline void *prefetch_and_load_ptr(void **addr, intx prefetch_interval) {
+  Prefetch::read((void*)addr, prefetch_interval);
+  return *addr;
+}
+
+// Possibly the ugliest for loop the world has seen. C++ does not allow
+// multiple types in the declaration section of the for loop. In this case
+// we are only dealing with pointers and hence can cast them. It looks ugly
+// but macros are ugly and therefore it's fine to make things absurdly ugly.
+#define DO_JAVA_THREADS(LIST, X)                                                                                          \
+    for (JavaThread *MACRO_scan_interval = (JavaThread*)(uintptr_t)PrefetchScanIntervalInBytes,                           \
+             *MACRO_list = (JavaThread*)(LIST),                                                                           \
+             **MACRO_end = ((JavaThread**)((ThreadsList*)MACRO_list)->threads()) + ((ThreadsList*)MACRO_list)->length(),  \
+             **MACRO_current_p = (JavaThread**)((ThreadsList*)MACRO_list)->threads(),                                     \
+             *X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval);                 \
+         MACRO_current_p != MACRO_end;                                                                                    \
+         MACRO_current_p++,                                                                                               \
+             X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval))
+
+inline ThreadsList* Threads::get_smr_java_thread_list() {
+  return (ThreadsList*)OrderAccess::load_acquire(&_smr_java_thread_list);
+}
+
 // All JavaThreads
-#define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next())
+#define ALL_JAVA_THREADS(X) DO_JAVA_THREADS(get_smr_java_thread_list(), X)
 
 // All JavaThreads + all non-JavaThreads (i.e., every thread in the system)
 void Threads::threads_do(ThreadClosure* tc) {
@@ -3435,6 +3667,240 @@
                                          vmSymbols::void_method_signature(), CHECK);
 }
 
+// Safe Memory Reclamation (SMR) support:
+//
+
+// Acquire a stable ThreadsList.
+//
+ThreadsList *Threads::acquire_stable_list(Thread *self, bool is_ThreadsListSetter) {
+  assert(self != NULL, "sanity check");
+  // acquire_stable_list_nested_path() will grab the Threads_lock
+  // so let's make sure the ThreadsListHandle is in a safe place.
+  // ThreadsListSetter cannot make this check on this code path.
+  debug_only(if (!is_ThreadsListSetter && StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);)
+
+  if (self->get_threads_hazard_ptr() == NULL) {
+    // The typical case is first.
+    return acquire_stable_list_fast_path(self);
+  }
+
+  // The nested case is rare.
+  return acquire_stable_list_nested_path(self);
+}
+
+// Fast path (and lock free) way to acquire a stable ThreadsList.
+//
+ThreadsList *Threads::acquire_stable_list_fast_path(Thread *self) {
+  assert(self != NULL, "sanity check");
+  assert(self->get_threads_hazard_ptr() == NULL, "sanity check");
+  assert(self->get_nested_threads_hazard_ptr() == NULL,
+         "cannot have a nested hazard ptr with a NULL regular hazard ptr");
+
+  ThreadsList* threads;
+
+  // Stable recording of a hazard ptr for SMR. This code does not use
+  // locks so its use of the _smr_java_thread_list & _threads_hazard_ptr
+  // fields is racy relative to code that uses those fields with locks.
+  // OrderAccess and Atomic functions are used to deal with those races.
+  //
+  while (true) {
+    threads = get_smr_java_thread_list();
+
+    // Publish a tagged hazard ptr to denote that the hazard ptr is not
+    // yet verified as being stable. Due to the fence after the hazard
+    // ptr write, it will be sequentially consistent w.r.t. the
+    // sequentially consistent writes of the ThreadsList, even on
+    // non-multiple copy atomic machines where stores can be observed
+    // in different order from different observer threads.
+    ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads);
+    self->set_threads_hazard_ptr(unverified_threads);
+
+    // If _smr_java_thread_list has changed, we have lost a race with
+    // Threads::add() or Threads::remove() and have to try again.
+    if (get_smr_java_thread_list() != threads) {
+      continue;
+    }
+
+    // We try to remove the tag which will verify the hazard ptr as
+    // being stable. This exchange can race with a scanning thread
+    // which might invalidate the tagged hazard ptr to keep it from
+    // being followed to access JavaThread ptrs. If we lose the race,
+    // we simply retry. If we win the race, then the stable hazard
+    // ptr is officially published.
+    if (self->cmpxchg_threads_hazard_ptr(threads, unverified_threads) == unverified_threads) {
+      break;
+    }
+  }
+
+  // A stable hazard ptr has been published letting other threads know
+  // that the ThreadsList and the JavaThreads reachable from this list
+  // are protected and hence they should not be deleted until everyone
+  // agrees it is safe to do so.
+
+  return threads;
+}
+
+// Acquire a nested stable ThreadsList; this is rare so it uses
+// Threads_lock.
+//
+ThreadsList *Threads::acquire_stable_list_nested_path(Thread *self) {
+  assert(self != NULL, "sanity check");
+  assert(self->get_threads_hazard_ptr() != NULL,
+         "cannot have a NULL regular hazard ptr when acquiring a nested hazard ptr");
+
+  // The thread already has a hazard ptr (ThreadsList ref) so we need
+  // to create a nested ThreadsListHandle with the current ThreadsList
+  // since it might be different than our current hazard ptr. The need
+  // for a nested ThreadsListHandle is rare so we do this while holding
+  // the Threads_lock so we don't race with the scanning code; the code
+  // is so much simpler this way.
+
+  NestedThreadsList* node;
+  {
+    // Only grab the Threads_lock if we don't already own it.
+    MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock);
+    node = new NestedThreadsList(get_smr_java_thread_list());
+    // We insert at the front of the list to match up with the delete
+    // in release_stable_list().
+    node->set_next(self->get_nested_threads_hazard_ptr());
+    self->set_nested_threads_hazard_ptr(node);
+    if (EnableThreadSMRStatistics) {
+      self->inc_nested_threads_hazard_ptr_cnt();
+      if (self->nested_threads_hazard_ptr_cnt() > _smr_nested_thread_list_max) {
+        _smr_nested_thread_list_max = self->nested_threads_hazard_ptr_cnt();
+      }
+    }
+  }
+  log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::acquire_stable_list: add NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list()));
+
+  return node->t_list();
+}
+
+inline void Threads::add_smr_deleted_thread_times(uint add_value) {
+  Atomic::add(add_value, &_smr_deleted_thread_times);
+}
+
+inline void Threads::inc_smr_deleted_thread_cnt() {
+  Atomic::inc(&_smr_deleted_thread_cnt);
+}
+
+// Release a stable ThreadsList.
+//
+void Threads::release_stable_list(Thread *self) {
+  assert(self != NULL, "sanity check");
+  // release_stable_list_nested_path() will grab the Threads_lock
+  // so let's make sure the ThreadsListHandle is in a safe place.
+  debug_only(if (StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);)
+
+  if (self->get_nested_threads_hazard_ptr() == NULL) {
+    // The typical case is first.
+    release_stable_list_fast_path(self);
+    return;
+  }
+
+  // The nested case is rare.
+  release_stable_list_nested_path(self);
+}
+
+// Fast path way to release a stable ThreadsList. The release portion
+// is lock-free, but the wake up portion is not.
+//
+void Threads::release_stable_list_fast_path(Thread *self) {
+  assert(self != NULL, "sanity check");
+  assert(self->get_threads_hazard_ptr() != NULL, "sanity check");
+  assert(self->get_nested_threads_hazard_ptr() == NULL,
+         "cannot have a nested hazard ptr when releasing a regular hazard ptr");
+
+  // After releasing the hazard ptr, other threads may go ahead and
+  // free up some memory temporarily used by a ThreadsList snapshot.
+  self->set_threads_hazard_ptr(NULL);
+
+  // We use double-check locking to reduce traffic on the system
+  // wide smr_delete_lock.
+  if (Threads::smr_delete_notify()) {
+    // An exiting thread might be waiting in smr_delete(); we need to
+    // check with smr_delete_lock to be sure.
+    release_stable_list_wake_up((char *) "regular hazard ptr");
+  }
+}
+
+// Release a nested stable ThreadsList; this is rare so it uses
+// Threads_lock.
+//
+void Threads::release_stable_list_nested_path(Thread *self) {
+  assert(self != NULL, "sanity check");
+  assert(self->get_nested_threads_hazard_ptr() != NULL, "sanity check");
+  assert(self->get_threads_hazard_ptr() != NULL,
+         "must have a regular hazard ptr to have nested hazard ptrs");
+
+  // We have a nested ThreadsListHandle so we have to release it first.
+  // The need for a nested ThreadsListHandle is rare so we do this while
+  // holding the Threads_lock so we don't race with the scanning code;
+  // the code is so much simpler this way.
+
+  NestedThreadsList *node;
+  {
+    // Only grab the Threads_lock if we don't already own it.
+    MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock);
+    // We remove from the front of the list to match up with the insert
+    // in acquire_stable_list().
+    node = self->get_nested_threads_hazard_ptr();
+    self->set_nested_threads_hazard_ptr(node->next());
+    if (EnableThreadSMRStatistics) {
+      self->dec_nested_threads_hazard_ptr_cnt();
+    }
+  }
+
+  // An exiting thread might be waiting in smr_delete(); we need to
+  // check with smr_delete_lock to be sure.
+  release_stable_list_wake_up((char *) "nested hazard ptr");
+
+  log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::release_stable_list: delete NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list()));
+
+  delete node;
+}
+
+// Wake up portion of the release stable ThreadsList protocol;
+// uses the smr_delete_lock().
+//
+void Threads::release_stable_list_wake_up(char *log_str) {
+  assert(log_str != NULL, "sanity check");
+
+  // Note: smr_delete_lock is held in smr_delete() for the entire
+  // hazard ptr search so that we do not lose this notify() if
+  // the exiting thread has to wait. That code path also holds
+  // Threads_lock (which was grabbed before smr_delete_lock) so that
+  // threads_do() can be called. This means the system can't start a
+  // safepoint which means this thread can't take too long to get to
+  // a safepoint because of being blocked on smr_delete_lock.
+  //
+  MonitorLockerEx ml(Threads::smr_delete_lock(), Monitor::_no_safepoint_check_flag);
+  if (Threads::smr_delete_notify()) {
+    // Notify any exiting JavaThreads that are waiting in smr_delete()
+    // that we've released a ThreadsList.
+    ml.notify_all();
+    log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::release_stable_list notified %s", os::current_thread_id(), log_str);
+  }
+}
+
+inline void Threads::update_smr_deleted_thread_time_max(uint new_value) {
+  while (true) {
+    uint cur_value = _smr_deleted_thread_time_max;
+    if (new_value <= cur_value) {
+      // No need to update max value so we're done.
+      break;
+    }
+    if (Atomic::cmpxchg(new_value, &_smr_deleted_thread_time_max, cur_value) == cur_value) {
+      // Updated max value so we're done. Otherwise try it all again.
+      break;
+    }
+  }
+}
+
+inline ThreadsList* Threads::xchg_smr_java_thread_list(ThreadsList* new_list) {
+  return (ThreadsList*)Atomic::xchg(new_list, &_smr_java_thread_list);
+}
+
 void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
   TraceTime timer("Initialize java.lang classes", TRACETIME_LOG(Info, startuptime));
 
@@ -3616,7 +4082,7 @@
   if (!main_thread->set_as_starting_thread()) {
     vm_shutdown_during_initialization(
                                       "Failed necessary internal allocation. Out of swap space");
-    delete main_thread;
+    main_thread->smr_delete();
     *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
     return JNI_ENOMEM;
   }
@@ -3631,7 +4097,7 @@
   // Initialize global modules
   jint status = init_globals();
   if (status != JNI_OK) {
-    delete main_thread;
+    main_thread->smr_delete();
     *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
     return status;
   }
@@ -4037,23 +4503,6 @@
   }
 }
 
-JavaThread* Threads::find_java_thread_from_java_tid(jlong java_tid) {
-  assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
-
-  JavaThread* java_thread = NULL;
-  // Sequential search for now.  Need to do better optimization later.
-  for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
-    oop tobj = thread->threadObj();
-    if (!thread->is_exiting() &&
-        tobj != NULL &&
-        java_tid == java_lang_Thread::thread_id(tobj)) {
-      java_thread = thread;
-      break;
-    }
-  }
-  return java_thread;
-}
-
 
 // Last thread running calls java.lang.Shutdown.shutdown()
 void JavaThread::invoke_shutdown_hooks() {
@@ -4179,6 +4628,11 @@
 
   notify_vm_shutdown();
 
+  // We are after VM_Exit::set_vm_exited() so we can't call
+  // thread->smr_delete() or we will block on the Threads_lock.
+  // Deleting the shutdown thread here is safe because another
+  // JavaThread cannot have an active ThreadsListHandle for
+  // this JavaThread.
   delete thread;
 
 #if INCLUDE_JVMCI
@@ -4212,6 +4666,501 @@
   return JNI_FALSE;
 }
 
+// Hash table of pointers found by a scan. Used for collecting hazard
+// pointers (ThreadsList references). Also used for collecting JavaThreads
+// that are indirectly referenced by hazard ptrs. An instance of this
+// class only contains one type of pointer.
+//
+class ThreadScanHashtable : public CHeapObj<mtThread> {
+ private:
+  static bool ptr_equals(void * const& s1, void * const& s2) {
+    return s1 == s2;
+  }
+
+  static unsigned int ptr_hash(void * const& s1) {
+    // 2654435761 = 2^32 * Phi (golden ratio)
+    return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u);
+  }
+
+  int _table_size;
+  // ResourceHashtable SIZE is specified at compile time so our
+  // dynamic _table_size is unused for now; 1031 is the first prime
+  // after 1024.
+  typedef ResourceHashtable<void *, int, &ThreadScanHashtable::ptr_hash,
+                            &ThreadScanHashtable::ptr_equals, 1031,
+                            ResourceObj::C_HEAP, mtThread> PtrTable;
+  PtrTable * _ptrs;
+
+ public:
+  // ResourceHashtable is passed to various functions and populated in
+  // different places so we allocate it using C_HEAP to make it immune
+  // from any ResourceMarks that happen to be in the code paths.
+  ThreadScanHashtable(int table_size) : _table_size(table_size), _ptrs(new (ResourceObj::C_HEAP, mtThread) PtrTable()) {}
+
+  ~ThreadScanHashtable() { delete _ptrs; }
+
+  bool has_entry(void *pointer) {
+    int *val_ptr = _ptrs->get(pointer);
+    return val_ptr != NULL && *val_ptr == 1;
+  }
+
+  void add_entry(void *pointer) {
+    _ptrs->put(pointer, 1);
+  }
+};
+
+// Closure to gather JavaThreads indirectly referenced by hazard ptrs
+// (ThreadsList references) into a hash table. This closure handles part 2
+// of the dance - adding all the JavaThreads referenced by the hazard
+// pointer (ThreadsList reference) to the hash table.
+//
+class AddThreadHazardPointerThreadClosure : public ThreadClosure {
+ private:
+  ThreadScanHashtable *_table;
+
+ public:
+  AddThreadHazardPointerThreadClosure(ThreadScanHashtable *table) : _table(table) {}
+
+  virtual void do_thread(Thread *thread) {
+    if (!_table->has_entry((void*)thread)) {
+      // The same JavaThread might be on more than one ThreadsList or
+      // more than one thread might be using the same ThreadsList. In
+      // either case, we only need a single entry for a JavaThread.
+      _table->add_entry((void*)thread);
+    }
+  }
+};
+
+// Closure to gather JavaThreads indirectly referenced by hazard ptrs
+// (ThreadsList references) into a hash table. This closure handles part 1
+// of the dance - hazard ptr chain walking and dispatch to another
+// closure.
+//
+class ScanHazardPtrGatherProtectedThreadsClosure : public ThreadClosure {
+ private:
+  ThreadScanHashtable *_table;
+ public:
+  ScanHazardPtrGatherProtectedThreadsClosure(ThreadScanHashtable *table) : _table(table) {}
+
+  virtual void do_thread(Thread *thread) {
+    assert_locked_or_safepoint(Threads_lock);
+
+    if (thread == NULL) return;
+
+    // This code races with Threads::acquire_stable_list() which is
+    // lock-free so we have to handle some special situations.
+    //
+    ThreadsList *current_list = NULL;
+    while (true) {
+      current_list = thread->get_threads_hazard_ptr();
+      // No hazard ptr so nothing more to do.
+      if (current_list == NULL) {
+        assert(thread->get_nested_threads_hazard_ptr() == NULL,
+               "cannot have a nested hazard ptr with a NULL regular hazard ptr");
+        return;
+      }
+
+      // If the hazard ptr is verified as stable (since it is not tagged),
+      // then it is safe to use.
+      if (!Thread::is_hazard_ptr_tagged(current_list)) break;
+
+      // The hazard ptr is tagged as not yet verified as being stable
+      // so we are racing with acquire_stable_list(). This exchange
+      // attempts to invalidate the hazard ptr. If we win the race,
+      // then we can ignore this unstable hazard ptr and the other
+      // thread will retry the attempt to publish a stable hazard ptr.
+      // If we lose the race, then we retry our attempt to look at the
+      // hazard ptr.
+      if (thread->cmpxchg_threads_hazard_ptr(NULL, current_list) == current_list) return;
+    }
+
+    // The current JavaThread has a hazard ptr (ThreadsList reference)
+    // which might be _smr_java_thread_list or it might be an older
+    // ThreadsList that has been removed but not freed. In either case,
+    // the hazard ptr is protecting all the JavaThreads on that
+    // ThreadsList.
+    AddThreadHazardPointerThreadClosure add_cl(_table);
+    current_list->threads_do(&add_cl);
+
+    // Any NestedThreadsLists are also protecting JavaThreads so
+    // gather those also; the ThreadsLists may be different.
+    for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr();
+         node != NULL; node = node->next()) {
+      node->t_list()->threads_do(&add_cl);
+    }
+  }
+};
+
+// Closure to print JavaThreads that have a hazard ptr (ThreadsList
+// reference) that contains an indirect reference to a specific JavaThread.
+//
+class ScanHazardPtrPrintMatchingThreadsClosure : public ThreadClosure {
+ private:
+  JavaThread *_thread;
+ public:
+  ScanHazardPtrPrintMatchingThreadsClosure(JavaThread *thread) : _thread(thread) {}
+
+  virtual void do_thread(Thread *thread) {
+    assert_locked_or_safepoint(Threads_lock);
+
+    if (thread == NULL) return;
+    ThreadsList *current_list = thread->get_threads_hazard_ptr();
+    if (current_list == NULL) {
+      assert(thread->get_nested_threads_hazard_ptr() == NULL,
+             "cannot have a nested hazard ptr with a NULL regular hazard ptr");
+      return;
+    }
+    // If the hazard ptr is unverified, then ignore it.
+    if (Thread::is_hazard_ptr_tagged(current_list)) return;
+
+    // The current JavaThread has a hazard ptr (ThreadsList reference)
+    // which might be _smr_java_thread_list or it might be an older
+    // ThreadsList that has been removed but not freed. In either case,
+    // the hazard ptr is protecting all the JavaThreads on that
+    // ThreadsList, but we only care about matching a specific JavaThread.
+    DO_JAVA_THREADS(current_list, p) {
+      if (p == _thread) {
+        log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread1=" INTPTR_FORMAT " has a hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread));
+        break;
+      }
+    }
+
+    // Any NestedThreadsLists are also protecting JavaThreads so
+    // check those also; the ThreadsLists may be different.
+    for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr();
+         node != NULL; node = node->next()) {
+      DO_JAVA_THREADS(node->t_list(), p) {
+        if (p == _thread) {
+          log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread1=" INTPTR_FORMAT " has a nested hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread));
+          return;
+        }
+      }
+    }
+  }
+};
+
+// Return true if the specified JavaThread is protected by a hazard
+// pointer (ThreadsList reference). Otherwise, returns false.
+//
+bool Threads::is_a_protected_JavaThread(JavaThread *thread) {
+  assert_locked_or_safepoint(Threads_lock);
+
+  // Hash table size should be first power of two higher than twice
+  // the length of the Threads list.
+  int hash_table_size = MIN2(_number_of_threads, 32) << 1;
+  hash_table_size--;
+  hash_table_size |= hash_table_size >> 1;
+  hash_table_size |= hash_table_size >> 2;
+  hash_table_size |= hash_table_size >> 4;
+  hash_table_size |= hash_table_size >> 8;
+  hash_table_size |= hash_table_size >> 16;
+  hash_table_size++;
+
+  // Gather a hash table of the JavaThreads indirectly referenced by
+  // hazard ptrs.
+  ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size);
+  ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table);
+  Threads::threads_do(&scan_cl);
+
+  bool thread_is_protected = false;
+  if (scan_table->has_entry((void*)thread)) {
+    thread_is_protected = true;
+  }
+  delete scan_table;
+  return thread_is_protected;
+}
+
+// Safely delete a JavaThread when it is no longer in use by a
+// ThreadsListHandle.
+//
+void Threads::smr_delete(JavaThread *thread) {
+  assert(!Threads_lock->owned_by_self(), "sanity");
+
+  bool has_logged_once = false;
+  elapsedTimer timer;
+  if (EnableThreadSMRStatistics) {
+    timer.start();
+  }
+
+  while (true) {
+    {
+      // No safepoint check because this JavaThread is not on the
+      // Threads list.
+      MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
+      // Cannot use a MonitorLockerEx helper here because we have
+      // to drop the Threads_lock first if we wait.
+      Threads::smr_delete_lock()->lock_without_safepoint_check();
+      // Set the smr_delete_notify flag after we grab smr_delete_lock
+      // and before we scan hazard ptrs because we're doing
+      // double-check locking in release_stable_list().
+      Threads::set_smr_delete_notify();
+
+      if (!is_a_protected_JavaThread(thread)) {
+        // This is the common case.
+        Threads::clear_smr_delete_notify();
+        Threads::smr_delete_lock()->unlock();
+        break;
+      }
+      if (!has_logged_once) {
+        has_logged_once = true;
+        log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread));
+        if (log_is_enabled(Debug, os, thread)) {
+          ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread);
+          Threads::threads_do(&scan_cl);
+        }
+      }
+    } // We have to drop the Threads_lock to wait or delete the thread
+
+    if (EnableThreadSMRStatistics) {
+      _smr_delete_lock_wait_cnt++;
+      if (_smr_delete_lock_wait_cnt > _smr_delete_lock_wait_max) {
+        _smr_delete_lock_wait_max = _smr_delete_lock_wait_cnt;
+      }
+    }
+    // Wait for a release_stable_list() call before we check again. No
+    // safepoint check, no timeout, and not as suspend equivalent flag
+    // because this JavaThread is not on the Threads list.
+    Threads::smr_delete_lock()->wait(Mutex::_no_safepoint_check_flag, 0,
+                                     !Mutex::_as_suspend_equivalent_flag);
+    if (EnableThreadSMRStatistics) {
+      _smr_delete_lock_wait_cnt--;
+    }
+
+    Threads::clear_smr_delete_notify();
+    Threads::smr_delete_lock()->unlock();
+    // Retry the whole scenario.
+  }
+
+  if (ThreadLocalHandshakes) {
+    // The thread is about to be deleted so cancel any handshake.
+    thread->cancel_handshake();
+  }
+
+  delete thread;
+  if (EnableThreadSMRStatistics) {
+    timer.stop();
+    uint millis = (uint)timer.milliseconds();
+    Threads::inc_smr_deleted_thread_cnt();
+    Threads::add_smr_deleted_thread_times(millis);
+    Threads::update_smr_deleted_thread_time_max(millis);
+  }
+
+  log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread));
+}
+
+bool Threads::smr_delete_notify() {
+  // Use load_acquire() in order to see any updates to _smr_delete_notify
+  // earlier than when smr_delete_lock is grabbed.
+  return (OrderAccess::load_acquire(&_smr_delete_notify) != 0);
+}
+
+// set_smr_delete_notify() and clear_smr_delete_notify() are called
+// under the protection of the smr_delete_lock, but we also use an
+// Atomic operation to ensure the memory update is seen earlier than
+// when the smr_delete_lock is dropped.
+//
+void Threads::set_smr_delete_notify() {
+  Atomic::inc(&_smr_delete_notify);
+}
+
+void Threads::clear_smr_delete_notify() {
+  Atomic::dec(&_smr_delete_notify);
+}
+
+// Closure to gather hazard ptrs (ThreadsList references) into a hash table.
+//
+class ScanHazardPtrGatherThreadsListClosure : public ThreadClosure {
+ private:
+  ThreadScanHashtable *_table;
+ public:
+  ScanHazardPtrGatherThreadsListClosure(ThreadScanHashtable *table) : _table(table) {}
+
+  virtual void do_thread(Thread* thread) {
+    assert_locked_or_safepoint(Threads_lock);
+
+    if (thread == NULL) return;
+    ThreadsList *threads = thread->get_threads_hazard_ptr();
+    if (threads == NULL) {
+      assert(thread->get_nested_threads_hazard_ptr() == NULL,
+             "cannot have a nested hazard ptr with a NULL regular hazard ptr");
+      return;
+    }
+    // In this closure we always ignore the tag that might mark this
+    // hazard ptr as not yet verified. If we happen to catch an
+    // unverified hazard ptr that is subsequently discarded (not
+    // published), then the only side effect is that we might keep a
+    // to-be-deleted ThreadsList alive a little longer.
+    threads = Thread::untag_hazard_ptr(threads);
+    if (!_table->has_entry((void*)threads)) {
+      _table->add_entry((void*)threads);
+    }
+
+    // Any NestedThreadsLists are also protecting JavaThreads so
+    // gather those also; the ThreadsLists may be different.
+    for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr();
+         node != NULL; node = node->next()) {
+      threads = node->t_list();
+      if (!_table->has_entry((void*)threads)) {
+        _table->add_entry((void*)threads);
+      }
+    }
+  }
+};
+
+// Safely free a ThreadsList after a Threads::add() or Threads::remove().
+// The specified ThreadsList may not get deleted during this call if it
+// is still in-use (referenced by a hazard ptr). Other ThreadsLists
+// in the chain may get deleted by this call if they are no longer in-use.
+void Threads::smr_free_list(ThreadsList* threads) {
+  assert_locked_or_safepoint(Threads_lock);
+
+  threads->set_next_list(_smr_to_delete_list);
+  _smr_to_delete_list = threads;
+  if (EnableThreadSMRStatistics) {
+    _smr_to_delete_list_cnt++;
+    if (_smr_to_delete_list_cnt > _smr_to_delete_list_max) {
+      _smr_to_delete_list_max = _smr_to_delete_list_cnt;
+    }
+  }
+
+  // Hash table size should be first power of two higher than twice the length of the ThreadsList
+  int hash_table_size = MIN2(_number_of_threads, 32) << 1;
+  hash_table_size--;
+  hash_table_size |= hash_table_size >> 1;
+  hash_table_size |= hash_table_size >> 2;
+  hash_table_size |= hash_table_size >> 4;
+  hash_table_size |= hash_table_size >> 8;
+  hash_table_size |= hash_table_size >> 16;
+  hash_table_size++;
+
+  // Gather a hash table of the current hazard ptrs:
+  ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size);
+  ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table);
+  Threads::threads_do(&scan_cl);
+
+  // Walk through the linked list of pending freeable ThreadsLists
+  // and free the ones that are not referenced from hazard ptrs.
+  ThreadsList* current = _smr_to_delete_list;
+  ThreadsList* prev = NULL;
+  ThreadsList* next = NULL;
+  bool threads_is_freed = false;
+  while (current != NULL) {
+    next = current->next_list();
+    if (!scan_table->has_entry((void*)current)) {
+      // This ThreadsList is not referenced by a hazard ptr.
+      if (prev != NULL) {
+        prev->set_next_list(next);
+      }
+      if (_smr_to_delete_list == current) {
+        _smr_to_delete_list = next;
+      }
+
+      log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current));
+      if (current == threads) threads_is_freed = true;
+      delete current;
+      if (EnableThreadSMRStatistics) {
+        _smr_java_thread_list_free_cnt++;
+        _smr_to_delete_list_cnt--;
+      }
+    } else {
+      prev = current;
+    }
+    current = next;
+  }
+
+  if (!threads_is_freed) {
+    // Only report "is not freed" on the original call to
+    // smr_free_list() for this ThreadsList.
+    log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads));
+  }
+
+  delete scan_table;
+}
+
+// Remove a JavaThread from a ThreadsList. The returned ThreadsList is a
+// new copy of the specified ThreadsList with the specified JavaThread
+// removed.
+ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thread) {
+  assert(list->_length > 0, "sanity");
+
+  uint i = 0;
+  DO_JAVA_THREADS(list, current) {
+    if (current == java_thread) {
+      break;
+    }
+    i++;
+  }
+  assert(i < list->_length, "did not find JavaThread on the list");
+  const uint index = i;
+  const uint new_length = list->_length - 1;
+  const uint head_length = index;
+  const uint tail_length = (new_length >= index) ? (new_length - index) : 0;
+  ThreadsList *const new_list = new ThreadsList(new_length);
+
+  if (head_length > 0) {
+    Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length);
+  }
+  if (tail_length > 0) {
+    Copy::disjoint_words((HeapWord*)list->_threads + index + 1, (HeapWord*)new_list->_threads + index, tail_length);
+  }
+
+  return new_list;
+}
+
+// Add a JavaThread to a ThreadsList. The returned ThreadsList is a
+// new copy of the specified ThreadsList with the specified JavaThread
+// appended to the end.
+ThreadsList *ThreadsList::add_thread(ThreadsList *list, JavaThread *java_thread) {
+  const uint index = list->_length;
+  const uint new_length = index + 1;
+  const uint head_length = index;
+  ThreadsList *const new_list = new ThreadsList(new_length);
+
+  if (head_length > 0) {
+    Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length);
+  }
+  *(JavaThread**)(new_list->_threads + index) = java_thread;
+
+  return new_list;
+}
+
+int ThreadsList::find_index_of_JavaThread(JavaThread *target) {
+  if (target == NULL) {
+    return -1;
+  }
+  for (uint i = 0; i < length(); i++) {
+    if (target == thread_at(i)) {
+      return (int)i;
+    }
+  }
+  return -1;
+}
+
+JavaThread* ThreadsList::find_JavaThread_from_java_tid(jlong java_tid) const {
+  DO_JAVA_THREADS(this, thread) {
+    oop tobj = thread->threadObj();
+    // Ignore the thread if it hasn't run yet, has exited
+    // or is starting to exit.
+    if (tobj != NULL && !thread->is_exiting() &&
+        java_tid == java_lang_Thread::thread_id(tobj)) {
+      // found a match
+      return thread;
+    }
+  }
+  return NULL;
+}
+
+bool ThreadsList::includes(const JavaThread * const p) const {
+  if (p == NULL) {
+    return false;
+  }
+  DO_JAVA_THREADS(this, q) {
+    if (q == p) {
+      return true;
+    }
+  }
+  return false;
+}
 
 void Threads::add(JavaThread* p, bool force_daemon) {
   // The threads lock must be owned at this point
@@ -4222,6 +5171,11 @@
   p->initialize_queues();
   p->set_next(_thread_list);
   _thread_list = p;
+
+  // Once a JavaThread is added to the Threads list, smr_delete() has
+  // to be used to delete it. Otherwise we can just delete it directly.
+  p->set_on_thread_list();
+
   _number_of_threads++;
   oop threadObj = p->threadObj();
   bool daemon = true;
@@ -4234,6 +5188,20 @@
 
   ThreadService::add_thread(p, daemon);
 
+  // Maintain fast thread list
+  ThreadsList *new_list = ThreadsList::add_thread(get_smr_java_thread_list(), p);
+  if (EnableThreadSMRStatistics) {
+    _smr_java_thread_list_alloc_cnt++;
+    if (new_list->length() > _smr_java_thread_list_max) {
+      _smr_java_thread_list_max = new_list->length();
+    }
+  }
+  // Initial _smr_java_thread_list will not generate a "Threads::add" mesg.
+  log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
+
+  ThreadsList *old_list = xchg_smr_java_thread_list(new_list);
+  smr_free_list(old_list);
+
   // Possible GC point.
   Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p));
 }
@@ -4247,7 +5215,20 @@
   // that we do not remove thread without safepoint code notice
   { MutexLocker ml(Threads_lock);
 
-    assert(includes(p), "p must be present");
+    assert(get_smr_java_thread_list()->includes(p), "p must be present");
+
+    // Maintain fast thread list
+    ThreadsList *new_list = ThreadsList::remove_thread(get_smr_java_thread_list(), p);
+    if (EnableThreadSMRStatistics) {
+      _smr_java_thread_list_alloc_cnt++;
+      // This list is smaller so no need to check for a "longest" update.
+    }
+
+    // Final _smr_java_thread_list will not generate a "Threads::remove" mesg.
+    log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
+
+    ThreadsList *old_list = xchg_smr_java_thread_list(new_list);
+    smr_free_list(old_list);
 
     JavaThread* current = _thread_list;
     JavaThread* prev    = NULL;
@@ -4262,6 +5243,7 @@
     } else {
       _thread_list = p->next();
     }
+
     _number_of_threads--;
     oop threadObj = p->threadObj();
     bool daemon = true;
@@ -4288,17 +5270,6 @@
   Events::log(p, "Thread exited: " INTPTR_FORMAT, p2i(p));
 }
 
-// Threads_lock must be held when this is called (or must be called during a safepoint)
-bool Threads::includes(JavaThread* p) {
-  assert(Threads_lock->is_locked(), "sanity check");
-  ALL_JAVA_THREADS(q) {
-    if (q == p) {
-      return true;
-    }
-  }
-  return false;
-}
-
 // Operations on the Threads list for GC.  These are not explicitly locked,
 // but the garbage collector must provide a safe context for them to run.
 // In particular, these things should never be called when the Threads_lock
@@ -4411,47 +5382,36 @@
 
 
 // Get count Java threads that are waiting to enter the specified monitor.
-GrowableArray<JavaThread*>* Threads::get_pending_threads(int count,
-                                                         address monitor,
-                                                         bool doLock) {
-  assert(doLock || SafepointSynchronize::is_at_safepoint(),
-         "must grab Threads_lock or be at safepoint");
+GrowableArray<JavaThread*>* Threads::get_pending_threads(ThreadsList * t_list,
+                                                         int count,
+                                                         address monitor) {
   GrowableArray<JavaThread*>* result = new GrowableArray<JavaThread*>(count);
 
   int i = 0;
-  {
-    MutexLockerEx ml(doLock ? Threads_lock : NULL);
-    ALL_JAVA_THREADS(p) {
-      if (!p->can_call_java()) continue;
-
-      address pending = (address)p->current_pending_monitor();
-      if (pending == monitor) {             // found a match
-        if (i < count) result->append(p);   // save the first count matches
-        i++;
-      }
+  DO_JAVA_THREADS(t_list, p) {
+    if (!p->can_call_java()) continue;
+
+    address pending = (address)p->current_pending_monitor();
+    if (pending == monitor) {             // found a match
+      if (i < count) result->append(p);   // save the first count matches
+      i++;
     }
   }
+
   return result;
 }
 
 
-JavaThread *Threads::owning_thread_from_monitor_owner(address owner,
-                                                      bool doLock) {
-  assert(doLock ||
-         Threads_lock->owned_by_self() ||
-         SafepointSynchronize::is_at_safepoint(),
-         "must grab Threads_lock or be at safepoint");
-
+JavaThread *Threads::owning_thread_from_monitor_owner(ThreadsList * t_list,
+                                                      address owner) {
   // NULL owner means not locked so we can skip the search
   if (owner == NULL) return NULL;
 
-  {
-    MutexLockerEx ml(doLock ? Threads_lock : NULL);
-    ALL_JAVA_THREADS(p) {
-      // first, see if owner is the address of a Java thread
-      if (owner == (address)p) return p;
-    }
-  }
+  DO_JAVA_THREADS(t_list, p) {
+    // first, see if owner is the address of a Java thread
+    if (owner == (address)p) return p;
+  }
+
   // Cannot assert on lack of success here since this function may be
   // used by code that is trying to report useful problem information
   // like deadlock detection.
@@ -4462,15 +5422,13 @@
   // Lock Word in the owning Java thread's stack.
   //
   JavaThread* the_owner = NULL;
-  {
-    MutexLockerEx ml(doLock ? Threads_lock : NULL);
-    ALL_JAVA_THREADS(q) {
-      if (q->is_lock_owned(owner)) {
-        the_owner = q;
-        break;
-      }
+  DO_JAVA_THREADS(t_list, q) {
+    if (q->is_lock_owned(owner)) {
+      the_owner = q;
+      break;
     }
   }
+
   // cannot assert on lack of success here; see above comment
   return the_owner;
 }
@@ -4495,6 +5453,9 @@
   }
 #endif // INCLUDE_SERVICES
 
+  print_smr_info_on(st);
+  st->cr();
+
   ALL_JAVA_THREADS(p) {
     ResourceMark rm;
     p->print_on(st);
@@ -4521,9 +5482,105 @@
     wt->print_on(st);
     st->cr();
   }
+
   st->flush();
 }
 
+// Log Threads class SMR info.
+void Threads::log_smr_statistics() {
+  LogTarget(Info, thread, smr) log;
+  if (log.is_enabled()) {
+    LogStream out(log);
+    print_smr_info_on(&out);
+  }
+}
+
+// Print Threads class SMR info.
+void Threads::print_smr_info_on(outputStream* st) {
+  // Only grab the Threads_lock if we don't already own it
+  // and if we are not reporting an error.
+  MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock);
+
+  st->print_cr("Threads class SMR info:");
+  st->print_cr("_smr_java_thread_list=" INTPTR_FORMAT ", length=%u, "
+               "elements={", p2i(_smr_java_thread_list),
+               _smr_java_thread_list->length());
+  print_smr_info_elements_on(st, _smr_java_thread_list);
+  st->print_cr("}");
+  if (_smr_to_delete_list != NULL) {
+    st->print_cr("_smr_to_delete_list=" INTPTR_FORMAT ", length=%u, "
+                 "elements={", p2i(_smr_to_delete_list),
+                 _smr_to_delete_list->length());
+    print_smr_info_elements_on(st, _smr_to_delete_list);
+    st->print_cr("}");
+    for (ThreadsList *t_list = _smr_to_delete_list->next_list();
+         t_list != NULL; t_list = t_list->next_list()) {
+      st->print("next-> " INTPTR_FORMAT ", length=%u, "
+                "elements={", p2i(t_list), t_list->length());
+      print_smr_info_elements_on(st, t_list);
+      st->print_cr("}");
+    }
+  }
+  if (!EnableThreadSMRStatistics) {
+    return;
+  }
+  st->print_cr("_smr_java_thread_list_alloc_cnt=" UINT64_FORMAT ","
+               "_smr_java_thread_list_free_cnt=" UINT64_FORMAT ","
+               "_smr_java_thread_list_max=%u, "
+               "_smr_nested_thread_list_max=%u",
+               _smr_java_thread_list_alloc_cnt,
+               _smr_java_thread_list_free_cnt,
+               _smr_java_thread_list_max,
+               _smr_nested_thread_list_max);
+  if (_smr_tlh_cnt > 0) {
+    st->print_cr("_smr_tlh_cnt=%u"
+                 ", _smr_tlh_times=%u"
+                 ", avg_smr_tlh_time=%0.2f"
+                 ", _smr_tlh_time_max=%u",
+                 _smr_tlh_cnt, _smr_tlh_times,
+                 ((double) _smr_tlh_times / _smr_tlh_cnt),
+                 _smr_tlh_time_max);
+  }
+  if (_smr_deleted_thread_cnt > 0) {
+    st->print_cr("_smr_deleted_thread_cnt=%u"
+                 ", _smr_deleted_thread_times=%u"
+                 ", avg_smr_deleted_thread_time=%0.2f"
+                 ", _smr_deleted_thread_time_max=%u",
+                 _smr_deleted_thread_cnt, _smr_deleted_thread_times,
+                 ((double) _smr_deleted_thread_times / _smr_deleted_thread_cnt),
+                 _smr_deleted_thread_time_max);
+  }
+  st->print_cr("_smr_delete_lock_wait_cnt=%u, _smr_delete_lock_wait_max=%u",
+               _smr_delete_lock_wait_cnt, _smr_delete_lock_wait_max);
+  st->print_cr("_smr_to_delete_list_cnt=%u, _smr_to_delete_list_max=%u",
+               _smr_to_delete_list_cnt, _smr_to_delete_list_max);
+}
+
+// Print ThreadsList elements (4 per line).
+void Threads::print_smr_info_elements_on(outputStream* st,
+                                         ThreadsList* t_list) {
+  uint cnt = 0;
+  JavaThreadIterator jti(t_list);
+  for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) {
+    st->print(INTPTR_FORMAT, p2i(jt));
+    if (cnt < t_list->length() - 1) {
+      // Separate with comma or comma-space except for the last one.
+      if (((cnt + 1) % 4) == 0) {
+        // Four INTPTR_FORMAT fit on an 80 column line so end the
+        // current line with just a comma.
+        st->print_cr(",");
+      } else {
+        // Not the last one on the current line so use comma-space:
+        st->print(", ");
+      }
+    } else {
+      // Last one so just end the current line.
+      st->cr();
+    }
+    cnt++;
+  }
+}
+
 void Threads::print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
                              int buflen, bool* found_current) {
   if (this_thread != NULL) {
@@ -4560,6 +5617,9 @@
 // memory (even in resource area), it might deadlock the error handler.
 void Threads::print_on_error(outputStream* st, Thread* current, char* buf,
                              int buflen) {
+  print_smr_info_on(st);
+  st->cr();
+
   bool found_current = false;
   st->print_cr("Java Threads: ( => current thread )");
   ALL_JAVA_THREADS(thread) {
@@ -4581,6 +5641,7 @@
     st->cr();
   }
   st->cr();
+
   st->print_cr("Threads with active compile tasks:");
   print_threads_compiling(st, buf, buflen);
 }
--- a/src/hotspot/share/runtime/thread.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/thread.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -57,6 +57,8 @@
 #endif
 
 class ThreadSafepointState;
+class ThreadsList;
+class NestedThreadsList;
 
 class JvmtiThreadState;
 class JvmtiGetLoadedClassesClosure;
@@ -101,6 +103,7 @@
 //   - WatcherThread
 
 class Thread: public ThreadShadow {
+  friend class Threads;
   friend class VMStructs;
   friend class JVMCIVMStructs;
  private:
@@ -118,6 +121,47 @@
  protected:
   // Support for forcing alignment of thread objects for biased locking
   void*       _real_malloc_address;
+  // JavaThread lifecycle support:
+  friend class ScanHazardPtrGatherProtectedThreadsClosure;
+  friend class ScanHazardPtrGatherThreadsListClosure;
+  friend class ScanHazardPtrPrintMatchingThreadsClosure;
+  friend class ThreadsListHandle;
+  friend class ThreadsListSetter;
+  ThreadsList* volatile _threads_hazard_ptr;
+  ThreadsList*          cmpxchg_threads_hazard_ptr(ThreadsList* exchange_value, ThreadsList* compare_value);
+  ThreadsList*          get_threads_hazard_ptr();
+  void                  set_threads_hazard_ptr(ThreadsList* new_list);
+  static bool           is_hazard_ptr_tagged(ThreadsList* list) {
+    return (intptr_t(list) & intptr_t(1)) == intptr_t(1);
+  }
+  static ThreadsList*   tag_hazard_ptr(ThreadsList* list) {
+    return (ThreadsList*)(intptr_t(list) | intptr_t(1));
+  }
+  static ThreadsList*   untag_hazard_ptr(ThreadsList* list) {
+    return (ThreadsList*)(intptr_t(list) & ~intptr_t(1));
+  }
+  NestedThreadsList* _nested_threads_hazard_ptr;
+  NestedThreadsList* get_nested_threads_hazard_ptr() {
+    return _nested_threads_hazard_ptr;
+  }
+  void set_nested_threads_hazard_ptr(NestedThreadsList* value) {
+    assert(Threads_lock->owned_by_self(),
+           "must own Threads_lock for _nested_threads_hazard_ptr to be valid.");
+    _nested_threads_hazard_ptr = value;
+  }
+  // This field is enabled via -XX:+EnableThreadSMRStatistics:
+  uint _nested_threads_hazard_ptr_cnt;
+  void dec_nested_threads_hazard_ptr_cnt() {
+    assert(_nested_threads_hazard_ptr_cnt != 0, "mismatched {dec,inc}_nested_threads_hazard_ptr_cnt()");
+    _nested_threads_hazard_ptr_cnt--;
+  }
+  void inc_nested_threads_hazard_ptr_cnt() {
+    _nested_threads_hazard_ptr_cnt++;
+  }
+  uint nested_threads_hazard_ptr_cnt() {
+    return _nested_threads_hazard_ptr_cnt;
+  }
+
  public:
   void* operator new(size_t size) throw() { return allocate(size, true); }
   void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
@@ -359,6 +403,9 @@
   static inline Thread* current_or_null_safe();
 
   // Common thread operations
+#ifdef ASSERT
+  static void check_for_dangling_thread_pointer(Thread *thread);
+#endif
   static void set_priority(Thread* thread, ThreadPriority priority);
   static ThreadPriority get_priority(const Thread* const thread);
   static void start(Thread* thread);
@@ -576,6 +623,7 @@
 
   // Printing
   virtual void print_on(outputStream* st) const;
+  virtual void print_nested_threads_hazard_ptrs_on(outputStream* st) const;
   void print() const { print_on(tty); }
   virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
   void print_value_on(outputStream* st) const;
@@ -798,6 +846,7 @@
   friend class WhiteBox;
  private:
   JavaThread*    _next;                          // The next thread in the Threads list
+  bool           _on_thread_list;                // Is set when this JavaThread is added to the Threads list
   oop            _threadObj;                     // The Java level thread object
 
 #ifdef ASSERT
@@ -1125,15 +1174,23 @@
   void set_safepoint_state(ThreadSafepointState *state) { _safepoint_state = state; }
   bool is_at_poll_safepoint()                    { return _safepoint_state->is_at_poll_safepoint(); }
 
+  // JavaThread termination and lifecycle support:
+  void smr_delete();
+  bool on_thread_list() const { return _on_thread_list; }
+  void set_on_thread_list() { _on_thread_list = true; }
+
   // thread has called JavaThread::exit() or is terminated
-  bool is_exiting()                              { return _terminated == _thread_exiting || is_terminated(); }
+  bool is_exiting() const;
   // thread is terminated (no longer on the threads list); we compare
   // against the two non-terminated values so that a freed JavaThread
   // will also be considered terminated.
-  bool is_terminated()                           { return _terminated != _not_terminated && _terminated != _thread_exiting; }
-  void set_terminated(TerminatedTypes t)         { _terminated = t; }
+  bool check_is_terminated(TerminatedTypes l_terminated) const {
+    return l_terminated != _not_terminated && l_terminated != _thread_exiting;
+  }
+  bool is_terminated() const;
+  void set_terminated(TerminatedTypes t);
   // special for Threads::remove() which is static:
-  void set_terminated_value()                    { _terminated = _thread_terminated; }
+  void set_terminated_value();
   void block_if_vm_exited();
 
   bool doing_unsafe_access()                     { return _doing_unsafe_access; }
@@ -1220,6 +1277,9 @@
   // via the appropriate -XX options.
   bool wait_for_ext_suspend_completion(int count, int delay, uint32_t *bits);
 
+  // test for suspend - most (all?) of these should go away
+  bool is_thread_fully_suspended(bool wait_for_suspend, uint32_t *bits);
+
   inline void set_external_suspend();
   inline void clear_external_suspend();
 
@@ -2066,28 +2126,84 @@
 class Threads: AllStatic {
   friend class VMStructs;
  private:
-  static JavaThread* _thread_list;
-  static int         _number_of_threads;
-  static int         _number_of_non_daemon_threads;
-  static int         _return_code;
-  static int         _thread_claim_parity;
+  // Safe Memory Reclamation (SMR) support:
+  // The coordination between Threads::release_stable_list() and
+  // Threads::smr_delete() uses the smr_delete_lock in order to
+  // reduce the traffic on the Threads_lock.
+  static Monitor*              _smr_delete_lock;
+  // The '_cnt', '_max' and '_times" fields are enabled via
+  // -XX:+EnableThreadSMRStatistics (see thread.cpp for a
+  // description about each field):
+  static uint                  _smr_delete_lock_wait_cnt;
+  static uint                  _smr_delete_lock_wait_max;
+  // The smr_delete_notify flag is used for proper double-check
+  // locking in order to reduce the traffic on the smr_delete_lock.
+  static volatile uint         _smr_delete_notify;
+  static volatile uint         _smr_deleted_thread_cnt;
+  static volatile uint         _smr_deleted_thread_time_max;
+  static volatile uint         _smr_deleted_thread_times;
+  static ThreadsList* volatile _smr_java_thread_list;
+  static uint64_t              _smr_java_thread_list_alloc_cnt;
+  static uint64_t              _smr_java_thread_list_free_cnt;
+  static uint                  _smr_java_thread_list_max;
+  static uint                  _smr_nested_thread_list_max;
+  static volatile uint         _smr_tlh_cnt;
+  static volatile uint         _smr_tlh_time_max;
+  static volatile uint         _smr_tlh_times;
+  static ThreadsList*          _smr_to_delete_list;
+  static uint                  _smr_to_delete_list_cnt;
+  static uint                  _smr_to_delete_list_max;
+
+  static JavaThread*           _thread_list;
+  static int                   _number_of_threads;
+  static int                   _number_of_non_daemon_threads;
+  static int                   _return_code;
+  static int                   _thread_claim_parity;
 #ifdef ASSERT
-  static bool        _vm_complete;
+  static bool                  _vm_complete;
 #endif
 
   static void initialize_java_lang_classes(JavaThread* main_thread, TRAPS);
   static void initialize_jsr292_core_classes(TRAPS);
+
+  static ThreadsList *acquire_stable_list_fast_path(Thread *self);
+  static ThreadsList *acquire_stable_list_nested_path(Thread *self);
+  static void add_smr_deleted_thread_times(uint add_value);
+  static void clear_smr_delete_notify();
+  static ThreadsList* get_smr_java_thread_list();
+  static void inc_smr_deleted_thread_cnt();
+  static void release_stable_list_fast_path(Thread *self);
+  static void release_stable_list_nested_path(Thread *self);
+  static void release_stable_list_wake_up(char *log_str);
+  static void set_smr_delete_notify();
+  static Monitor* smr_delete_lock() { return _smr_delete_lock; }
+  static bool smr_delete_notify();
+  static void smr_free_list(ThreadsList* threads);
+  static void update_smr_deleted_thread_time_max(uint new_value);
+  static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list);
+
  public:
   // Thread management
   // force_daemon is a concession to JNI, where we may need to add a
   // thread to the thread list before allocating its thread object
   static void add(JavaThread* p, bool force_daemon = false);
   static void remove(JavaThread* p);
-  static bool includes(JavaThread* p);
-  static JavaThread* first()                     { return _thread_list; }
   static void threads_do(ThreadClosure* tc);
   static void possibly_parallel_threads_do(bool is_par, ThreadClosure* tc);
 
+  // SMR support:
+  static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter);
+  static void release_stable_list(Thread *self);
+  static bool is_a_protected_JavaThread(JavaThread *thread);
+  static bool is_a_protected_JavaThread_with_lock(JavaThread *thread) {
+    MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock);
+    return is_a_protected_JavaThread(thread);
+  }
+  static void smr_delete(JavaThread *thread);
+  static void inc_smr_tlh_cnt();
+  static void update_smr_tlh_time_max(uint new_value);
+  static void add_smr_tlh_times(uint add_value);
+
   // Initializes the vm and creates the vm thread
   static jint create_vm(JavaVMInitArgs* args, bool* canTryAgain);
   static void convert_vm_init_libraries_to_agents();
@@ -2148,7 +2264,10 @@
 
   // Verification
   static void verify();
+  static void log_smr_statistics();
   static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks);
+  static void print_smr_info_on(outputStream* st);
+  static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list);
   static void print(bool print_stacks, bool internal_format) {
     // this function is only used by debug.cpp
     print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
@@ -2158,17 +2277,13 @@
                              int buflen, bool* found_current);
   static void print_threads_compiling(outputStream* st, char* buf, int buflen);
 
-  // Get Java threads that are waiting to enter a monitor. If doLock
-  // is true, then Threads_lock is grabbed as needed. Otherwise, the
-  // VM needs to be at a safepoint.
-  static GrowableArray<JavaThread*>* get_pending_threads(int count,
-                                                         address monitor, bool doLock);
+  // Get Java threads that are waiting to enter a monitor.
+  static GrowableArray<JavaThread*>* get_pending_threads(ThreadsList * t_list,
+                                                         int count, address monitor);
 
-  // Get owning Java thread from the monitor's owner field. If doLock
-  // is true, then Threads_lock is grabbed as needed. Otherwise, the
-  // VM needs to be at a safepoint.
-  static JavaThread *owning_thread_from_monitor_owner(address owner,
-                                                      bool doLock);
+  // Get owning Java thread from the monitor's owner field.
+  static JavaThread *owning_thread_from_monitor_owner(ThreadsList * t_list,
+                                                      address owner);
 
   // Number of threads on the active threads list
   static int number_of_threads()                 { return _number_of_threads; }
@@ -2177,9 +2292,6 @@
 
   // Deoptimizes all frames tied to marked nmethods
   static void deoptimized_wrt_marked_nmethods();
-
-  static JavaThread* find_java_thread_from_java_tid(jlong java_tid);
-
 };
 
 
--- a/src/hotspot/share/runtime/thread.inline.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/thread.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,13 +25,10 @@
 #ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP
 #define SHARE_VM_RUNTIME_THREAD_INLINE_HPP
 
-#define SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
-
 #include "runtime/atomic.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/thread.hpp"
-
-#undef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+#include "runtime/threadSMR.hpp"
 
 inline void Thread::set_suspend_flag(SuspendFlags f) {
   assert(sizeof(jint) == sizeof(_suspend_flags), "size mismatch");
@@ -89,6 +86,18 @@
   return allocated_bytes;
 }
 
+inline ThreadsList* Thread::cmpxchg_threads_hazard_ptr(ThreadsList* exchange_value, ThreadsList* compare_value) {
+  return (ThreadsList*)Atomic::cmpxchg(exchange_value, &_threads_hazard_ptr, compare_value);
+}
+
+inline ThreadsList* Thread::get_threads_hazard_ptr() {
+  return (ThreadsList*)OrderAccess::load_acquire(&_threads_hazard_ptr);
+}
+
+inline void Thread::set_threads_hazard_ptr(ThreadsList* new_list) {
+  OrderAccess::release_store_fence(&_threads_hazard_ptr, new_list);
+}
+
 inline void JavaThread::set_ext_suspended() {
   set_suspend_flag (_ext_suspended);
 }
@@ -176,4 +185,53 @@
   return OrderAccess::load_acquire(polling_page_addr());
 }
 
+inline bool JavaThread::is_exiting() const {
+  // Use load-acquire so that setting of _terminated by
+  // JavaThread::exit() is seen more quickly.
+  TerminatedTypes l_terminated = (TerminatedTypes)
+      OrderAccess::load_acquire((volatile jint *) &_terminated);
+  return l_terminated == _thread_exiting || check_is_terminated(l_terminated);
+}
+
+inline bool JavaThread::is_terminated() const {
+  // Use load-acquire so that setting of _terminated by
+  // JavaThread::exit() is seen more quickly.
+  TerminatedTypes l_terminated = (TerminatedTypes)
+      OrderAccess::load_acquire((volatile jint *) &_terminated);
+  return check_is_terminated(l_terminated);
+}
+
+inline void JavaThread::set_terminated(TerminatedTypes t) {
+  // use release-store so the setting of _terminated is seen more quickly
+  OrderAccess::release_store((volatile jint *) &_terminated, (jint) t);
+}
+
+// special for Threads::remove() which is static:
+inline void JavaThread::set_terminated_value() {
+  // use release-store so the setting of _terminated is seen more quickly
+  OrderAccess::release_store((volatile jint *) &_terminated, (jint) _thread_terminated);
+}
+
+inline void Threads::add_smr_tlh_times(uint add_value) {
+  Atomic::add(add_value, &_smr_tlh_times);
+}
+
+inline void Threads::inc_smr_tlh_cnt() {
+  Atomic::inc(&_smr_tlh_cnt);
+}
+
+inline void Threads::update_smr_tlh_time_max(uint new_value) {
+  while (true) {
+    uint cur_value = _smr_tlh_time_max;
+    if (new_value <= cur_value) {
+      // No need to update max value so we're done.
+      break;
+    }
+    if (Atomic::cmpxchg(new_value, &_smr_tlh_time_max, cur_value) == cur_value) {
+      // Updated max value so we're done. Otherwise try it all again.
+      break;
+    }
+  }
+}
+
 #endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/threadSMR.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
+#include "services/threadService.hpp"
+
+// 'entries + 1' so we always have at least one entry.
+ThreadsList::ThreadsList(int entries) : _length(entries), _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), _next_list(NULL) {
+  *(JavaThread**)(_threads + entries) = NULL;  // Make sure the extra entry is NULL.
+}
+
+ThreadsList::~ThreadsList() {
+  FREE_C_HEAP_ARRAY(JavaThread*, _threads);
+}
+
+ThreadsListSetter::~ThreadsListSetter() {
+  if (_target_needs_release) {
+    // The hazard ptr in the target needs to be released.
+    Threads::release_stable_list(_target);
+  }
+}
+
+void ThreadsListSetter::set() {
+  assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set");
+  (void) Threads::acquire_stable_list(_target, /* is_ThreadsListSetter */ true);
+  _target_needs_release = true;
+}
+
+ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(Threads::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) {
+  assert(self == Thread::current(), "sanity check");
+  if (EnableThreadSMRStatistics) {
+    _timer.start();
+  }
+}
+
+ThreadsListHandle::~ThreadsListHandle() {
+  Threads::release_stable_list(_self);
+  if (EnableThreadSMRStatistics) {
+    _timer.stop();
+    uint millis = (uint)_timer.milliseconds();
+    Threads::inc_smr_tlh_cnt();
+    Threads::add_smr_tlh_times(millis);
+    Threads::update_smr_tlh_time_max(millis);
+  }
+}
+
+// Convert an internal thread reference to a JavaThread found on the
+// associated ThreadsList. This ThreadsListHandle "protects" the
+// returned JavaThread *.
+//
+// If thread_oop_p is not NULL, then the caller wants to use the oop
+// after this call so the oop is returned. On success, *jt_pp is set
+// to the converted JavaThread * and true is returned. On error,
+// returns false.
+//
+bool ThreadsListHandle::cv_internal_thread_to_JavaThread(jobject jthread,
+                                                         JavaThread ** jt_pp,
+                                                         oop * thread_oop_p) {
+  assert(this->list() != NULL, "must have a ThreadsList");
+  assert(jt_pp != NULL, "must have a return JavaThread pointer");
+  // thread_oop_p is optional so no assert()
+
+  // The JVM_* interfaces don't allow a NULL thread parameter; JVM/TI
+  // allows a NULL thread parameter to signify "current thread" which
+  // allows us to avoid calling cv_external_thread_to_JavaThread().
+  // The JVM_* interfaces have no such leeway.
+
+  oop thread_oop = JNIHandles::resolve_non_null(jthread);
+  // Looks like an oop at this point.
+  if (thread_oop_p != NULL) {
+    // Return the oop to the caller; the caller may still want
+    // the oop even if this function returns false.
+    *thread_oop_p = thread_oop;
+  }
+
+  JavaThread *java_thread = java_lang_Thread::thread(thread_oop);
+  if (java_thread == NULL) {
+    // The java.lang.Thread does not contain a JavaThread * so it has
+    // not yet run or it has died.
+    return false;
+  }
+  // Looks like a live JavaThread at this point.
+
+  if (java_thread != JavaThread::current()) {
+    // jthread is not for the current JavaThread so have to verify
+    // the JavaThread * against the ThreadsList.
+    if (EnableThreadSMRExtraValidityChecks && !includes(java_thread)) {
+      // Not on the JavaThreads list so it is not alive.
+      return false;
+    }
+  }
+
+  // Return a live JavaThread that is "protected" by the
+  // ThreadsListHandle in the caller.
+  *jt_pp = java_thread;
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/threadSMR.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_THREADSMR_HPP
+#define SHARE_VM_RUNTIME_THREADSMR_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/timer.hpp"
+
+// Thread Safe Memory Reclamation (Thread-SMR) support.
+//
+// ThreadsListHandles are used to safely perform operations on one or more
+// threads without the risk of the thread or threads exiting during the
+// operation. It is no longer necessary to hold the Threads_lock to safely
+// perform an operation on a target thread.
+//
+// There are several different ways to refer to java.lang.Thread objects
+// so we have a few ways to get a protected JavaThread *:
+//
+// JNI jobject example:
+//   jobject jthread = ...;
+//   :
+//   ThreadsListHandle tlh;
+//   JavaThread* jt = NULL;
+//   bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, NULL);
+//   if (is_alive) {
+//     :  // do stuff with 'jt'...
+//   }
+//
+// JVM/TI jthread example:
+//   jthread thread = ...;
+//   :
+//   JavaThread* jt = NULL;
+//   ThreadsListHandle tlh;
+//   jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &jt, NULL);
+//   if (err != JVMTI_ERROR_NONE) {
+//     return err;
+//   }
+//   :  // do stuff with 'jt'...
+//
+// JVM/TI oop example (this one should be very rare):
+//   oop thread_obj = ...;
+//   :
+//   JavaThread *jt = NULL;
+//   ThreadsListHandle tlh;
+//   jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt);
+//   if (err != JVMTI_ERROR_NONE) {
+//     return err;
+//   }
+//   :  // do stuff with 'jt'...
+//
+// A JavaThread * that is included in the ThreadsList that is held by
+// a ThreadsListHandle is protected as long as the ThreadsListHandle
+// remains in scope. The target JavaThread * may have logically exited,
+// but that target JavaThread * will not be deleted until it is no
+// longer protected by a ThreadsListHandle.
+
+
+// A fast list of JavaThreads.
+//
+class ThreadsList : public CHeapObj<mtThread> {
+  friend class ScanHazardPtrGatherProtectedThreadsClosure;
+  friend class Threads;
+
+  const uint _length;
+  ThreadsList* _next_list;
+  JavaThread *const *const _threads;
+
+  template <class T>
+  void threads_do_dispatch(T *cl, JavaThread *const thread) const;
+
+  ThreadsList *next_list() const        { return _next_list; }
+  void set_next_list(ThreadsList *list) { _next_list = list; }
+
+public:
+  ThreadsList(int entries);
+  ~ThreadsList();
+
+  template <class T>
+  void threads_do(T *cl) const;
+
+  uint length() const                       { return _length; }
+
+  JavaThread *const thread_at(uint i) const { return _threads[i]; }
+
+  JavaThread *const *threads() const        { return _threads; }
+
+  // Returns -1 if target is not found.
+  int find_index_of_JavaThread(JavaThread* target);
+  JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const;
+  bool includes(const JavaThread * const p) const;
+
+  static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
+  static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
+};
+
+// Linked list of ThreadsLists to support nested ThreadsListHandles.
+class NestedThreadsList : public CHeapObj<mtThread> {
+  ThreadsList*const _t_list;
+  NestedThreadsList* _next;
+
+public:
+  NestedThreadsList(ThreadsList* t_list) : _t_list(t_list) {
+    assert(Threads_lock->owned_by_self(),
+           "must own Threads_lock for saved t_list to be valid.");
+  }
+
+  ThreadsList* t_list() { return _t_list; }
+  NestedThreadsList* next() { return _next; }
+  void set_next(NestedThreadsList* value) { _next = value; }
+};
+
+// A helper to optionally set the hazard ptr in ourself. This helper can
+// be used by ourself or by another thread. If the hazard ptr is set(),
+// then the destructor will release it.
+//
+class ThreadsListSetter : public StackObj {
+private:
+  bool _target_needs_release;  // needs release only when set()
+  Thread * _target;
+
+public:
+  ThreadsListSetter() : _target_needs_release(false), _target(Thread::current()) {
+  }
+  ~ThreadsListSetter();
+  ThreadsList* list();
+  void set();
+  bool target_needs_release() { return _target_needs_release; }
+};
+
+// This stack allocated ThreadsListHandle keeps all JavaThreads in the
+// ThreadsList from being deleted until it is safe.
+//
+class ThreadsListHandle : public StackObj {
+  ThreadsList * _list;
+  Thread *const _self;
+  elapsedTimer _timer;  // Enabled via -XX:+EnableThreadSMRStatistics.
+
+public:
+  ThreadsListHandle(Thread *self = Thread::current());
+  ~ThreadsListHandle();
+
+  ThreadsList *list() const {
+    return _list;
+  }
+
+  template <class T>
+  void threads_do(T *cl) const {
+    return _list->threads_do(cl);
+  }
+
+  bool cv_internal_thread_to_JavaThread(jobject jthread, JavaThread ** jt_pp, oop * thread_oop_p);
+
+  bool includes(JavaThread* p) {
+    return _list->includes(p);
+  }
+
+  uint length() const {
+    return _list->length();
+  }
+};
+
+// This stack allocated JavaThreadIterator is used to walk the
+// specified ThreadsList using the following style:
+//
+//   JavaThreadIterator jti(t_list);
+//   for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) {
+//     ...
+//   }
+//
+class JavaThreadIterator : public StackObj {
+  ThreadsList * _list;
+  uint _index;
+
+public:
+  JavaThreadIterator(ThreadsList *list) : _list(list), _index(0) {
+    assert(list != NULL, "ThreadsList must not be NULL.");
+  }
+
+  JavaThread *first() {
+    _index = 0;
+    return _list->thread_at(_index);
+  }
+
+  uint length() const {
+    return _list->length();
+  }
+
+  ThreadsList *list() const {
+    return _list;
+  }
+
+  JavaThread *next() {
+    if (++_index >= length()) {
+      return NULL;
+    }
+    return _list->thread_at(_index);
+  }
+};
+
+// This stack allocated ThreadsListHandle and JavaThreadIterator combo
+// is used to walk the ThreadsList in the included ThreadsListHandle
+// using the following style:
+//
+//   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
+//     ...
+//   }
+//
+class JavaThreadIteratorWithHandle : public StackObj {
+  ThreadsListHandle _tlh;
+  uint _index;
+
+public:
+  JavaThreadIteratorWithHandle() : _index(0) {}
+
+  uint length() const {
+    return _tlh.length();
+  }
+
+  ThreadsList *list() const {
+    return _tlh.list();
+  }
+
+  JavaThread *next() {
+    if (_index >= length()) {
+      return NULL;
+    }
+    return _tlh.list()->thread_at(_index++);
+  }
+
+  void rewind() {
+    _index = 0;
+  }
+};
+
+#endif // SHARE_VM_RUNTIME_THREADSMR_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/threadSMR.inline.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP
+#define SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP
+
+#include "runtime/atomic.hpp"
+#include "runtime/prefetch.inline.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
+
+// Devirtualize known thread closure types.
+template <class T>
+inline void ThreadsList::threads_do_dispatch(T *cl, JavaThread *const thread) const {
+  cl->T::do_thread(thread);
+}
+
+template <>
+inline void ThreadsList::threads_do_dispatch<ThreadClosure>(ThreadClosure *cl, JavaThread *const thread) const {
+  cl->do_thread(thread);
+}
+
+template <class T>
+inline void ThreadsList::threads_do(T *cl) const {
+  const intx scan_interval = PrefetchScanIntervalInBytes;
+  JavaThread *const *const end = _threads + _length;
+  for (JavaThread *const *current_p = _threads; current_p != end; current_p++) {
+    Prefetch::read((void*)current_p, scan_interval);
+    JavaThread *const current = *current_p;
+    threads_do_dispatch(cl, current);
+  }
+}
+
+inline ThreadsList* ThreadsListSetter::list() {
+  ThreadsList *ret = _target->get_threads_hazard_ptr();
+  assert(ret != NULL, "hazard ptr should be set");
+  assert(!Thread::is_hazard_ptr_tagged(ret), "hazard ptr should be validated");
+  return ret;
+}
+
+#endif // SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP
--- a/src/hotspot/share/runtime/vmStructs.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -830,7 +830,7 @@
   nonstatic_field(nmethod,                     _osr_link,                                     nmethod*)                              \
   nonstatic_field(nmethod,                     _scavenge_root_link,                           nmethod*)                              \
   nonstatic_field(nmethod,                     _scavenge_root_state,                          jbyte)                                 \
-  nonstatic_field(nmethod,                     _state,                                        volatile char)                         \
+  nonstatic_field(nmethod,                     _state,                                        volatile signed char)                         \
   nonstatic_field(nmethod,                     _exception_offset,                             int)                                   \
   nonstatic_field(nmethod,                     _orig_pc_offset,                               int)                                   \
   nonstatic_field(nmethod,                     _stub_offset,                                  int)                                   \
@@ -1350,8 +1350,8 @@
   declare_integer_type(int)                                               \
   declare_integer_type(long)                                              \
   declare_integer_type(char)                                              \
+  declare_integer_type(volatile signed char)                              \
   declare_unsigned_integer_type(unsigned char)                            \
-  declare_unsigned_integer_type(volatile char)                            \
   declare_unsigned_integer_type(u_char)                                   \
   declare_unsigned_integer_type(unsigned int)                             \
   declare_unsigned_integer_type(uint)                                     \
@@ -1534,6 +1534,7 @@
   declare_toplevel_type(PerfDataPrologue*)                                \
   declare_toplevel_type(PerfDataEntry)                                    \
   declare_toplevel_type(PerfMemory)                                       \
+  declare_type(PerfData, CHeapObj<mtInternal>)                            \
                                                                           \
   /*********************************/                                     \
   /* SymbolTable, SystemDictionary */                                     \
@@ -1958,6 +1959,7 @@
   declare_c2_type(NegFNode, NegNode)                                      \
   declare_c2_type(NegDNode, NegNode)                                      \
   declare_c2_type(AtanDNode, Node)                                        \
+  declare_c2_type(SqrtFNode, Node)                                        \
   declare_c2_type(SqrtDNode, Node)                                        \
   declare_c2_type(ReverseBytesINode, Node)                                \
   declare_c2_type(ReverseBytesLNode, Node)                                \
@@ -2480,6 +2482,12 @@
   declare_constant(InstanceKlass::inner_class_access_flags_offset)        \
   declare_constant(InstanceKlass::inner_class_next_offset)                \
                                                                           \
+  /*****************************************************/                 \
+  /* InstanceKlass EnclosingMethodAttributeOffset enum */                 \
+  /*****************************************************/                 \
+                                                                          \
+  declare_constant(InstanceKlass::enclosing_method_attribute_size)        \
+                                                                          \
   /*********************************/                                     \
   /* InstanceKlass ClassState enum */                                     \
   /*********************************/                                     \
@@ -2635,6 +2643,46 @@
   declare_constant(Deoptimization::_reason_shift)                         \
   declare_constant(Deoptimization::_debug_id_shift)                       \
                                                                           \
+  /******************************************/                            \
+  /* BasicType enum (globalDefinitions.hpp) */                            \
+  /******************************************/                            \
+                                                                          \
+  declare_constant(T_BOOLEAN)                                             \
+  declare_constant(T_CHAR)                                                \
+  declare_constant(T_FLOAT)                                               \
+  declare_constant(T_DOUBLE)                                              \
+  declare_constant(T_BYTE)                                                \
+  declare_constant(T_SHORT)                                               \
+  declare_constant(T_INT)                                                 \
+  declare_constant(T_LONG)                                                \
+  declare_constant(T_OBJECT)                                              \
+  declare_constant(T_ARRAY)                                               \
+  declare_constant(T_VOID)                                                \
+  declare_constant(T_ADDRESS)                                             \
+  declare_constant(T_NARROWOOP)                                           \
+  declare_constant(T_METADATA)                                            \
+  declare_constant(T_NARROWKLASS)                                         \
+  declare_constant(T_CONFLICT)                                            \
+  declare_constant(T_ILLEGAL)                                             \
+                                                                          \
+  /**********************************************/                        \
+  /* BasicTypeSize enum (globalDefinitions.hpp) */                        \
+  /**********************************************/                        \
+                                                                          \
+  declare_constant(T_BOOLEAN_size)                                        \
+  declare_constant(T_CHAR_size)                                           \
+  declare_constant(T_FLOAT_size)                                          \
+  declare_constant(T_DOUBLE_size)                                         \
+  declare_constant(T_BYTE_size)                                           \
+  declare_constant(T_SHORT_size)                                          \
+  declare_constant(T_INT_size)                                            \
+  declare_constant(T_LONG_size)                                           \
+  declare_constant(T_OBJECT_size)                                         \
+  declare_constant(T_ARRAY_size)                                          \
+  declare_constant(T_NARROWOOP_size)                                      \
+  declare_constant(T_NARROWKLASS_size)                                    \
+  declare_constant(T_VOID_size)                                           \
+                                                                          \
   /*********************/                                                 \
   /* Matcher (C2 only) */                                                 \
   /*********************/                                                 \
@@ -2733,6 +2781,21 @@
   declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \
   declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT) \
                                                                           \
+  /************/                                                          \
+  /* PerfData */                                                          \
+  /************/                                                          \
+                                                                          \
+  /***********************/                                               \
+  /* PerfData Units enum */                                               \
+  /***********************/                                               \
+                                                                          \
+  declare_constant(PerfData::U_None)                                      \
+  declare_constant(PerfData::U_Bytes)                                     \
+  declare_constant(PerfData::U_Ticks)                                     \
+  declare_constant(PerfData::U_Events)                                    \
+  declare_constant(PerfData::U_String)                                    \
+  declare_constant(PerfData::U_Hertz)                                     \
+                                                                          \
   /****************/                                                      \
   /* JVMCI */                                                             \
   /****************/                                                      \
--- a/src/hotspot/share/runtime/vm_operations.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/vm_operations.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/sweeper.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.inline.hpp"
 #include "runtime/vm_operations.hpp"
 #include "services/threadService.hpp"
 #include "trace/tracing.hpp"
@@ -96,11 +97,12 @@
 
 void VM_ThreadStop::doit() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
+  ThreadsListHandle tlh;
   JavaThread* target = java_lang_Thread::thread(target_thread());
   // Note that this now allows multiple ThreadDeath exceptions to be
   // thrown at a thread.
-  if (target != NULL) {
-    // the thread has run and is not already in the process of exiting
+  if (target != NULL && (!EnableThreadSMRExtraValidityChecks || tlh.includes(target))) {
+    // The target thread has run and has not exited yet.
     target->send_thread_stop(throwable());
   }
 }
@@ -146,9 +148,10 @@
 
 void VM_DeoptimizeAll::doit() {
   DeoptimizationMarker dm;
+  JavaThreadIteratorWithHandle jtiwh;
   // deoptimize all java threads in the system
   if (DeoptimizeALot) {
-    for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
+    for (; JavaThread *thread = jtiwh.next(); ) {
       if (thread->has_last_Java_frame()) {
         thread->deoptimize();
       }
@@ -159,7 +162,7 @@
     int tnum = os::random() & 0x3;
     int fnum =  os::random() & 0x3;
     int tcount = 0;
-    for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
+    for (; JavaThread *thread = jtiwh.next(); ) {
       if (thread->has_last_Java_frame()) {
         if (tcount++ == tnum)  {
         tcount = 0;
@@ -259,12 +262,19 @@
 }
 
 void VM_FindDeadlocks::doit() {
-  _deadlocks = ThreadService::find_deadlocks_at_safepoint(_concurrent_locks);
+  // Update the hazard ptr in the originating thread to the current
+  // list of threads. This VM operation needs the current list of
+  // threads for proper deadlock detection and those are the
+  // JavaThreads we need to be protected when we return info to the
+  // originating thread.
+  _setter.set();
+
+  _deadlocks = ThreadService::find_deadlocks_at_safepoint(_setter.list(), _concurrent_locks);
   if (_out != NULL) {
     int num_deadlocks = 0;
     for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) {
       num_deadlocks++;
-      cycle->print_on(_out);
+      cycle->print_on_with(_setter.list(), _out);
     }
 
     if (num_deadlocks == 1) {
@@ -331,6 +341,12 @@
 void VM_ThreadDump::doit() {
   ResourceMark rm;
 
+  // Set the hazard ptr in the originating thread to protect the
+  // current list of threads. This VM operation needs the current list
+  // of threads for a proper dump and those are the JavaThreads we need
+  // to be protected when we return info to the originating thread.
+  _result->set_t_list();
+
   ConcurrentLocksDump concurrent_locks(true);
   if (_with_locked_synchronizers) {
     concurrent_locks.dump_at_safepoint();
@@ -338,7 +354,9 @@
 
   if (_num_threads == 0) {
     // Snapshot all live threads
-    for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
+
+    for (uint i = 0; i < _result->t_list()->length(); i++) {
+      JavaThread* jt = _result->t_list()->thread_at(i);
       if (jt->is_exiting() ||
           jt->is_hidden_from_external_view())  {
         // skip terminating threads and hidden threads
@@ -354,6 +372,7 @@
   } else {
     // Snapshot threads in the given _threads array
     // A dummy snapshot is created if a thread doesn't exist
+
     for (int i = 0; i < _num_threads; i++) {
       instanceHandle th = _threads->at(i);
       if (th() == NULL) {
@@ -366,6 +385,12 @@
       // Dump thread stack only if the thread is alive and not exiting
       // and not VM internal thread.
       JavaThread* jt = java_lang_Thread::thread(th());
+      if (jt != NULL && !_result->t_list()->includes(jt)) {
+        // _threads[i] doesn't refer to a valid JavaThread; this check
+        // is primarily for JVM_DumpThreads() which doesn't have a good
+        // way to validate the _threads array.
+        jt = NULL;
+      }
       if (jt == NULL || /* thread not alive */
           jt->is_exiting() ||
           jt->is_hidden_from_external_view())  {
@@ -384,7 +409,7 @@
 }
 
 ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) {
-  ThreadSnapshot* snapshot = new ThreadSnapshot(java_thread);
+  ThreadSnapshot* snapshot = new ThreadSnapshot(_result->t_list(), java_thread);
   snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors);
   snapshot->set_concurrent_locks(tcl);
   return snapshot;
@@ -403,11 +428,12 @@
 
   _shutdown_thread = thr_cur;
   _vm_exited = true;                                // global flag
-  for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next())
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
     if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
       ++num_active;
       thr->set_terminated(JavaThread::_vm_exited);  // per-thread flag
     }
+  }
 
   return num_active;
 }
@@ -435,11 +461,13 @@
   int max_wait = max_wait_compiler_thread;
 
   int attempts = 0;
+  JavaThreadIteratorWithHandle jtiwh;
   while (true) {
     int num_active = 0;
     int num_active_compiler_thread = 0;
 
-    for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) {
+    jtiwh.rewind();
+    for (; JavaThread *thr = jtiwh.next(); ) {
       if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
         num_active++;
         if (thr->is_Compiler_thread()) {
--- a/src/hotspot/share/runtime/vm_operations.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/runtime/vm_operations.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -392,12 +392,14 @@
 class DeadlockCycle;
 class VM_FindDeadlocks: public VM_Operation {
  private:
-  bool           _concurrent_locks;
-  DeadlockCycle* _deadlocks;
-  outputStream*  _out;
+  bool              _concurrent_locks;
+  DeadlockCycle*    _deadlocks;
+  outputStream*     _out;
+  ThreadsListSetter _setter;  // Helper to set hazard ptr in the originating thread
+                              // which protects the JavaThreads in _deadlocks.
 
  public:
-  VM_FindDeadlocks(bool concurrent_locks) :  _concurrent_locks(concurrent_locks), _out(NULL), _deadlocks(NULL) {};
+  VM_FindDeadlocks(bool concurrent_locks) :  _concurrent_locks(concurrent_locks), _out(NULL), _deadlocks(NULL), _setter() {};
   VM_FindDeadlocks(outputStream* st) : _concurrent_locks(true), _out(st), _deadlocks(NULL) {};
   ~VM_FindDeadlocks();
 
--- a/src/hotspot/share/services/diagnosticArgument.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/diagnosticArgument.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,29 @@
 #include "runtime/thread.hpp"
 #include "services/diagnosticArgument.hpp"
 
+StringArrayArgument::StringArrayArgument() {
+  _array = new(ResourceObj::C_HEAP, mtInternal)GrowableArray<char *>(32, true);
+  assert(_array != NULL, "Sanity check");
+}
+
+StringArrayArgument::~StringArrayArgument() {
+  for (int i=0; i<_array->length(); i++) {
+    if(_array->at(i) != NULL) { // Safety check
+      FREE_C_HEAP_ARRAY(char, _array->at(i));
+    }
+  }
+  delete _array;
+}
+
+void StringArrayArgument::add(const char* str, size_t len) {
+  if (str != NULL) {
+    char* ptr = NEW_C_HEAP_ARRAY(char, len+1, mtInternal);
+    strncpy(ptr, str, len);
+    ptr[len] = 0;
+    _array->append(ptr);
+  }
+}
+
 void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
   /* NOTE:Some argument types doesn't require a value,
    * for instance boolean arguments: "enableFeatureX". is
--- a/src/hotspot/share/services/diagnosticArgument.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/diagnosticArgument.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -35,29 +35,14 @@
 private:
   GrowableArray<char*>* _array;
 public:
-  StringArrayArgument() {
-    _array = new(ResourceObj::C_HEAP, mtInternal)GrowableArray<char *>(32, true);
-    assert(_array != NULL, "Sanity check");
-  }
-  void add(const char* str, size_t len) {
-    if (str != NULL) {
-      char* ptr = NEW_C_HEAP_ARRAY(char, len+1, mtInternal);
-      strncpy(ptr, str, len);
-      ptr[len] = 0;
-      _array->append(ptr);
-    }
-  }
+  StringArrayArgument();
+  ~StringArrayArgument();
+
+  void add(const char* str, size_t len);
+
   GrowableArray<char*>* array() {
     return _array;
   }
-  ~StringArrayArgument() {
-    for (int i=0; i<_array->length(); i++) {
-      if(_array->at(i) != NULL) { // Safety check
-        FREE_C_HEAP_ARRAY(char, _array->at(i));
-      }
-    }
-    delete _array;
-  }
 };
 
 class NanoTimeArgument {
--- a/src/hotspot/share/services/g1MemoryPool.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/g1CollectedHeap.hpp"
-#include "gc/g1/heapRegion.hpp"
-#include "services/g1MemoryPool.hpp"
-
-G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
-                                     const char* name,
-                                     size_t init_size,
-                                     size_t max_size,
-                                     bool support_usage_threshold) :
-  _g1mm(g1h->g1mm()), CollectedMemoryPool(name,
-                                          MemoryPool::Heap,
-                                          init_size,
-                                          max_size,
-                                          support_usage_threshold) {
-  assert(UseG1GC, "sanity");
-}
-
-G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
-  G1MemoryPoolSuper(g1h,
-                    "G1 Eden Space",
-                    g1h->g1mm()->eden_space_committed(), /* init_size */
-                    _undefined_max,
-                    false /* support_usage_threshold */) { }
-
-MemoryUsage G1EdenPool::get_memory_usage() {
-  size_t initial_sz = initial_size();
-  size_t max_sz     = max_size();
-  size_t used       = used_in_bytes();
-  size_t committed  = _g1mm->eden_space_committed();
-
-  return MemoryUsage(initial_sz, used, committed, max_sz);
-}
-
-G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
-  G1MemoryPoolSuper(g1h,
-                    "G1 Survivor Space",
-                    g1h->g1mm()->survivor_space_committed(), /* init_size */
-                    _undefined_max,
-                    false /* support_usage_threshold */) { }
-
-MemoryUsage G1SurvivorPool::get_memory_usage() {
-  size_t initial_sz = initial_size();
-  size_t max_sz     = max_size();
-  size_t used       = used_in_bytes();
-  size_t committed  = _g1mm->survivor_space_committed();
-
-  return MemoryUsage(initial_sz, used, committed, max_sz);
-}
-
-G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
-  G1MemoryPoolSuper(g1h,
-                    "G1 Old Gen",
-                    g1h->g1mm()->old_space_committed(), /* init_size */
-                    g1h->g1mm()->old_gen_max(),
-                    true /* support_usage_threshold */) { }
-
-MemoryUsage G1OldGenPool::get_memory_usage() {
-  size_t initial_sz = initial_size();
-  size_t max_sz     = max_size();
-  size_t used       = used_in_bytes();
-  size_t committed  = _g1mm->old_space_committed();
-
-  return MemoryUsage(initial_sz, used, committed, max_sz);
-}
--- a/src/hotspot/share/services/g1MemoryPool.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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.
- *
- */
-
-#ifndef SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
-#define SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
-
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1MonitoringSupport.hpp"
-#include "services/memoryPool.hpp"
-#include "services/memoryUsage.hpp"
-#endif // INCLUDE_ALL_GCS
-
-// This file contains the three classes that represent the memory
-// pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and
-// G1OldGenPool. In G1, unlike our other GCs, we do not have a
-// physical space for each of those spaces. Instead, we allocate
-// regions for all three spaces out of a single pool of regions (that
-// pool basically covers the entire heap). As a result, the eden,
-// survivor, and old gen are considered logical spaces in G1, as each
-// is a set of non-contiguous regions. This is also reflected in the
-// way we map them to memory pools here. The easiest way to have done
-// this would have been to map the entire G1 heap to a single memory
-// pool. However, it's helpful to show how large the eden and survivor
-// get, as this does affect the performance and behavior of G1. Which
-// is why we introduce the three memory pools implemented here.
-//
-// See comments in g1MonitoringSupport.hpp for additional details
-// on this model.
-//
-
-// This class is shared by the three G1 memory pool classes
-// (G1EdenPool, G1SurvivorPool, G1OldGenPool).
-class G1MemoryPoolSuper : public CollectedMemoryPool {
-protected:
-  const static size_t _undefined_max = (size_t) -1;
-  G1MonitoringSupport* _g1mm;
-
-  // Would only be called from subclasses.
-  G1MemoryPoolSuper(G1CollectedHeap* g1h,
-                    const char* name,
-                    size_t init_size,
-                    size_t max_size,
-                    bool support_usage_threshold);
-};
-
-// Memory pool that represents the G1 eden.
-class G1EdenPool : public G1MemoryPoolSuper {
-public:
-  G1EdenPool(G1CollectedHeap* g1h);
-
-  size_t used_in_bytes() {
-    return _g1mm->eden_space_used();
-  }
-  size_t max_size() const {
-    return _undefined_max;
-  }
-  MemoryUsage get_memory_usage();
-};
-
-// Memory pool that represents the G1 survivor.
-class G1SurvivorPool : public G1MemoryPoolSuper {
-public:
-  G1SurvivorPool(G1CollectedHeap* g1h);
-
-  size_t used_in_bytes() {
-    return _g1mm->survivor_space_used();
-  }
-  size_t max_size() const {
-    return _undefined_max;
-  }
-  MemoryUsage get_memory_usage();
-};
-
-// Memory pool that represents the G1 old gen.
-class G1OldGenPool : public G1MemoryPoolSuper {
-public:
-  G1OldGenPool(G1CollectedHeap* g1h);
-
-  size_t used_in_bytes() {
-    return _g1mm->old_space_used();
-  }
-  size_t max_size() const {
-    return _g1mm->old_gen_max();
-  }
-  MemoryUsage get_memory_usage();
-};
-
-#endif // SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
--- a/src/hotspot/share/services/heapDumper.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/heapDumper.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,8 @@
 #include "runtime/jniHandles.hpp"
 #include "runtime/os.hpp"
 #include "runtime/reflectionUtils.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
@@ -1895,7 +1897,7 @@
 
   _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
   int frame_serial_num = 0;
-  for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     oop threadObj = thread->threadObj();
     if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
       // dump thread stack trace
--- a/src/hotspot/share/services/jmm.h	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,345 +0,0 @@
-/*
- * Copyright (c) 2003, 2017, 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.
- */
-
-#ifndef _JAVA_JMM_H_
-#define _JAVA_JMM_H_
-
-/*
- * This is a private interface used by JDK for JVM monitoring
- * and management.
- *
- * Bump the version number when either of the following happens:
- *
- * 1. There is a change in functions in JmmInterface.
- *
- * 2. There is a change in the contract between VM and Java classes.
- */
-
-#include "jni.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
-  JMM_VERSION_1   = 0x20010000,
-  JMM_VERSION_1_0 = 0x20010000,
-  JMM_VERSION_1_1 = 0x20010100, // JDK 6
-  JMM_VERSION_1_2 = 0x20010200, // JDK 7
-  JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
-  JMM_VERSION_1_2_2 = 0x20010202,
-  JMM_VERSION_2  = 0x20020000,  // JDK 10
-  JMM_VERSION     = 0x20020000
-};
-
-typedef struct {
-  unsigned int isLowMemoryDetectionSupported : 1;
-  unsigned int isCompilationTimeMonitoringSupported : 1;
-  unsigned int isThreadContentionMonitoringSupported : 1;
-  unsigned int isCurrentThreadCpuTimeSupported : 1;
-  unsigned int isOtherThreadCpuTimeSupported : 1;
-  unsigned int isObjectMonitorUsageSupported : 1;
-  unsigned int isSynchronizerUsageSupported : 1;
-  unsigned int isThreadAllocatedMemorySupported : 1;
-  unsigned int isRemoteDiagnosticCommandsSupported : 1;
-  unsigned int : 22;
-} jmmOptionalSupport;
-
-typedef enum {
-  JMM_CLASS_LOADED_COUNT             = 1,    /* Total number of loaded classes */
-  JMM_CLASS_UNLOADED_COUNT           = 2,    /* Total number of unloaded classes */
-  JMM_THREAD_TOTAL_COUNT             = 3,    /* Total number of threads that have been started */
-  JMM_THREAD_LIVE_COUNT              = 4,    /* Current number of live threads */
-  JMM_THREAD_PEAK_COUNT              = 5,    /* Peak number of live threads */
-  JMM_THREAD_DAEMON_COUNT            = 6,    /* Current number of daemon threads */
-  JMM_JVM_INIT_DONE_TIME_MS          = 7,    /* Time when the JVM finished initialization */
-  JMM_COMPILE_TOTAL_TIME_MS          = 8,    /* Total accumulated time spent in compilation */
-  JMM_GC_TIME_MS                     = 9,    /* Total accumulated time spent in collection */
-  JMM_GC_COUNT                       = 10,   /* Total number of collections */
-  JMM_JVM_UPTIME_MS                  = 11,   /* The JVM uptime in milliseconds */
-
-  JMM_INTERNAL_ATTRIBUTE_INDEX       = 100,
-  JMM_CLASS_LOADED_BYTES             = 101,  /* Number of bytes loaded instance classes */
-  JMM_CLASS_UNLOADED_BYTES           = 102,  /* Number of bytes unloaded instance classes */
-  JMM_TOTAL_CLASSLOAD_TIME_MS        = 103,  /* Accumulated VM class loader time (TraceClassLoadingTime) */
-  JMM_VM_GLOBAL_COUNT                = 104,  /* Number of VM internal flags */
-  JMM_SAFEPOINT_COUNT                = 105,  /* Total number of safepoints */
-  JMM_TOTAL_SAFEPOINTSYNC_TIME_MS    = 106,  /* Accumulated time spent getting to safepoints */
-  JMM_TOTAL_STOPPED_TIME_MS          = 107,  /* Accumulated time spent at safepoints */
-  JMM_TOTAL_APP_TIME_MS              = 108,  /* Accumulated time spent in Java application */
-  JMM_VM_THREAD_COUNT                = 109,  /* Current number of VM internal threads */
-  JMM_CLASS_INIT_TOTAL_COUNT         = 110,  /* Number of classes for which initializers were run */
-  JMM_CLASS_INIT_TOTAL_TIME_MS       = 111,  /* Accumulated time spent in class initializers */
-  JMM_METHOD_DATA_SIZE_BYTES         = 112,  /* Size of method data in memory */
-  JMM_CLASS_VERIFY_TOTAL_TIME_MS     = 113,  /* Accumulated time spent in class verifier */
-  JMM_SHARED_CLASS_LOADED_COUNT      = 114,  /* Number of shared classes loaded */
-  JMM_SHARED_CLASS_UNLOADED_COUNT    = 115,  /* Number of shared classes unloaded */
-  JMM_SHARED_CLASS_LOADED_BYTES      = 116,  /* Number of bytes loaded shared classes */
-  JMM_SHARED_CLASS_UNLOADED_BYTES    = 117,  /* Number of bytes unloaded shared classes */
-
-  JMM_OS_ATTRIBUTE_INDEX             = 200,
-  JMM_OS_PROCESS_ID                  = 201,  /* Process id of the JVM */
-  JMM_OS_MEM_TOTAL_PHYSICAL_BYTES    = 202,  /* Physical memory size */
-
-  JMM_GC_EXT_ATTRIBUTE_INFO_SIZE     = 401   /* the size of the GC specific attributes for a given GC memory manager */
-} jmmLongAttribute;
-
-typedef enum {
-  JMM_VERBOSE_GC                     = 21,
-  JMM_VERBOSE_CLASS                  = 22,
-  JMM_THREAD_CONTENTION_MONITORING   = 23,
-  JMM_THREAD_CPU_TIME                = 24,
-  JMM_THREAD_ALLOCATED_MEMORY        = 25
-} jmmBoolAttribute;
-
-
-enum {
-  JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000,
-  JMM_THREAD_STATE_FLAG_NATIVE    = 0x00400000
-};
-
-#define JMM_THREAD_STATE_FLAG_MASK  0xFFF00000
-
-typedef enum {
-  JMM_STAT_PEAK_THREAD_COUNT         = 801,
-  JMM_STAT_THREAD_CONTENTION_COUNT   = 802,
-  JMM_STAT_THREAD_CONTENTION_TIME    = 803,
-  JMM_STAT_THREAD_CONTENTION_STAT    = 804,
-  JMM_STAT_PEAK_POOL_USAGE           = 805,
-  JMM_STAT_GC_STAT                   = 806
-} jmmStatisticType;
-
-typedef enum {
-  JMM_USAGE_THRESHOLD_HIGH            = 901,
-  JMM_USAGE_THRESHOLD_LOW             = 902,
-  JMM_COLLECTION_USAGE_THRESHOLD_HIGH = 903,
-  JMM_COLLECTION_USAGE_THRESHOLD_LOW  = 904
-} jmmThresholdType;
-
-/* Should match what is allowed in globals.hpp */
-typedef enum {
-  JMM_VMGLOBAL_TYPE_UNKNOWN  = 0,
-  JMM_VMGLOBAL_TYPE_JBOOLEAN = 1,
-  JMM_VMGLOBAL_TYPE_JSTRING  = 2,
-  JMM_VMGLOBAL_TYPE_JLONG    = 3,
-  JMM_VMGLOBAL_TYPE_JDOUBLE  = 4
-} jmmVMGlobalType;
-
-typedef enum {
-  JMM_VMGLOBAL_ORIGIN_DEFAULT      = 1,   /* Default value */
-  JMM_VMGLOBAL_ORIGIN_COMMAND_LINE = 2,   /* Set at command line (or JNI invocation) */
-  JMM_VMGLOBAL_ORIGIN_MANAGEMENT   = 3,   /* Set via management interface */
-  JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR  = 4,   /* Set via environment variables */
-  JMM_VMGLOBAL_ORIGIN_CONFIG_FILE  = 5,   /* Set via config file (such as .hotspotrc) */
-  JMM_VMGLOBAL_ORIGIN_ERGONOMIC    = 6,   /* Set via ergonomic */
-  JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND = 7,   /* Set via attach */
-  JMM_VMGLOBAL_ORIGIN_OTHER        = 99   /* Set via some other mechanism */
-} jmmVMGlobalOrigin;
-
-typedef struct {
-  jstring           name;
-  jvalue            value;
-  jmmVMGlobalType   type;           /* Data type */
-  jmmVMGlobalOrigin origin;         /* Default or non-default value */
-  unsigned int      writeable : 1;  /* dynamically writeable */
-  unsigned int      external  : 1;  /* external supported interface */
-  unsigned int      reserved  : 30;
-  void *reserved1;
-  void *reserved2;
-} jmmVMGlobal;
-
-typedef struct {
-  const char*  name;
-  char         type;
-  const char*  description;
-} jmmExtAttributeInfo;
-
-/* Caller has to set the following fields before calling GetLastGCStat
- *   o usage_before_gc               - array of MemoryUsage objects
- *   o usage_after_gc                - array of MemoryUsage objects
- *   o gc_ext_attribute_values_size - size of gc_ext_atttribute_values array
- *   o gc_ext_attribtue_values      - array of jvalues
- */
-typedef struct {
-  jlong        gc_index;                       /* Index of the collections */
-  jlong        start_time;                     /* Start time of the GC */
-  jlong        end_time;                       /* End time of the GC */
-  jobjectArray usage_before_gc;                /* Memory usage array before GC */
-  jobjectArray usage_after_gc;                 /* Memory usage array after GC */
-  jint         gc_ext_attribute_values_size;   /* set by the caller of GetGCStat */
-  jvalue*      gc_ext_attribute_values;        /* Array of jvalue for GC extension attributes */
-  jint         num_gc_ext_attributes;          /* number of GC extension attribute values s are filled */
-                                               /* -1 indicates gc_ext_attribute_values is not big enough */
-} jmmGCStat;
-
-typedef struct {
-  const char* name;                /* Name of the diagnostic command */
-  const char* description;         /* Short description */
-  const char* impact;              /* Impact on the JVM */
-  const char* permission_class;    /* Class name of the required permission if any */
-  const char* permission_name;     /* Permission name of the required permission if any */
-  const char* permission_action;   /* Action name of the required permission if any*/
-  int         num_arguments;       /* Number of supported options or arguments */
-  jboolean    enabled;             /* True if the diagnostic command can be invoked, false otherwise */
-} dcmdInfo;
-
-typedef struct {
-  const char* name;                /* Option/Argument name*/
-  const char* description;         /* Short description */
-  const char* type;                /* Type: STRING, BOOLEAN, etc. */
-  const char* default_string;      /* Default value in a parsable string */
-  jboolean    mandatory;           /* True if the option/argument is mandatory */
-  jboolean    option;              /* True if it is an option, false if it is an argument */
-                                   /* (see diagnosticFramework.hpp for option/argument definitions) */
-  jboolean    multiple;            /* True if the option can be specified several time */
-  int         position;            /* Expected position for this argument (this field is */
-                                   /* meaningless for options) */
-} dcmdArgInfo;
-
-typedef struct jmmInterface_1_ {
-  void*        reserved1;
-  void*        reserved2;
-
-  jint         (JNICALL *GetVersion)             (JNIEnv *env);
-
-  jint         (JNICALL *GetOptionalSupport)     (JNIEnv *env,
-                                                  jmmOptionalSupport* support_ptr);
-
-  jint         (JNICALL *GetThreadInfo)          (JNIEnv *env,
-                                                  jlongArray ids,
-                                                  jint maxDepth,
-                                                  jobjectArray infoArray);
-
-  jobjectArray (JNICALL *GetMemoryPools)         (JNIEnv* env, jobject mgr);
-
-  jobjectArray (JNICALL *GetMemoryManagers)      (JNIEnv* env, jobject pool);
-
-  jobject      (JNICALL *GetMemoryPoolUsage)     (JNIEnv* env, jobject pool);
-  jobject      (JNICALL *GetPeakMemoryPoolUsage) (JNIEnv* env, jobject pool);
-
-  void         (JNICALL *GetThreadAllocatedMemory)
-                                                 (JNIEnv *env,
-                                                  jlongArray ids,
-                                                  jlongArray sizeArray);
-
-  jobject      (JNICALL *GetMemoryUsage)         (JNIEnv* env, jboolean heap);
-
-  jlong        (JNICALL *GetLongAttribute)       (JNIEnv *env, jobject obj, jmmLongAttribute att);
-  jboolean     (JNICALL *GetBoolAttribute)       (JNIEnv *env, jmmBoolAttribute att);
-  jboolean     (JNICALL *SetBoolAttribute)       (JNIEnv *env, jmmBoolAttribute att, jboolean flag);
-
-  jint         (JNICALL *GetLongAttributes)      (JNIEnv *env,
-                                                  jobject obj,
-                                                  jmmLongAttribute* atts,
-                                                  jint count,
-                                                  jlong* result);
-
-  jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env);
-
-  // Not used in JDK 6 or JDK 7
-  jlong        (JNICALL *GetThreadCpuTime)       (JNIEnv *env, jlong thread_id);
-
-  jobjectArray (JNICALL *GetVMGlobalNames)       (JNIEnv *env);
-  jint         (JNICALL *GetVMGlobals)           (JNIEnv *env,
-                                                  jobjectArray names,
-                                                  jmmVMGlobal *globals,
-                                                  jint count);
-
-  jint         (JNICALL *GetInternalThreadTimes) (JNIEnv *env,
-                                                  jobjectArray names,
-                                                  jlongArray times);
-
-  jboolean     (JNICALL *ResetStatistic)         (JNIEnv *env,
-                                                  jvalue obj,
-                                                  jmmStatisticType type);
-
-  void         (JNICALL *SetPoolSensor)          (JNIEnv *env,
-                                                  jobject pool,
-                                                  jmmThresholdType type,
-                                                  jobject sensor);
-
-  jlong        (JNICALL *SetPoolThreshold)       (JNIEnv *env,
-                                                  jobject pool,
-                                                  jmmThresholdType type,
-                                                  jlong threshold);
-  jobject      (JNICALL *GetPoolCollectionUsage) (JNIEnv* env, jobject pool);
-
-  jint         (JNICALL *GetGCExtAttributeInfo)  (JNIEnv *env,
-                                                  jobject mgr,
-                                                  jmmExtAttributeInfo *ext_info,
-                                                  jint count);
-  void         (JNICALL *GetLastGCStat)          (JNIEnv *env,
-                                                  jobject mgr,
-                                                  jmmGCStat *gc_stat);
-
-  jlong        (JNICALL *GetThreadCpuTimeWithKind)
-                                                 (JNIEnv *env,
-                                                  jlong thread_id,
-                                                  jboolean user_sys_cpu_time);
-  void         (JNICALL *GetThreadCpuTimesWithKind)
-                                                 (JNIEnv *env,
-                                                  jlongArray ids,
-                                                  jlongArray timeArray,
-                                                  jboolean user_sys_cpu_time);
-
-  jint         (JNICALL *DumpHeap0)              (JNIEnv *env,
-                                                  jstring outputfile,
-                                                  jboolean live);
-  jobjectArray (JNICALL *FindDeadlocks)          (JNIEnv *env,
-                                                  jboolean object_monitors_only);
-  void         (JNICALL *SetVMGlobal)            (JNIEnv *env,
-                                                  jstring flag_name,
-                                                  jvalue  new_value);
-  void*        reserved6;
-  jobjectArray (JNICALL *DumpThreads)            (JNIEnv *env,
-                                                  jlongArray ids,
-                                                  jboolean lockedMonitors,
-                                                  jboolean lockedSynchronizers,
-                                                  jint maxDepth);
-  void         (JNICALL *SetGCNotificationEnabled) (JNIEnv *env,
-                                                    jobject mgr,
-                                                    jboolean enabled);
-  jobjectArray (JNICALL *GetDiagnosticCommands)  (JNIEnv *env);
-  void         (JNICALL *GetDiagnosticCommandInfo)
-                                                 (JNIEnv *env,
-                                                  jobjectArray cmds,
-                                                  dcmdInfo *infoArray);
-  void         (JNICALL *GetDiagnosticCommandArgumentsInfo)
-                                                 (JNIEnv *env,
-                                                  jstring commandName,
-                                                  dcmdArgInfo *infoArray);
-  jstring      (JNICALL *ExecuteDiagnosticCommand)
-                                                 (JNIEnv *env,
-                                                  jstring command);
-  void         (JNICALL *SetDiagnosticFrameworkNotificationEnabled)
-                                                 (JNIEnv *env,
-                                                  jboolean enabled);
-} JmmInterface;
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* !_JAVA_JMM_H_ */
--- a/src/hotspot/share/services/management.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/management.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jmm.h"
 #include "classfile/systemDictionary.hpp"
 #include "compiler/compileBroker.hpp"
 #include "memory/iterator.hpp"
@@ -41,12 +42,12 @@
 #include "runtime/os.hpp"
 #include "runtime/serviceThread.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "services/classLoadingService.hpp"
 #include "services/diagnosticCommand.hpp"
 #include "services/diagnosticFramework.hpp"
 #include "services/writeableFlags.hpp"
 #include "services/heapDumper.hpp"
-#include "services/jmm.h"
 #include "services/lowMemoryDetector.hpp"
 #include "services/gcNotifier.hpp"
 #include "services/nmtDCmd.hpp"
@@ -1025,11 +1026,15 @@
   // First get an array of threadObj handles.
   // A JavaThread may terminate before we get the stack trace.
   GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
+
   {
-    MutexLockerEx ml(Threads_lock);
+    // Need this ThreadsListHandle for converting Java thread IDs into
+    // threadObj handles; dump_result->set_t_list() is called in the
+    // VM op below so we can't use it yet.
+    ThreadsListHandle tlh;
     for (int i = 0; i < num_threads; i++) {
       jlong tid = ids_ah->long_at(i);
-      JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
+      JavaThread* jt = tlh.list()->find_JavaThread_from_java_tid(tid);
       oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
       instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
       thread_handle_array->append(threadObj_h);
@@ -1101,22 +1106,21 @@
   ThreadDumpResult dump_result(num_threads);
 
   if (maxDepth == 0) {
-    // no stack trace dumped - do not need to stop the world
-    {
-      MutexLockerEx ml(Threads_lock);
-      for (int i = 0; i < num_threads; i++) {
-        jlong tid = ids_ah->long_at(i);
-        JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
-        ThreadSnapshot* ts;
-        if (jt == NULL) {
-          // if the thread does not exist or now it is terminated,
-          // create dummy snapshot
-          ts = new ThreadSnapshot();
-        } else {
-          ts = new ThreadSnapshot(jt);
-        }
-        dump_result.add_thread_snapshot(ts);
+    // No stack trace to dump so we do not need to stop the world.
+    // Since we never do the VM op here we must set the threads list.
+    dump_result.set_t_list();
+    for (int i = 0; i < num_threads; i++) {
+      jlong tid = ids_ah->long_at(i);
+      JavaThread* jt = dump_result.t_list()->find_JavaThread_from_java_tid(tid);
+      ThreadSnapshot* ts;
+      if (jt == NULL) {
+        // if the thread does not exist or now it is terminated,
+        // create dummy snapshot
+        ts = new ThreadSnapshot();
+      } else {
+        ts = new ThreadSnapshot(dump_result.t_list(), jt);
       }
+      dump_result.add_thread_snapshot(ts);
     }
   } else {
     // obtain thread dump with the specific list of threads with stack trace
@@ -1131,6 +1135,7 @@
 
   int num_snapshots = dump_result.num_snapshots();
   assert(num_snapshots == num_threads, "Must match the number of thread snapshots");
+  assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");
   int index = 0;
   for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; index++, ts = ts->next()) {
     // For each thread, create an java/lang/management/ThreadInfo object
@@ -1196,6 +1201,7 @@
   }
 
   int num_snapshots = dump_result.num_snapshots();
+  assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");
 
   // create the result ThreadInfo[] object
   InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
@@ -1319,10 +1325,10 @@
       }
 
       // Look for the JavaThread of this given tid
-      MutexLockerEx ml(Threads_lock);
+      JavaThreadIteratorWithHandle jtiwh;
       if (tid == 0) {
         // reset contention statistics for all threads if tid == 0
-        for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) {
+        for (; JavaThread *java_thread = jtiwh.next(); ) {
           if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
             ThreadService::reset_contention_count_stat(java_thread);
           } else {
@@ -1331,7 +1337,7 @@
         }
       } else {
         // reset contention statistics for a given thread
-        JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
+        JavaThread* java_thread = jtiwh.list()->find_JavaThread_from_java_tid(tid);
         if (java_thread == NULL) {
           return false;
         }
@@ -1399,8 +1405,8 @@
     // current thread
     return os::current_thread_cpu_time();
   } else {
-    MutexLockerEx ml(Threads_lock);
-    java_thread = Threads::find_java_thread_from_java_tid(thread_id);
+    ThreadsListHandle tlh;
+    java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
     if (java_thread != NULL) {
       return os::thread_cpu_time((Thread*) java_thread);
     }
@@ -1649,6 +1655,7 @@
 // Called with Threads_lock held
 //
 void ThreadTimesClosure::do_thread(Thread* thread) {
+  assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
   assert(thread != NULL, "thread was NULL");
 
   // exclude externally visible JavaThreads
@@ -2109,9 +2116,9 @@
               "the given array of thread IDs");
   }
 
-  MutexLockerEx ml(Threads_lock);
+  ThreadsListHandle tlh;
   for (int i = 0; i < num_threads; i++) {
-    JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
+    JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(ids_ah->long_at(i));
     if (java_thread != NULL) {
       sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
     }
@@ -2138,8 +2145,8 @@
     // current thread
     return os::current_thread_cpu_time(user_sys_cpu_time != 0);
   } else {
-    MutexLockerEx ml(Threads_lock);
-    java_thread = Threads::find_java_thread_from_java_tid(thread_id);
+    ThreadsListHandle tlh;
+    java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
     if (java_thread != NULL) {
       return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
     }
@@ -2180,9 +2187,9 @@
               "the given array of thread IDs");
   }
 
-  MutexLockerEx ml(Threads_lock);
+  ThreadsListHandle tlh;
   for (int i = 0; i < num_threads; i++) {
-    JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
+    JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(ids_ah->long_at(i));
     if (java_thread != NULL) {
       timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
                                                       user_sys_cpu_time != 0));
--- a/src/hotspot/share/services/management.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/management.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,10 +25,10 @@
 #ifndef SHARE_VM_SERVICES_MANAGEMENT_HPP
 #define SHARE_VM_SERVICES_MANAGEMENT_HPP
 
+#include "jmm.h"
 #include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/timer.hpp"
-#include "services/jmm.h"
 
 class OopClosure;
 class ThreadSnapshot;
--- a/src/hotspot/share/services/memoryManager.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/memoryManager.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -37,7 +37,7 @@
 #include "services/gcNotifier.hpp"
 #include "utilities/dtrace.hpp"
 
-MemoryManager::MemoryManager() {
+MemoryManager::MemoryManager(const char* name) : _name(name) {
   _num_pools = 0;
   (void)const_cast<instanceOop&>(_memory_mgr_obj = instanceOop(NULL));
 }
@@ -52,43 +52,11 @@
 }
 
 MemoryManager* MemoryManager::get_code_cache_memory_manager() {
-  return (MemoryManager*) new CodeCacheMemoryManager();
+  return new MemoryManager("CodeCacheManager");
 }
 
 MemoryManager* MemoryManager::get_metaspace_memory_manager() {
-  return (MemoryManager*) new MetaspaceMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_copy_memory_manager() {
-  return (GCMemoryManager*) new CopyMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_msc_memory_manager() {
-  return (GCMemoryManager*) new MSCMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_parnew_memory_manager() {
-  return (GCMemoryManager*) new ParNewMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_cms_memory_manager() {
-  return (GCMemoryManager*) new CMSMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_psScavenge_memory_manager() {
-  return (GCMemoryManager*) new PSScavengeMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_psMarkSweep_memory_manager() {
-  return (GCMemoryManager*) new PSMarkSweepMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_g1YoungGen_memory_manager() {
-  return (GCMemoryManager*) new G1YoungGenMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_g1OldGen_memory_manager() {
-  return (GCMemoryManager*) new G1OldGenMemoryManager();
+  return new MemoryManager("Metaspace Manager");
 }
 
 instanceOop MemoryManager::get_memory_manager_instance(TRAPS) {
@@ -203,7 +171,8 @@
 }
 
 
-GCMemoryManager::GCMemoryManager() : MemoryManager() {
+GCMemoryManager::GCMemoryManager(const char* name, const char* gc_end_message) :
+  MemoryManager(name), _gc_end_message(gc_end_message) {
   _num_collections = 0;
   _last_gc_stat = NULL;
   _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true,
@@ -308,9 +277,7 @@
     }
 
     if (is_notification_enabled()) {
-      bool isMajorGC = this == MemoryService::get_major_gc_manager();
-      GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
-                                   GCCause::to_string(cause));
+      GCNotifier::pushNotification(this, _gc_end_message, GCCause::to_string(cause));
     }
   }
 }
--- a/src/hotspot/share/services/memoryManager.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/memoryManager.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -25,7 +25,10 @@
 #ifndef SHARE_VM_SERVICES_MEMORYMANAGER_HPP
 #define SHARE_VM_SERVICES_MEMORYMANAGER_HPP
 
+#include "gc/shared/gcCause.hpp"
 #include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "runtime/handles.hpp"
 #include "runtime/timer.hpp"
 #include "services/memoryUsage.hpp"
 
@@ -49,11 +52,13 @@
   MemoryPool* _pools[max_num_pools];
   int         _num_pools;
 
+  const char* _name;
+
 protected:
   volatile instanceOop _memory_mgr_obj;
 
 public:
-  MemoryManager();
+  MemoryManager(const char* name);
 
   int num_memory_pools() const           { return _num_pools; }
   MemoryPool* get_memory_pool(int index) {
@@ -67,7 +72,8 @@
 
   virtual instanceOop get_memory_manager_instance(TRAPS);
   virtual bool is_gc_memory_manager()    { return false; }
-  virtual const char* name() = 0;
+
+  const char* name() const { return _name; }
 
   // GC support
   void oops_do(OopClosure* f);
@@ -75,29 +81,6 @@
   // Static factory methods to get a memory manager of a specific type
   static MemoryManager*   get_code_cache_memory_manager();
   static MemoryManager*   get_metaspace_memory_manager();
-  static GCMemoryManager* get_copy_memory_manager();
-  static GCMemoryManager* get_msc_memory_manager();
-  static GCMemoryManager* get_parnew_memory_manager();
-  static GCMemoryManager* get_cms_memory_manager();
-  static GCMemoryManager* get_psScavenge_memory_manager();
-  static GCMemoryManager* get_psMarkSweep_memory_manager();
-  static GCMemoryManager* get_g1YoungGen_memory_manager();
-  static GCMemoryManager* get_g1OldGen_memory_manager();
-};
-
-class CodeCacheMemoryManager : public MemoryManager {
-private:
-public:
-  CodeCacheMemoryManager() : MemoryManager() {}
-
-  const char* name() { return "CodeCacheManager"; }
-};
-
-class MetaspaceMemoryManager : public MemoryManager {
-public:
-  MetaspaceMemoryManager() : MemoryManager() {}
-
-  const char* name() { return "Metaspace Manager"; }
 };
 
 class GCStatInfo : public ResourceObj {
@@ -159,8 +142,9 @@
   GCStatInfo*  _current_gc_stat;
   int          _num_gc_threads;
   volatile bool _notification_enabled;
+  const char* _gc_end_message;
 public:
-  GCMemoryManager();
+  GCMemoryManager(const char* name, const char* gc_end_message);
   ~GCMemoryManager();
 
   void   initialize_gc_stat_info();
@@ -186,71 +170,4 @@
   bool is_notification_enabled() { return _notification_enabled; }
 };
 
-// These subclasses of GCMemoryManager are defined to include
-// GC-specific information.
-// TODO: Add GC-specific information
-class CopyMemoryManager : public GCMemoryManager {
-private:
-public:
-  CopyMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "Copy"; }
-};
-
-class MSCMemoryManager : public GCMemoryManager {
-private:
-public:
-  MSCMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "MarkSweepCompact"; }
-};
-
-class ParNewMemoryManager : public GCMemoryManager {
-private:
-public:
-  ParNewMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "ParNew"; }
-};
-
-class CMSMemoryManager : public GCMemoryManager {
-private:
-public:
-  CMSMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "ConcurrentMarkSweep";}
-};
-
-class PSScavengeMemoryManager : public GCMemoryManager {
-private:
-public:
-  PSScavengeMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "PS Scavenge"; }
-};
-
-class PSMarkSweepMemoryManager : public GCMemoryManager {
-private:
-public:
-  PSMarkSweepMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "PS MarkSweep"; }
-};
-
-class G1YoungGenMemoryManager : public GCMemoryManager {
-private:
-public:
-  G1YoungGenMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "G1 Young Generation"; }
-};
-
-class G1OldGenMemoryManager : public GCMemoryManager {
-private:
-public:
-  G1OldGenMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "G1 Old Generation"; }
-};
-
 #endif // SHARE_VM_SERVICES_MEMORYMANAGER_HPP
--- a/src/hotspot/share/services/memoryPool.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/memoryPool.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,8 +25,6 @@
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#include "gc/shared/space.hpp"
 #include "memory/metaspace.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
@@ -38,9 +36,6 @@
 #include "services/memoryPool.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/cms/compactibleFreeListSpace.hpp"
-#endif
 
 MemoryPool::MemoryPool(const char* name,
                        PoolType type,
@@ -182,95 +177,6 @@
   }
 }
 
-ContiguousSpacePool::ContiguousSpacePool(ContiguousSpace* space,
-                                         const char* name,
-                                         PoolType type,
-                                         size_t max_size,
-                                         bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, space->capacity(), max_size,
-                      support_usage_threshold), _space(space) {
-}
-
-size_t ContiguousSpacePool::used_in_bytes() {
-  return space()->used();
-}
-
-MemoryUsage ContiguousSpacePool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used      = used_in_bytes();
-  size_t committed = _space->capacity();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-SurvivorContiguousSpacePool::SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
-                                                         const char* name,
-                                                         PoolType type,
-                                                         size_t max_size,
-                                                         bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, young_gen->from()->capacity(), max_size,
-                      support_usage_threshold), _young_gen(young_gen) {
-}
-
-size_t SurvivorContiguousSpacePool::used_in_bytes() {
-  return _young_gen->from()->used();
-}
-
-size_t SurvivorContiguousSpacePool::committed_in_bytes() {
-  return _young_gen->from()->capacity();
-}
-
-MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
-  size_t maxSize = (available_for_allocation() ? max_size() : 0);
-  size_t used    = used_in_bytes();
-  size_t committed = committed_in_bytes();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-#if INCLUDE_ALL_GCS
-CompactibleFreeListSpacePool::CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
-                                                           const char* name,
-                                                           PoolType type,
-                                                           size_t max_size,
-                                                           bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, space->capacity(), max_size,
-                      support_usage_threshold), _space(space) {
-}
-
-size_t CompactibleFreeListSpacePool::used_in_bytes() {
-  return _space->used();
-}
-
-MemoryUsage CompactibleFreeListSpacePool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used      = used_in_bytes();
-  size_t committed = _space->capacity();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-#endif // INCLUDE_ALL_GCS
-
-GenerationPool::GenerationPool(Generation* gen,
-                               const char* name,
-                               PoolType type,
-                               bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, gen->capacity(), gen->max_capacity(),
-                      support_usage_threshold), _gen(gen) {
-}
-
-size_t GenerationPool::used_in_bytes() {
-  return _gen->used();
-}
-
-MemoryUsage GenerationPool::get_memory_usage() {
-  size_t used      = used_in_bytes();
-  size_t committed = _gen->capacity();
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
 CodeHeapPool::CodeHeapPool(CodeHeap* codeHeap, const char* name, bool support_usage_threshold) :
   MemoryPool(name, NonHeap, codeHeap->capacity(), codeHeap->max_capacity(),
              support_usage_threshold, false), _codeHeap(codeHeap) {
--- a/src/hotspot/share/services/memoryPool.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/memoryPool.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -37,12 +37,8 @@
 // both heap and non-heap memory.
 
 // Forward declaration
-class CompactibleFreeListSpace;
-class ContiguousSpace;
 class MemoryManager;
 class SensorInfo;
-class Generation;
-class DefNewGeneration;
 class ThresholdSupport;
 
 class MemoryPool : public CHeapObj<mtInternal> {
@@ -144,67 +140,11 @@
 
 class CollectedMemoryPool : public MemoryPool {
 public:
-  CollectedMemoryPool(const char* name, PoolType type, size_t init_size, size_t max_size, bool support_usage_threshold) :
-    MemoryPool(name, type, init_size, max_size, support_usage_threshold, true) {};
+  CollectedMemoryPool(const char* name, size_t init_size, size_t max_size, bool support_usage_threshold) :
+    MemoryPool(name, MemoryPool::Heap, init_size, max_size, support_usage_threshold, true) {};
   bool is_collected_pool()            { return true; }
 };
 
-class ContiguousSpacePool : public CollectedMemoryPool {
-private:
-  ContiguousSpace* _space;
-
-public:
-  ContiguousSpacePool(ContiguousSpace* space, const char* name, PoolType type, size_t max_size, bool support_usage_threshold);
-
-  ContiguousSpace* space()              { return _space; }
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes();
-};
-
-class SurvivorContiguousSpacePool : public CollectedMemoryPool {
-private:
-  DefNewGeneration* _young_gen;
-
-public:
-  SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
-                              const char* name,
-                              PoolType type,
-                              size_t max_size,
-                              bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-
-  size_t used_in_bytes();
-  size_t committed_in_bytes();
-};
-
-#if INCLUDE_ALL_GCS
-class CompactibleFreeListSpacePool : public CollectedMemoryPool {
-private:
-  CompactibleFreeListSpace* _space;
-public:
-  CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
-                               const char* name,
-                               PoolType type,
-                               size_t max_size,
-                               bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes();
-};
-#endif // INCLUDE_ALL_GCS
-
-
-class GenerationPool : public CollectedMemoryPool {
-private:
-  Generation* _gen;
-public:
-  GenerationPool(Generation* gen, const char* name, PoolType type, bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes();
-};
-
 class CodeHeapPool: public MemoryPool {
 private:
   CodeHeap* _codeHeap;
--- a/src/hotspot/share/services/memoryService.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/memoryService.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -25,13 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "gc/parallel/mutableSpace.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#include "gc/serial/tenuredGeneration.hpp"
-#include "gc/shared/collectorPolicy.hpp"
-#include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/generation.hpp"
-#include "gc/shared/generationSpec.hpp"
+#include "gc/shared/collectedHeap.hpp"
 #include "logging/logConfiguration.hpp"
 #include "memory/heap.hpp"
 #include "memory/memRegion.hpp"
@@ -46,24 +40,12 @@
 #include "services/memoryService.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/cms/concurrentMarkSweepGeneration.hpp"
-#include "gc/cms/parNewGeneration.hpp"
-#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/parallel/parallelScavengeHeap.hpp"
-#include "gc/parallel/psOldGen.hpp"
-#include "gc/parallel/psYoungGen.hpp"
-#include "services/g1MemoryPool.hpp"
-#include "services/psMemoryPool.hpp"
-#endif // INCLUDE_ALL_GCS
 
 GrowableArray<MemoryPool*>* MemoryService::_pools_list =
   new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryPool*>(init_pools_list_size, true);
 GrowableArray<MemoryManager*>* MemoryService::_managers_list =
   new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryManager*>(init_managers_list_size, true);
 
-GCMemoryManager* MemoryService::_minor_gc_manager      = NULL;
-GCMemoryManager* MemoryService::_major_gc_manager      = NULL;
 MemoryManager*   MemoryService::_code_cache_manager    = NULL;
 GrowableArray<MemoryPool*>* MemoryService::_code_heap_pools =
     new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryPool*>(init_code_heap_pools_size, true);
@@ -84,311 +66,28 @@
 }
 
 void MemoryService::set_universe_heap(CollectedHeap* heap) {
-  CollectedHeap::Name kind = heap->kind();
-  switch (kind) {
-    case CollectedHeap::SerialHeap :
-    case CollectedHeap::CMSHeap : {
-      add_gen_collected_heap_info(GenCollectedHeap::heap());
-      break;
-    }
-#if INCLUDE_ALL_GCS
-    case CollectedHeap::ParallelScavengeHeap : {
-      add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
-      break;
-    }
-    case CollectedHeap::G1CollectedHeap : {
-      add_g1_heap_info(G1CollectedHeap::heap());
-      break;
-    }
-#endif // INCLUDE_ALL_GCS
-    default: {
-      guarantee(false, "Unrecognized kind of heap");
-    }
-  }
+  ResourceMark rm; // For internal allocations in GrowableArray.
+
+  GrowableArray<MemoryPool*> gc_mem_pools = heap->memory_pools();
+  _pools_list->appendAll(&gc_mem_pools);
 
   // set the GC thread count
   GcThreadCountClosure gctcc;
   heap->gc_threads_do(&gctcc);
   int count = gctcc.count();
-  if (count > 0) {
-    _minor_gc_manager->set_num_gc_threads(count);
-    _major_gc_manager->set_num_gc_threads(count);
-  }
 
-  // All memory pools and memory managers are initialized.
-  //
-  _minor_gc_manager->initialize_gc_stat_info();
-  _major_gc_manager->initialize_gc_stat_info();
-}
-
-// Add memory pools for GenCollectedHeap
-// This function currently only supports two generations collected heap.
-// The collector for GenCollectedHeap will have two memory managers.
-void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
-  CollectorPolicy* policy = heap->collector_policy();
-
-  assert(policy->is_generation_policy(), "Only support two generations");
-  GenCollectorPolicy* gen_policy = policy->as_generation_policy();
-  if (gen_policy != NULL) {
-    Generation::Name kind = gen_policy->young_gen_spec()->name();
-    switch (kind) {
-      case Generation::DefNew:
-        _minor_gc_manager = MemoryManager::get_copy_memory_manager();
-        break;
-#if INCLUDE_ALL_GCS
-      case Generation::ParNew:
-        _minor_gc_manager = MemoryManager::get_parnew_memory_manager();
-        break;
-#endif // INCLUDE_ALL_GCS
-      default:
-        guarantee(false, "Unrecognized generation spec");
-        break;
-    }
-    if (policy->is_mark_sweep_policy()) {
-      _major_gc_manager = MemoryManager::get_msc_memory_manager();
-#if INCLUDE_ALL_GCS
-    } else if (policy->is_concurrent_mark_sweep_policy()) {
-      _major_gc_manager = MemoryManager::get_cms_memory_manager();
-#endif // INCLUDE_ALL_GCS
-    } else {
-      guarantee(false, "Unknown two-gen policy");
-    }
-  } else {
-    guarantee(false, "Non two-gen policy");
-  }
-  _managers_list->append(_minor_gc_manager);
-  _managers_list->append(_major_gc_manager);
-
-  add_generation_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
-  add_generation_memory_pool(heap->old_gen(), _major_gc_manager);
-}
-
-#if INCLUDE_ALL_GCS
-// Add memory pools for ParallelScavengeHeap
-// This function currently only supports two generations collected heap.
-// The collector for ParallelScavengeHeap will have two memory managers.
-void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap) {
-  // Two managers to keep statistics about _minor_gc_manager and _major_gc_manager GC.
-  _minor_gc_manager = MemoryManager::get_psScavenge_memory_manager();
-  _major_gc_manager = MemoryManager::get_psMarkSweep_memory_manager();
-  _managers_list->append(_minor_gc_manager);
-  _managers_list->append(_major_gc_manager);
-
-  add_psYoung_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
-  add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
-}
-
-void MemoryService::add_g1_heap_info(G1CollectedHeap* g1h) {
-  assert(UseG1GC, "sanity");
-
-  _minor_gc_manager = MemoryManager::get_g1YoungGen_memory_manager();
-  _major_gc_manager = MemoryManager::get_g1OldGen_memory_manager();
-  _managers_list->append(_minor_gc_manager);
-  _managers_list->append(_major_gc_manager);
-
-  add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
-  add_g1OldGen_memory_pool(g1h, _major_gc_manager);
-}
-#endif // INCLUDE_ALL_GCS
-
-MemoryPool* MemoryService::add_gen(Generation* gen,
-                                   const char* name,
-                                   bool is_heap,
-                                   bool support_usage_threshold) {
-
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  GenerationPool* pool = new GenerationPool(gen, name, type, support_usage_threshold);
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-
-MemoryPool* MemoryService::add_space(ContiguousSpace* space,
-                                     const char* name,
-                                     bool is_heap,
-                                     size_t max_size,
-                                     bool support_usage_threshold) {
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  ContiguousSpacePool* pool = new ContiguousSpacePool(space, name, type, max_size, support_usage_threshold);
-
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
+  GrowableArray<GCMemoryManager*> gc_memory_managers = heap->memory_managers();
+  for (int i = 0; i < gc_memory_managers.length(); i++) {
+    GCMemoryManager* gc_manager = gc_memory_managers.at(i);
 
-MemoryPool* MemoryService::add_survivor_spaces(DefNewGeneration* young_gen,
-                                               const char* name,
-                                               bool is_heap,
-                                               size_t max_size,
-                                               bool support_usage_threshold) {
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  SurvivorContiguousSpacePool* pool = new SurvivorContiguousSpacePool(young_gen, name, type, max_size, support_usage_threshold);
-
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-
-#if INCLUDE_ALL_GCS
-MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space,
-                                         const char* name,
-                                         bool is_heap,
-                                         size_t max_size,
-                                         bool support_usage_threshold) {
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  CompactibleFreeListSpacePool* pool = new CompactibleFreeListSpacePool(space, name, type, max_size, support_usage_threshold);
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-#endif // INCLUDE_ALL_GCS
-
-// Add memory pool(s) for one generation
-void MemoryService::add_generation_memory_pool(Generation* gen,
-                                               MemoryManager* major_mgr,
-                                               MemoryManager* minor_mgr) {
-  guarantee(gen != NULL, "No generation for memory pool");
-  Generation::Name kind = gen->kind();
-  int index = _pools_list->length();
-
-  switch (kind) {
-    case Generation::DefNew: {
-      assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
-      DefNewGeneration* young_gen = (DefNewGeneration*) gen;
-      // Add a memory pool for each space and young gen doesn't
-      // support low memory detection as it is expected to get filled up.
-      MemoryPool* eden = add_space(young_gen->eden(),
-                                   "Eden Space",
-                                   true, /* is_heap */
-                                   young_gen->max_eden_size(),
-                                   false /* support_usage_threshold */);
-      MemoryPool* survivor = add_survivor_spaces(young_gen,
-                                                 "Survivor Space",
-                                                 true, /* is_heap */
-                                                 young_gen->max_survivor_size(),
-                                                 false /* support_usage_threshold */);
-      break;
+    if (count > 0) {
+      gc_manager->set_num_gc_threads(count);
     }
-
-#if INCLUDE_ALL_GCS
-    case Generation::ParNew:
-    {
-      assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
-      // Add a memory pool for each space and young gen doesn't
-      // support low memory detection as it is expected to get filled up.
-      ParNewGeneration* parnew_gen = (ParNewGeneration*) gen;
-      MemoryPool* eden = add_space(parnew_gen->eden(),
-                                   "Par Eden Space",
-                                   true /* is_heap */,
-                                   parnew_gen->max_eden_size(),
-                                   false /* support_usage_threshold */);
-      MemoryPool* survivor = add_survivor_spaces(parnew_gen,
-                                                 "Par Survivor Space",
-                                                 true, /* is_heap */
-                                                 parnew_gen->max_survivor_size(),
-                                                 false /* support_usage_threshold */);
-
-      break;
-    }
-#endif // INCLUDE_ALL_GCS
-
-    case Generation::MarkSweepCompact: {
-      assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
-      add_gen(gen,
-              "Tenured Gen",
-              true, /* is_heap */
-              true  /* support_usage_threshold */);
-      break;
-    }
-
-#if INCLUDE_ALL_GCS
-    case Generation::ConcurrentMarkSweep:
-    {
-      assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
-      ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*) gen;
-      MemoryPool* pool = add_cms_space(cms->cmsSpace(),
-                                       "CMS Old Gen",
-                                       true, /* is_heap */
-                                       cms->reserved().byte_size(),
-                                       true  /* support_usage_threshold */);
-      break;
-    }
-#endif // INCLUDE_ALL_GCS
-
-    default:
-      assert(false, "should not reach here");
-      // no memory pool added for others
-      break;
-  }
-
-  assert(major_mgr != NULL, "Should have at least one manager");
-  // Link managers and the memory pools together
-  for (int i = index; i < _pools_list->length(); i++) {
-    MemoryPool* pool = _pools_list->at(i);
-    major_mgr->add_pool(pool);
-    if (minor_mgr != NULL) {
-      minor_mgr->add_pool(pool);
-    }
+    gc_manager->initialize_gc_stat_info();
+    _managers_list->append(gc_manager);
   }
 }
 
-
-#if INCLUDE_ALL_GCS
-void MemoryService::add_psYoung_memory_pool(PSYoungGen* young_gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) {
-  assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
-
-  // Add a memory pool for each space and young gen doesn't
-  // support low memory detection as it is expected to get filled up.
-  EdenMutableSpacePool* eden = new EdenMutableSpacePool(young_gen,
-                                                        young_gen->eden_space(),
-                                                        "PS Eden Space",
-                                                        MemoryPool::Heap,
-                                                        false /* support_usage_threshold */);
-
-  SurvivorMutableSpacePool* survivor = new SurvivorMutableSpacePool(young_gen,
-                                                                    "PS Survivor Space",
-                                                                    MemoryPool::Heap,
-                                                                    false /* support_usage_threshold */);
-
-  major_mgr->add_pool(eden);
-  major_mgr->add_pool(survivor);
-  minor_mgr->add_pool(eden);
-  minor_mgr->add_pool(survivor);
-  _pools_list->append(eden);
-  _pools_list->append(survivor);
-}
-
-void MemoryService::add_psOld_memory_pool(PSOldGen* old_gen, MemoryManager* mgr) {
-  PSGenerationPool* old_gen_pool = new PSGenerationPool(old_gen,
-                                                       "PS Old Gen",
-                                                       MemoryPool::Heap,
-                                                       true /* support_usage_threshold */);
-  mgr->add_pool(old_gen_pool);
-  _pools_list->append(old_gen_pool);
-}
-
-void MemoryService::add_g1YoungGen_memory_pool(G1CollectedHeap* g1h,
-                                               MemoryManager* major_mgr,
-                                               MemoryManager* minor_mgr) {
-  assert(major_mgr != NULL && minor_mgr != NULL, "should have two managers");
-
-  G1EdenPool* eden = new G1EdenPool(g1h);
-  G1SurvivorPool* survivor = new G1SurvivorPool(g1h);
-
-  major_mgr->add_pool(eden);
-  major_mgr->add_pool(survivor);
-  minor_mgr->add_pool(eden);
-  minor_mgr->add_pool(survivor);
-  _pools_list->append(eden);
-  _pools_list->append(survivor);
-}
-
-void MemoryService::add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
-                                             MemoryManager* mgr) {
-  assert(mgr != NULL, "should have one manager");
-
-  G1OldGenPool* old_gen = new G1OldGenPool(g1h);
-  mgr->add_pool(old_gen);
-  _pools_list->append(old_gen);
-}
-#endif // INCLUDE_ALL_GCS
-
 void MemoryService::add_code_heap_memory_pool(CodeHeap* heap, const char* name) {
   // Create new memory pool for this heap
   MemoryPool* code_heap_pool = new CodeHeapPool(heap, name, true /* support_usage_threshold */);
@@ -463,18 +162,11 @@
   }
 }
 
-void MemoryService::gc_begin(bool fullGC, bool recordGCBeginTime,
+void MemoryService::gc_begin(GCMemoryManager* manager, bool recordGCBeginTime,
                              bool recordAccumulatedGCTime,
                              bool recordPreGCUsage, bool recordPeakUsage) {
 
-  GCMemoryManager* mgr;
-  if (fullGC) {
-    mgr = _major_gc_manager;
-  } else {
-    mgr = _minor_gc_manager;
-  }
-  assert(mgr->is_gc_memory_manager(), "Sanity check");
-  mgr->gc_begin(recordGCBeginTime, recordPreGCUsage, recordAccumulatedGCTime);
+  manager->gc_begin(recordGCBeginTime, recordPreGCUsage, recordAccumulatedGCTime);
 
   // Track the peak memory usage when GC begins
   if (recordPeakUsage) {
@@ -485,22 +177,13 @@
   }
 }
 
-void MemoryService::gc_end(bool fullGC, bool recordPostGCUsage,
+void MemoryService::gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
                            bool recordAccumulatedGCTime,
                            bool recordGCEndTime, bool countCollection,
                            GCCause::Cause cause) {
-
-  GCMemoryManager* mgr;
-  if (fullGC) {
-    mgr = (GCMemoryManager*) _major_gc_manager;
-  } else {
-    mgr = (GCMemoryManager*) _minor_gc_manager;
-  }
-  assert(mgr->is_gc_memory_manager(), "Sanity check");
-
   // register the GC end statistics and memory usage
-  mgr->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
-              countCollection, cause);
+  manager->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
+                  countCollection, cause);
 }
 
 void MemoryService::oops_do(OopClosure* f) {
@@ -551,36 +234,7 @@
   return obj;
 }
 
-// GC manager type depends on the type of Generation. Depending on the space
-// availability and vm options the gc uses major gc manager or minor gc
-// manager or both. The type of gc manager depends on the generation kind.
-// For DefNew and ParNew generation doing scavenge gc uses minor gc manager (so
-// _fullGC is set to false ) and for other generation kinds doing
-// mark-sweep-compact uses major gc manager (so _fullGC is set to true).
-TraceMemoryManagerStats::TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause) {
-  switch (kind) {
-    case Generation::DefNew:
-#if INCLUDE_ALL_GCS
-    case Generation::ParNew:
-#endif // INCLUDE_ALL_GCS
-      _fullGC = false;
-      break;
-    case Generation::MarkSweepCompact:
-#if INCLUDE_ALL_GCS
-    case Generation::ConcurrentMarkSweep:
-#endif // INCLUDE_ALL_GCS
-      _fullGC = true;
-      break;
-    default:
-      _fullGC = false;
-      assert(false, "Unrecognized gc generation kind.");
-  }
-  // this has to be called in a stop the world pause and represent
-  // an entire gc pause, start to finish:
-  initialize(_fullGC, cause, true, true, true, true, true, true, true);
-}
-
-TraceMemoryManagerStats::TraceMemoryManagerStats(bool fullGC,
+TraceMemoryManagerStats::TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager,
                                                  GCCause::Cause cause,
                                                  bool recordGCBeginTime,
                                                  bool recordPreGCUsage,
@@ -589,14 +243,14 @@
                                                  bool recordAccumulatedGCTime,
                                                  bool recordGCEndTime,
                                                  bool countCollection) {
-  initialize(fullGC, cause, recordGCBeginTime, recordPreGCUsage, recordPeakUsage,
+  initialize(gc_memory_manager, cause, recordGCBeginTime, recordPreGCUsage, recordPeakUsage,
              recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
              countCollection);
 }
 
 // for a subclass to create then initialize an instance before invoking
 // the MemoryService
-void TraceMemoryManagerStats::initialize(bool fullGC,
+void TraceMemoryManagerStats::initialize(GCMemoryManager* gc_memory_manager,
                                          GCCause::Cause cause,
                                          bool recordGCBeginTime,
                                          bool recordPreGCUsage,
@@ -605,7 +259,7 @@
                                          bool recordAccumulatedGCTime,
                                          bool recordGCEndTime,
                                          bool countCollection) {
-  _fullGC = fullGC;
+  _gc_memory_manager = gc_memory_manager;
   _recordGCBeginTime = recordGCBeginTime;
   _recordPreGCUsage = recordPreGCUsage;
   _recordPeakUsage = recordPeakUsage;
@@ -615,11 +269,11 @@
   _countCollection = countCollection;
   _cause = cause;
 
-  MemoryService::gc_begin(_fullGC, _recordGCBeginTime, _recordAccumulatedGCTime,
+  MemoryService::gc_begin(_gc_memory_manager, _recordGCBeginTime, _recordAccumulatedGCTime,
                           _recordPreGCUsage, _recordPeakUsage);
 }
 
 TraceMemoryManagerStats::~TraceMemoryManagerStats() {
-  MemoryService::gc_end(_fullGC, _recordPostGCUsage, _recordAccumulatedGCTime,
+  MemoryService::gc_end(_gc_memory_manager, _recordPostGCUsage, _recordAccumulatedGCTime,
                         _recordGCEndTime, _countCollection, _cause);
 }
--- a/src/hotspot/share/services/memoryService.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/memoryService.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -26,7 +26,6 @@
 #define SHARE_VM_SERVICES_MEMORYSERVICE_HPP
 
 #include "gc/shared/gcCause.hpp"
-#include "gc/shared/generation.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
@@ -37,16 +36,7 @@
 class MemoryManager;
 class GCMemoryManager;
 class CollectedHeap;
-class Generation;
-class DefNewGeneration;
-class PSYoungGen;
-class PSOldGen;
 class CodeHeap;
-class ContiguousSpace;
-class CompactibleFreeListSpace;
-class GenCollectedHeap;
-class ParallelScavengeHeap;
-class G1CollectedHeap;
 
 // VM Monitoring and Management Support
 
@@ -61,10 +51,6 @@
   static GrowableArray<MemoryPool*>*    _pools_list;
   static GrowableArray<MemoryManager*>* _managers_list;
 
-  // memory managers for minor and major GC statistics
-  static GCMemoryManager*               _major_gc_manager;
-  static GCMemoryManager*               _minor_gc_manager;
-
   // memory manager and code heap pools for the CodeCache
   static MemoryManager*                 _code_cache_manager;
   static GrowableArray<MemoryPool*>*    _code_heap_pools;
@@ -72,51 +58,6 @@
   static MemoryPool*                    _metaspace_pool;
   static MemoryPool*                    _compressed_class_pool;
 
-  static void add_generation_memory_pool(Generation* gen,
-                                         MemoryManager* major_mgr,
-                                         MemoryManager* minor_mgr);
-  static void add_generation_memory_pool(Generation* gen,
-                                         MemoryManager* major_mgr) {
-    add_generation_memory_pool(gen, major_mgr, NULL);
-  }
-
-
-  static void add_psYoung_memory_pool(PSYoungGen* young_gen,
-                                      MemoryManager* major_mgr,
-                                      MemoryManager* minor_mgr);
-  static void add_psOld_memory_pool(PSOldGen* old_gen,
-                                    MemoryManager* mgr);
-
-  static void add_g1YoungGen_memory_pool(G1CollectedHeap* g1h,
-                                         MemoryManager* major_mgr,
-                                         MemoryManager* minor_mgr);
-  static void add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
-                                       MemoryManager* mgr);
-
-  static MemoryPool* add_space(ContiguousSpace* space,
-                               const char* name,
-                               bool is_heap,
-                               size_t max_size,
-                               bool support_usage_threshold);
-  static MemoryPool* add_survivor_spaces(DefNewGeneration* young_gen,
-                                         const char* name,
-                                         bool is_heap,
-                                         size_t max_size,
-                                         bool support_usage_threshold);
-  static MemoryPool* add_gen(Generation* gen,
-                             const char* name,
-                             bool is_heap,
-                             bool support_usage_threshold);
-  static MemoryPool* add_cms_space(CompactibleFreeListSpace* space,
-                                   const char* name,
-                                   bool is_heap,
-                                   size_t max_size,
-                                   bool support_usage_threshold);
-
-  static void add_gen_collected_heap_info(GenCollectedHeap* heap);
-  static void add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap);
-  static void add_g1_heap_info(G1CollectedHeap* g1h);
-
 public:
   static void set_universe_heap(CollectedHeap* heap);
   static void add_code_heap_memory_pool(CodeHeap* heap, const char* name);
@@ -155,10 +96,10 @@
   }
   static void track_memory_pool_usage(MemoryPool* pool);
 
-  static void gc_begin(bool fullGC, bool recordGCBeginTime,
+  static void gc_begin(GCMemoryManager* manager, bool recordGCBeginTime,
                        bool recordAccumulatedGCTime,
                        bool recordPreGCUsage, bool recordPeakUsage);
-  static void gc_end(bool fullGC, bool recordPostGCUsage,
+  static void gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
                      bool recordAccumulatedGCTime,
                      bool recordGCEndTime, bool countCollection,
                      GCCause::Cause cause);
@@ -170,19 +111,11 @@
 
   // Create an instance of java/lang/management/MemoryUsage
   static Handle create_MemoryUsage_obj(MemoryUsage usage, TRAPS);
-
-  static const GCMemoryManager* get_minor_gc_manager() {
-      return _minor_gc_manager;
-  }
-
-  static const GCMemoryManager* get_major_gc_manager() {
-      return _major_gc_manager;
-  }
 };
 
 class TraceMemoryManagerStats : public StackObj {
 private:
-  bool         _fullGC;
+  GCMemoryManager* _gc_memory_manager;
   bool         _recordGCBeginTime;
   bool         _recordPreGCUsage;
   bool         _recordPeakUsage;
@@ -193,7 +126,7 @@
   GCCause::Cause _cause;
 public:
   TraceMemoryManagerStats() {}
-  TraceMemoryManagerStats(bool fullGC,
+  TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager,
                           GCCause::Cause cause,
                           bool recordGCBeginTime = true,
                           bool recordPreGCUsage = true,
@@ -203,7 +136,7 @@
                           bool recordGCEndTime = true,
                           bool countCollection = true);
 
-  void initialize(bool fullGC,
+  void initialize(GCMemoryManager* gc_memory_manager,
                   GCCause::Cause cause,
                   bool recordGCBeginTime,
                   bool recordPreGCUsage,
@@ -213,7 +146,6 @@
                   bool recordGCEndTime,
                   bool countCollection);
 
-  TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause);
   ~TraceMemoryManagerStats();
 };
 
--- a/src/hotspot/share/services/psMemoryPool.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/vmSymbols.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/javaCalls.hpp"
-#include "services/lowMemoryDetector.hpp"
-#include "services/management.hpp"
-#include "services/memoryManager.hpp"
-#include "services/psMemoryPool.hpp"
-
-PSGenerationPool::PSGenerationPool(PSOldGen* old_gen,
-                                   const char* name,
-                                   PoolType type,
-                                   bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, old_gen->capacity_in_bytes(),
-                      old_gen->reserved().byte_size(), support_usage_threshold), _old_gen(old_gen) {
-}
-
-MemoryUsage PSGenerationPool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used      = used_in_bytes();
-  size_t committed = _old_gen->capacity_in_bytes();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-// The max size of EdenMutableSpacePool =
-//     max size of the PSYoungGen - capacity of two survivor spaces
-//
-// Max size of PS eden space is changing due to ergonomic.
-// PSYoungGen, PSOldGen, Eden, Survivor spaces are all resizable.
-//
-EdenMutableSpacePool::EdenMutableSpacePool(PSYoungGen* young_gen,
-                                           MutableSpace* space,
-                                           const char* name,
-                                           PoolType type,
-                                           bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, space->capacity_in_bytes(),
-                      (young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes()),
-                       support_usage_threshold),
-  _young_gen(young_gen),
-  _space(space) {
-}
-
-MemoryUsage EdenMutableSpacePool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used = used_in_bytes();
-  size_t committed = _space->capacity_in_bytes();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-// The max size of SurvivorMutableSpacePool =
-//     current capacity of the from-space
-//
-// PS from and to survivor spaces could have different sizes.
-//
-SurvivorMutableSpacePool::SurvivorMutableSpacePool(PSYoungGen* young_gen,
-                                                   const char* name,
-                                                   PoolType type,
-                                                   bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, young_gen->from_space()->capacity_in_bytes(),
-                      young_gen->from_space()->capacity_in_bytes(),
-                      support_usage_threshold), _young_gen(young_gen) {
-}
-
-MemoryUsage SurvivorMutableSpacePool::get_memory_usage() {
-  size_t maxSize = (available_for_allocation() ? max_size() : 0);
-  size_t used    = used_in_bytes();
-  size_t committed = committed_in_bytes();
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
--- a/src/hotspot/share/services/psMemoryPool.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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.
- *
- */
-
-#ifndef SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
-#define SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
-
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/parallel/mutableSpace.hpp"
-#include "gc/parallel/psOldGen.hpp"
-#include "gc/parallel/psYoungGen.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#include "gc/shared/space.hpp"
-#include "memory/heap.hpp"
-#include "services/memoryPool.hpp"
-#include "services/memoryUsage.hpp"
-#endif // INCLUDE_ALL_GCS
-
-class PSGenerationPool : public CollectedMemoryPool {
-private:
-  PSOldGen* _old_gen;
-
-public:
-  PSGenerationPool(PSOldGen* pool, const char* name, PoolType type, bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes()              { return _old_gen->used_in_bytes(); }
-  size_t max_size() const             { return _old_gen->reserved().byte_size(); }
-};
-
-class EdenMutableSpacePool : public CollectedMemoryPool {
-private:
-  PSYoungGen*   _young_gen;
-  MutableSpace* _space;
-
-public:
-  EdenMutableSpacePool(PSYoungGen* young_gen,
-                       MutableSpace* space,
-                       const char* name,
-                       PoolType type,
-                       bool support_usage_threshold);
-
-  MutableSpace* space()                     { return _space; }
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes()                    { return space()->used_in_bytes(); }
-  size_t max_size() const {
-    // Eden's max_size = max_size of Young Gen - the current committed size of survivor spaces
-    return _young_gen->max_size() - _young_gen->from_space()->capacity_in_bytes() - _young_gen->to_space()->capacity_in_bytes();
-  }
-};
-
-class SurvivorMutableSpacePool : public CollectedMemoryPool {
-private:
-  PSYoungGen*   _young_gen;
-
-public:
-  SurvivorMutableSpacePool(PSYoungGen* young_gen,
-                           const char* name,
-                           PoolType type,
-                           bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-
-  size_t used_in_bytes() {
-    return _young_gen->from_space()->used_in_bytes();
-  }
-  size_t committed_in_bytes() {
-    return _young_gen->from_space()->capacity_in_bytes();
-  }
-  size_t max_size() const {
-    // Return current committed size of the from-space
-    return _young_gen->from_space()->capacity_in_bytes();
-  }
-};
-
-#endif // SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
--- a/src/hotspot/share/services/threadService.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/threadService.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -34,9 +34,9 @@
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.inline.hpp"
 #include "runtime/vframe.hpp"
-#include "runtime/thread.inline.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
 #include "services/threadService.hpp"
@@ -148,7 +148,7 @@
 // FIXME: JVMTI should call this function
 Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
   assert(thread != NULL, "should be non-NULL");
-  assert(Threads_lock->owned_by_self(), "must grab Threads_lock or be at safepoint");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   ObjectMonitor *wait_obj = thread->current_waiting_monitor();
 
@@ -266,6 +266,7 @@
 
   int num_snapshots = dump_result.num_snapshots();
   assert(num_snapshots == num_threads, "Must have num_threads thread snapshots");
+  assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");
   int i = 0;
   for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; i++, ts = ts->next()) {
     ThreadStackTrace* stacktrace = ts->get_stack_trace();
@@ -297,7 +298,9 @@
 }
 
 // Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true
-DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks) {
+DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list, bool concurrent_locks) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+
   // This code was modified from the original Threads::find_deadlocks code.
   int globalDfn = 0, thisDfn;
   ObjectMonitor* waitingToLockMonitor = NULL;
@@ -306,15 +309,16 @@
   JavaThread *currentThread, *previousThread;
   int num_deadlocks = 0;
 
-  for (JavaThread* p = Threads::first(); p != NULL; p = p->next()) {
-    // Initialize the depth-first-number
-    p->set_depth_first_number(-1);
+  // Initialize the depth-first-number for each JavaThread.
+  JavaThreadIterator jti(t_list);
+  for (JavaThread* jt = jti.first(); jt != NULL; jt = jti.next()) {
+    jt->set_depth_first_number(-1);
   }
 
   DeadlockCycle* deadlocks = NULL;
   DeadlockCycle* last = NULL;
   DeadlockCycle* cycle = new DeadlockCycle();
-  for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
+  for (JavaThread* jt = jti.first(); jt != NULL; jt = jti.next()) {
     if (jt->depth_first_number() >= 0) {
       // this thread was already visited
       continue;
@@ -339,9 +343,8 @@
       if (waitingToLockMonitor != NULL) {
         address currentOwner = (address)waitingToLockMonitor->owner();
         if (currentOwner != NULL) {
-          currentThread = Threads::owning_thread_from_monitor_owner(
-                            currentOwner,
-                            false /* no locking needed */);
+          currentThread = Threads::owning_thread_from_monitor_owner(t_list,
+                                                                    currentOwner);
           if (currentThread == NULL) {
             // This function is called at a safepoint so the JavaThread
             // that owns waitingToLockMonitor should be findable, but
@@ -366,6 +369,8 @@
         if (concurrent_locks) {
           if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
             oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
+            // This JavaThread (if there is one) is protected by the
+            // ThreadsListSetter in VM_FindDeadlocks::doit().
             currentThread = threadObj != NULL ? java_lang_Thread::thread(threadObj) : NULL;
           } else {
             currentThread = NULL;
@@ -414,7 +419,7 @@
   return deadlocks;
 }
 
-ThreadDumpResult::ThreadDumpResult() : _num_threads(0), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL) {
+ThreadDumpResult::ThreadDumpResult() : _num_threads(0), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL), _setter() {
 
   // Create a new ThreadDumpResult object and append to the list.
   // If GC happens before this function returns, Method*
@@ -422,7 +427,7 @@
   ThreadService::add_thread_dump(this);
 }
 
-ThreadDumpResult::ThreadDumpResult(int num_threads) : _num_threads(num_threads), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL) {
+ThreadDumpResult::ThreadDumpResult(int num_threads) : _num_threads(num_threads), _num_snapshots(0), _snapshots(NULL), _next(NULL), _last(NULL), _setter() {
   // Create a new ThreadDumpResult object and append to the list.
   // If GC happens before this function returns, oops
   // will be visited.
@@ -467,6 +472,10 @@
   }
 }
 
+ThreadsList* ThreadDumpResult::t_list() {
+  return _setter.list();
+}
+
 StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
   _method = jvf->method();
   _bci = jvf->bci();
@@ -683,6 +692,8 @@
     oop o = aos_objects->at(i);
     oop owner_thread_obj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(o);
     if (owner_thread_obj != NULL) {
+      // See comments in ThreadConcurrentLocks to see how this
+      // JavaThread* is protected.
       JavaThread* thread = java_lang_Thread::thread(owner_thread_obj);
       assert(o->is_instance(), "Must be an instanceOop");
       add_lock(thread, (instanceOop) o);
@@ -764,7 +775,7 @@
   memset((void*) _perf_recursion_counts, 0, sizeof(_perf_recursion_counts));
 }
 
-ThreadSnapshot::ThreadSnapshot(JavaThread* thread) {
+ThreadSnapshot::ThreadSnapshot(ThreadsList * t_list, JavaThread* thread) {
   _thread = thread;
   _threadObj = thread->threadObj();
   _stack_trace = NULL;
@@ -796,7 +807,7 @@
       _thread_status = java_lang_Thread::RUNNABLE;
     } else {
       _blocker_object = obj();
-      JavaThread* owner = ObjectSynchronizer::get_lock_owner(obj, false);
+      JavaThread* owner = ObjectSynchronizer::get_lock_owner(t_list, obj);
       if ((owner == NULL && _thread_status == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER)
           || (owner != NULL && owner->is_attaching_via_jni())) {
         // ownership information of the monitor is not available
@@ -865,7 +876,7 @@
   delete _threads;
 }
 
-void DeadlockCycle::print_on(outputStream* st) const {
+void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const {
   st->cr();
   st->print_cr("Found one Java-level deadlock:");
   st->print("=============================");
@@ -895,9 +906,8 @@
         // No Java object associated - a JVMTI raw monitor
         owner_desc = " (JVMTI raw monitor),\n  which is held by";
       }
-      currentThread = Threads::owning_thread_from_monitor_owner(
-                        (address)waitingToLockMonitor->owner(),
-                        false /* no locking needed */);
+      currentThread = Threads::owning_thread_from_monitor_owner(t_list,
+                                                                (address)waitingToLockMonitor->owner());
       if (currentThread == NULL) {
         // The deadlock was detected at a safepoint so the JavaThread
         // that owns waitingToLockMonitor should be findable, but
@@ -915,6 +925,7 @@
              "Must be an AbstractOwnableSynchronizer");
       oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
       currentThread = java_lang_Thread::thread(ownerObj);
+      assert(currentThread != NULL, "AbstractOwnableSynchronizer owning thread is unexpectedly NULL");
     }
     st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name());
   }
@@ -943,9 +954,7 @@
   int init_size = ThreadService::get_live_thread_count();
   _threads_array = new GrowableArray<instanceHandle>(init_size);
 
-  MutexLockerEx ml(Threads_lock);
-
-  for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
     // skips JavaThreads in the process of exiting
     // and also skips VM internal JavaThreads
     // Threads in _thread_new or _thread_new_trans state are included.
--- a/src/hotspot/share/services/threadService.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/services/threadService.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -32,6 +32,7 @@
 #include "runtime/objectMonitor.hpp"
 #include "runtime/objectMonitor.inline.hpp"
 #include "runtime/perfData.hpp"
+#include "runtime/thread.hpp"
 #include "services/management.hpp"
 #include "services/serviceUtil.hpp"
 
@@ -109,7 +110,7 @@
   static void   reset_contention_count_stat(JavaThread* thread);
   static void   reset_contention_time_stat(JavaThread* thread);
 
-  static DeadlockCycle*       find_deadlocks_at_safepoint(bool object_monitors_only);
+  static DeadlockCycle*       find_deadlocks_at_safepoint(ThreadsList * t_list, bool object_monitors_only);
 
   // GC support
   static void   oops_do(OopClosure* f);
@@ -189,6 +190,8 @@
 // Thread snapshot to represent the thread state and statistics
 class ThreadSnapshot : public CHeapObj<mtInternal> {
 private:
+  // This JavaThread* is protected by being stored in objects that are
+  // protected by a ThreadsListSetter (ThreadDumpResult).
   JavaThread* _thread;
   oop         _threadObj;
   java_lang_Thread::ThreadStatus _thread_status;
@@ -213,7 +216,7 @@
   // Dummy snapshot
   ThreadSnapshot() : _thread(NULL), _threadObj(NULL), _stack_trace(NULL), _concurrent_locks(NULL), _next(NULL),
                      _blocker_object(NULL), _blocker_object_owner(NULL) {};
-  ThreadSnapshot(JavaThread* thread);
+  ThreadSnapshot(ThreadsList * t_list, JavaThread* thread);
   ~ThreadSnapshot();
 
   java_lang_Thread::ThreadStatus thread_status() { return _thread_status; }
@@ -310,6 +313,12 @@
 private:
   GrowableArray<instanceOop>* _owned_locks;
   ThreadConcurrentLocks*      _next;
+  // This JavaThread* is protected in one of two different ways
+  // depending on the usage of the ThreadConcurrentLocks object:
+  // 1) by being stored in objects that are only allocated and used at a
+  // safepoint (ConcurrentLocksDump), or 2) by being stored in objects
+  // that are protected by a ThreadsListSetter (ThreadSnapshot inside
+  // ThreadDumpResult).
   JavaThread*                 _thread;
  public:
   ThreadConcurrentLocks(JavaThread* thread);
@@ -333,8 +342,12 @@
   void add_lock(JavaThread* thread, instanceOop o);
 
  public:
-  ConcurrentLocksDump(bool retain_map_on_free) : _map(NULL), _last(NULL), _retain_map_on_free(retain_map_on_free) {};
-  ConcurrentLocksDump() : _map(NULL), _last(NULL), _retain_map_on_free(false) {};
+  ConcurrentLocksDump(bool retain_map_on_free) : _map(NULL), _last(NULL), _retain_map_on_free(retain_map_on_free) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Must be constructed at a safepoint.");
+  };
+  ConcurrentLocksDump() : _map(NULL), _last(NULL), _retain_map_on_free(false) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Must be constructed at a safepoint.");
+  };
   ~ConcurrentLocksDump();
 
   void                        dump_at_safepoint();
@@ -349,6 +362,9 @@
   ThreadSnapshot*      _snapshots;
   ThreadSnapshot*      _last;
   ThreadDumpResult*    _next;
+  ThreadsListSetter    _setter;  // Helper to set hazard ptr in the originating thread
+                                 // which protects the JavaThreads in _snapshots.
+
  public:
   ThreadDumpResult();
   ThreadDumpResult(int num_threads);
@@ -360,6 +376,9 @@
   int                  num_threads()                    { return _num_threads; }
   int                  num_snapshots()                  { return _num_snapshots; }
   ThreadSnapshot*      snapshots()                      { return _snapshots; }
+  void                 set_t_list()                     { _setter.set(); }
+  ThreadsList*         t_list();
+  bool                 t_list_has_been_set()            { return _setter.target_needs_release(); }
   void                 oops_do(OopClosure* f);
   void                 metadata_do(void f(Metadata*));
 };
@@ -381,7 +400,7 @@
   bool           is_deadlock()              { return _is_deadlock; }
   int            num_threads()              { return _threads->length(); }
   GrowableArray<JavaThread*>* threads()     { return _threads; }
-  void           print_on(outputStream* st) const;
+  void           print_on_with(ThreadsList * t_list, outputStream* st) const;
 };
 
 // Utility class to get list of java threads.
--- a/src/hotspot/share/utilities/decoder.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/decoder.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "jvm.h"
+#include "memory/allocation.inline.hpp"
 #include "runtime/os.hpp"
 #include "utilities/decoder.hpp"
 #include "utilities/vmError.hpp"
--- a/src/hotspot/share/utilities/decoder_elf.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/decoder_elf.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 
 #if !defined(_WINDOWS) && !defined(__APPLE__)
 #include "decoder_elf.hpp"
+#include "memory/allocation.inline.hpp"
 
 ElfDecoder::~ElfDecoder() {
   if (_opened_elf_files != NULL) {
--- a/src/hotspot/share/utilities/globalDefinitions.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -951,7 +951,6 @@
 const int      freeBlockPad     = 0xBA;                     // value used to pad freed blocks.
 const int      uninitBlockPad   = 0xF1;                     // value used to zap newly malloc'd blocks.
 const juint    uninitMetaWordVal= 0xf7f7f7f7;               // value used to zap newly allocated metachunk
-const intptr_t badJNIHandleVal  = (intptr_t) UCONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area
 const juint    badHeapWordVal   = 0xBAADBABE;               // value used to zap heap after GC
 const juint    badMetaWordVal   = 0xBAADFADE;               // value used to zap metadata heap after GC
 const int      badCodeHeapNewVal= 0xCC;                     // value used to zap Code heap at allocation
@@ -963,7 +962,6 @@
 #define       badAddress        ((address)::badAddressVal)
 #define       badOop            (cast_to_oop(::badOopVal))
 #define       badHeapWord       (::badHeapWordVal)
-#define       badJNIHandle      (cast_to_oop(::badJNIHandleVal))
 
 // Default TaskQueue size is 16K (32-bit) or 128K (64-bit)
 #define TASKQUEUE_SIZE (NOT_LP64(1<<14) LP64_ONLY(1<<17))
--- a/src/hotspot/share/utilities/growableArray.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/growableArray.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/thread.inline.hpp"
 #include "utilities/growableArray.hpp"
@@ -56,3 +57,7 @@
     return _arena->Amalloc(byte_size);
   }
 }
+
+void GenericGrowableArray::free_C_heap(void* elements) {
+  FreeHeap(elements);
+}
--- a/src/hotspot/share/utilities/growableArray.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/growableArray.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,9 +26,9 @@
 #define SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
 
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
 
 // A growable array.
 
@@ -144,6 +144,8 @@
     assert(on_stack(), "fast ResourceObj path only");
     return (void*)resource_allocate_bytes(thread, elementSize * _max);
   }
+
+  void free_C_heap(void* elements);
 };
 
 template<class E> class GrowableArrayIterator;
@@ -451,7 +453,7 @@
     for (     ; i < _max; i++) ::new ((void*)&newData[i]) E();
     for (i = 0; i < old_max; i++) _data[i].~E();
     if (on_C_heap() && _data != NULL) {
-      FreeHeap(_data);
+      free_C_heap(_data);
     }
     _data = newData;
 }
@@ -475,7 +477,7 @@
     clear();
     if (_data != NULL) {
       for (int i = 0; i < _max; i++) _data[i].~E();
-      FreeHeap(_data);
+      free_C_heap(_data);
       _data = NULL;
     }
 }
--- a/src/hotspot/share/utilities/stack.hpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/stack.hpp	Thu Dec 07 11:54:55 2017 +0000
@@ -26,7 +26,6 @@
 #define SHARE_VM_UTILITIES_STACK_HPP
 
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 
 // Class Stack (below) grows and shrinks by linking together "segments" which
 // are allocated on demand.  Segments are arrays of the element type (E) plus an
--- a/src/hotspot/share/utilities/vmError.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/hotspot/share/utilities/vmError.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 #include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
 #include "runtime/vm_version.hpp"
@@ -1655,7 +1656,12 @@
   char * const dataPtr = NULL;  // bad data pointer
   const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
 
-  // Keep this in sync with test/runtime/ErrorHandling/ErrorHandler.java
+  // Keep this in sync with test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java
+  // which tests cases 1 thru 13.
+  // Case 14 is tested by test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java.
+  // Case 15 is tested by test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java.
+  // Case 16 is tested by test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java.
+  // Case 17 is tested by test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java.
   switch (how) {
     case  1: vmassert(str == NULL, "expected null");
     case  2: vmassert(num == 1023 && *str == 'X',
@@ -1683,6 +1689,17 @@
     case 13: (*funcPtr)(); break;
     case 14: crash_with_segfault(); break;
     case 15: crash_with_sigfpe(); break;
+    case 16: {
+      ThreadsListHandle tlh;
+      fatal("Force crash with an active ThreadsListHandle.");
+    }
+    case 17: {
+      ThreadsListHandle tlh;
+      {
+        ThreadsListHandle tlh2;
+        fatal("Force crash with a nested ThreadsListHandle.");
+      }
+    }
 
     default: tty->print_cr("ERROR: %d: unexpected test_num value.", how);
   }
--- a/src/java.base/share/classes/com/sun/java/util/jar/pack/Constants.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/Constants.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -47,6 +47,7 @@
         1.7 to 1.7.X 51,0
         1.8 to 1.8.X 52,0
         1.9 to 1.9.X 53,0
+        1.10 to 1.10.X 54,0
     */
 
     public static final Package.Version JAVA_MIN_CLASS_VERSION =
@@ -67,6 +68,9 @@
     public static final Package.Version JAVA9_MAX_CLASS_VERSION =
             Package.Version.of(53, 00);
 
+    public static final Package.Version JAVA10_MAX_CLASS_VERSION =
+            Package.Version.of(54, 00);
+
     public static final int JAVA_PACKAGE_MAGIC = 0xCAFED00D;
 
     public static final Package.Version JAVA5_PACKAGE_VERSION =
@@ -83,7 +87,7 @@
 
     // upper limit, should point to the latest class version
     public static final Package.Version JAVA_MAX_CLASS_VERSION =
-            JAVA9_MAX_CLASS_VERSION;
+            JAVA10_MAX_CLASS_VERSION;
 
     // upper limit should point to the latest package version, for version info!.
     public static final Package.Version MAX_PACKAGE_VERSION =
--- a/src/java.base/share/classes/java/io/Reader.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/io/Reader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -26,6 +26,8 @@
 package java.io;
 
 
+import java.util.Objects;
+
 /**
  * Abstract class for reading character streams.  The only methods that a
  * subclass must implement are read(char[], int, int) and close().  Most
@@ -50,6 +52,8 @@
 
 public abstract class Reader implements Readable, Closeable {
 
+    private static final int TRANSFER_BUFFER_SIZE = 8192;
+
     /**
      * The object used to synchronize operations on this stream.  For
      * efficiency, a character-stream object may use an object other than
@@ -262,4 +266,41 @@
      */
      public abstract void close() throws IOException;
 
+    /**
+     * Reads all characters from this reader and writes the characters to the
+     * given writer in the order that they are read. On return, this reader
+     * will be at end of the stream. This method does not close either reader
+     * or writer.
+     * <p>
+     * This method may block indefinitely reading from the reader, or
+     * writing to the writer. The behavior for the case where the reader
+     * and/or writer is <i>asynchronously closed</i>, or the thread
+     * interrupted during the transfer, is highly reader and writer
+     * specific, and therefore not specified.
+     * <p>
+     * If an I/O error occurs reading from the reader or writing to the
+     * writer, then it may do so after some characters have been read or
+     * written. Consequently the reader may not be at end of the stream and
+     * one, or both, streams may be in an inconsistent state. It is strongly
+     * recommended that both streams be promptly closed if an I/O error occurs.
+     *
+     * @param  out the writer, non-null
+     * @return the number of characters transferred
+     * @throws IOException if an I/O error occurs when reading or writing
+     * @throws NullPointerException if {@code out} is {@code null}
+     *
+     * @since 10
+     */
+    public long transferTo(Writer out) throws IOException {
+        Objects.requireNonNull(out, "out");
+        long transferred = 0;
+        char[] buffer = new char[TRANSFER_BUFFER_SIZE];
+        int nRead;
+        while ((nRead = read(buffer, 0, TRANSFER_BUFFER_SIZE)) >= 0) {
+            out.write(buffer, 0, nRead);
+            transferred += nRead;
+        }
+        return transferred;
+    }
+
 }
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import java.io.UncheckedIOException;
 import java.io.File;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.AccessControlContext;
@@ -1867,7 +1868,7 @@
      * to be the system class loader. During construction, the class loader
      * should take great care to avoid calling {@code getSystemClassLoader()}.
      * If circular initialization of the system class loader is detected then
-     * an unspecified error or exception is thrown.
+     * an {@code IllegalStateException} is thrown.
      *
      * @implNote The system property to override the system class loader is not
      * examined until the VM is almost fully initialized. Code that executes
@@ -1918,8 +1919,8 @@
                 // the system class loader is the built-in app class loader during startup
                 return getBuiltinAppClassLoader();
             case 3:
-                String msg = "getSystemClassLoader should only be called after VM booted";
-                throw new InternalError(msg);
+                String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
+                throw new IllegalStateException(msg);
             case 4:
                 // system fully initialized
                 assert VM.isBooted() && scl != null;
@@ -1969,7 +1970,17 @@
                                            .getDeclaredConstructor(ClassLoader.class);
                 scl = (ClassLoader) ctor.newInstance(builtinLoader);
             } catch (Exception e) {
-                throw new Error(e);
+                Throwable cause = e;
+                if (e instanceof InvocationTargetException) {
+                    cause = e.getCause();
+                    if (cause instanceof Error) {
+                        throw (Error) cause;
+                    }
+                }
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                }
+                throw new Error(cause.getMessage(), cause);
             }
         } else {
             scl = builtinLoader;
--- a/src/java.base/share/classes/java/lang/ModuleLayer.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/lang/ModuleLayer.java	Thu Dec 07 11:54:55 2017 +0000
@@ -322,8 +322,8 @@
      * @return The newly created layer
      *
      * @throws IllegalArgumentException
-     *         If the parent of the given configuration is not the configuration
-     *         for this layer
+     *         If the given configuration has more than one parent or the parent
+     *         of the configuration is not the configuration for this layer
      * @throws LayerInstantiationException
      *         If the layer cannot be created for any of the reasons specified
      *         by the static {@code defineModulesWithOneLoader} method
@@ -364,8 +364,8 @@
      * @return The newly created layer
      *
      * @throws IllegalArgumentException
-     *         If the parent of the given configuration is not the configuration
-     *         for this layer
+     *         If the given configuration has more than one parent or the parent
+     *         of the configuration is not the configuration for this layer
      * @throws LayerInstantiationException
      *         If the layer cannot be created for any of the reasons specified
      *         by the static {@code defineModulesWithManyLoaders} method
@@ -403,8 +403,8 @@
      * @return The newly created layer
      *
      * @throws IllegalArgumentException
-     *         If the parent of the given configuration is not the configuration
-     *         for this layer
+     *         If the given configuration has more than one parent or the parent
+     *         of the configuration is not the configuration for this layer
      * @throws LayerInstantiationException
      *         If the layer cannot be created for any of the reasons specified
      *         by the static {@code defineModules} method
@@ -473,8 +473,8 @@
      * @return A controller that controls the newly created layer
      *
      * @throws IllegalArgumentException
-     *         If the parent configurations do not match the configuration of
-     *         the parent layers, including order
+     *         If the parent(s) of the given configuration do not match the
+     *         configuration of the parent layers, including order
      * @throws LayerInstantiationException
      *         If all modules cannot be defined to the same class loader for any
      *         of the reasons listed above
@@ -546,8 +546,8 @@
      * @return A controller that controls the newly created layer
      *
      * @throws IllegalArgumentException
-     *         If the parent configurations do not match the configuration of
-     *         the parent layers, including order
+     *         If the parent(s) of the given configuration do not match the
+     *         configuration of the parent layers, including order
      * @throws LayerInstantiationException
      *         If the layer cannot be created because the configuration contains
      *         a module named "{@code java.base}" or a module contains a package
@@ -637,8 +637,8 @@
      * @return A controller that controls the newly created layer
      *
      * @throws IllegalArgumentException
-     *         If the parent configurations do not match the configuration of
-     *         the parent layers, including order
+     *         If the parent(s) of the given configuration do not match the
+     *         configuration of the parent layers, including order
      * @throws LayerInstantiationException
      *         If creating the layer fails for any of the reasons listed above
      * @throws SecurityException
--- a/src/java.base/share/classes/java/lang/String.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/lang/String.java	Thu Dec 07 11:54:55 2017 +0000
@@ -645,19 +645,6 @@
         this(builder, null);
     }
 
-   /*
-    * Package private constructor which shares value array for speed.
-    * this constructor is always expected to be called with share==true.
-    * a separate constructor is needed because we already have a public
-    * String(char[]) constructor that makes a copy of the given char[].
-    */
-    // TBD: this is kept for package internal use (Thread/System),
-    // should be removed if they all have a byte[] version
-    String(char[] val, boolean share) {
-        // assert share : "unshared not supported";
-        this(val, 0, val.length, null);
-    }
-
     /**
      * Returns the length of this string.
      * The length is equal to the number of <a href="Character.html#unicode">Unicode
--- a/src/java.base/share/classes/java/lang/System.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/lang/System.java	Thu Dec 07 11:54:55 2017 +0000
@@ -2109,9 +2109,6 @@
             public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
                 Shutdown.add(slot, registerShutdownInProgress, hook);
             }
-            public String newStringUnsafe(char[] chars) {
-                return new String(chars, true);
-            }
             public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) {
                 return new Thread(target, acc);
             }
--- a/src/java.base/share/classes/java/lang/module/package-info.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/lang/module/package-info.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,7 +34,7 @@
  * will cause a {@code NullPointerException}, unless otherwise specified. </p>
  *
  *
- * <h1><a id="resolution">Resolution</a></h1>
+ * <h1><a id="resolution">{@index "Module Resolution"}</a></h1>
  *
  * <p> Resolution is the process of computing how modules depend on each other.
  * The process occurs at compile time and run time. </p>
--- a/src/java.base/share/classes/java/security/IdentityScope.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/security/IdentityScope.java	Thu Dec 07 11:54:55 2017 +0000
@@ -90,8 +90,8 @@
             try {
                 Class.forName(classname);
             } catch (ClassNotFoundException e) {
-                //Security.error("unable to establish a system scope from " +
-                //             classname);
+                System.err.println("unable to establish a system scope from " +
+                             classname);
                 e.printStackTrace();
             }
         }
--- a/src/java.base/share/classes/java/security/Signature.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/security/Signature.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1074,7 +1074,7 @@
                             debug.println("Further warnings of this type will "
                                 + "be suppressed");
                         }
-                        new Exception("Call trace").printStackTrace();
+                        new Exception("Debug call trace").printStackTrace();
                     }
                 }
                 Exception lastException = null;
--- a/src/java.base/share/classes/java/text/MessageFormat.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/text/MessageFormat.java	Thu Dec 07 11:54:55 2017 +0000
@@ -701,6 +701,10 @@
      *            larger than the number of format elements in the pattern string
      */
     public void setFormat(int formatElementIndex, Format newFormat) {
+
+        if (formatElementIndex > maxOffset) {
+            throw new ArrayIndexOutOfBoundsException(formatElementIndex);
+        }
         formats[formatElementIndex] = newFormat;
     }
 
--- a/src/java.base/share/classes/java/util/StringJoiner.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/util/StringJoiner.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,9 +24,6 @@
  */
 package java.util;
 
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
-
 /**
  * {@code StringJoiner} is used to construct a sequence of characters separated
  * by a delimiter and optionally starting with a supplied prefix
@@ -86,8 +83,6 @@
      */
     private String emptyValue;
 
-    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-
     /**
      * Constructs a {@code StringJoiner} with no characters in it, with no
      * {@code prefix} or {@code suffix}, and a copy of the supplied
@@ -189,7 +184,7 @@
             }
         }
         k += getChars(suffix, chars, k);
-        return jla.newStringUnsafe(chars);
+        return new String(chars);
     }
 
     /**
@@ -252,7 +247,7 @@
                 elts[i] = null;
             } while (++i < size);
             size = 1;
-            elts[0] = jla.newStringUnsafe(chars);
+            elts[0] = new String(chars);
         }
     }
 
--- a/src/java.base/share/classes/java/util/jar/JarFile.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java	Thu Dec 07 11:54:55 2017 +0000
@@ -43,17 +43,12 @@
 import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
-import java.util.Spliterator;
-import java.util.Spliterators;
-import java.util.stream.Collector;
+import java.util.function.Function;
 import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
@@ -566,7 +561,14 @@
      * given entry name or {@code null} if not found.
      */
     private JarFileEntry getEntry0(String name) {
-        return (JarFileEntry)JUZFA.getEntry(this, name, JarFileEntry::new);
+        // Not using a lambda/method reference here to optimize startup time
+        Function<String, JarEntry> newJarFileEntryFn = new Function<>() {
+            @Override
+            public JarEntry apply(String name) {
+                return new JarFileEntry(name);
+            }
+        };
+        return (JarFileEntry)JUZFA.getEntry(this, name, newJarFileEntryFn);
     }
 
     private String getBasename(String name) {
--- a/src/java.base/share/classes/java/util/stream/Stream.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/java/util/stream/Stream.java	Thu Dec 07 11:54:55 2017 +0000
@@ -671,7 +671,8 @@
      * <p>This is a <a href="package-summary.html#StreamOps">terminal
      * operation</a>.
      *
-     * @return an array containing the elements of this stream
+     * @return an array, whose {@linkplain Class#getComponentType runtime component
+     * type} is {@code Object}, containing the elements of this stream
      */
     Object[] toArray();
 
@@ -694,13 +695,13 @@
      *                          .toArray(Person[]::new);
      * }</pre>
      *
-     * @param <A> the element type of the resulting array
+     * @param <A> the component type of the resulting array
      * @param generator a function which produces a new array of the desired
      *                  type and the provided length
      * @return an array containing the elements in this stream
-     * @throws ArrayStoreException if the runtime type of the array returned
-     * from the array generator is not a supertype of the runtime type of every
-     * element in this stream
+     * @throws ArrayStoreException if the runtime type of any element of this
+     *         stream is not assignable to the {@linkplain Class#getComponentType
+     *         runtime component type} of the generated array
      */
     <A> A[] toArray(IntFunction<A[]> generator);
 
--- a/src/java.base/share/classes/jdk/internal/loader/Loader.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/Loader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -28,7 +28,6 @@
 import java.io.File;
 import java.io.FilePermission;
 import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.lang.module.Configuration;
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleReader;
@@ -58,12 +57,8 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.Spliterator;
-import java.util.Spliterators;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Supplier;
 import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
 
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.module.Resources;
@@ -403,12 +398,15 @@
 
         // this loader
         URL url = findResource(name);
-        if (url != null) {
-            return url;
-        } else {
+        if (url == null) {
             // parent loader
-            return parent.getResource(name);
+            if (parent != null) {
+                url = parent.getResource(name);
+            } else {
+                url = BootLoader.findResource(name);
+            }
         }
+        return url;
     }
 
     @Override
@@ -419,7 +417,12 @@
         List<URL> urls = findResourcesAsList(name);
 
         // parent loader
-        Enumeration<URL> e = parent.getResources(name);
+        Enumeration<URL> e;
+        if (parent != null) {
+            e = parent.getResources(name);
+        } else {
+            e = BootLoader.findResources(name);
+        }
 
         // concat the URLs with the URLs returned by the parent
         return new Enumeration<>() {
@@ -439,25 +442,6 @@
         };
     }
 
-    @Override
-    public Stream<URL> resources(String name) {
-        Objects.requireNonNull(name);
-        // ordering not specified
-        int characteristics = (Spliterator.NONNULL | Spliterator.IMMUTABLE |
-                               Spliterator.SIZED | Spliterator.SUBSIZED);
-        Supplier<Spliterator<URL>> supplier = () -> {
-            try {
-                List<URL> urls = findResourcesAsList(name);
-                return Spliterators.spliterator(urls, characteristics);
-            } catch (IOException e) {
-                throw new UncheckedIOException(e);
-            }
-        };
-        Stream<URL> s1 = StreamSupport.stream(supplier, characteristics, false);
-        Stream<URL> s2 = parent.resources(name);
-        return Stream.concat(s1, s2);
-    }
-
     /**
      * Finds the resources with the given name in this class loader.
      */
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Thu Dec 07 11:54:55 2017 +0000
@@ -124,16 +124,6 @@
     void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook);
 
     /**
-     * Returns a new string backed by the provided character array. The
-     * character array is not copied and must never be modified after the
-     * String is created, in order to fulfill String's contract.
-     *
-     * @param chars the character array to back the string
-     * @return a newly created string whose content is the character array
-     */
-    String newStringUnsafe(char[] chars);
-
-    /**
      * Returns a new Thread with the given Runnable and an
      * inherited AccessControlContext.
      */
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -185,7 +185,7 @@
     public ClassReader(final byte[] b, final int off, final int len) {
         this.b = b;
         // checks the class version
-        if (readShort(off + 6) > Opcodes.V9) {
+        if (readShort(off + 6) > Opcodes.V10) {
             throw new IllegalArgumentException();
         }
         // parses the constant pool
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Thu Dec 07 11:54:55 2017 +0000
@@ -89,6 +89,7 @@
     int V1_7 = 0 << 16 | 51;
     int V1_8 = 0 << 16 | 52;
     int V9 = 0 << 16 | 53;
+    int V10 = 0 << 16 | 54;
 
     // access flags
 
--- a/src/java.base/share/classes/sun/security/jca/ProviderList.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/jca/ProviderList.java	Thu Dec 07 11:54:55 2017 +0000
@@ -308,7 +308,7 @@
         }
         if (debug != null) {
             debug.println("Loading all providers");
-            new Exception("Call trace").printStackTrace();
+            new Exception("Debug Info. Call trace:").printStackTrace();
         }
         int n = 0;
         for (int i = 0; i < configs.length; i++) {
--- a/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java	Thu Dec 07 11:54:55 2017 +0000
@@ -346,7 +346,6 @@
             }
 
         } catch (IOException e) {
-            // e.printStackTrace ();
             throw new InvalidKeyException("IOException : " +
                                           e.getMessage());
         }
--- a/src/java.base/share/classes/sun/security/provider/AuthPolicyFile.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/AuthPolicyFile.java	Thu Dec 07 11:54:55 2017 +0000
@@ -187,6 +187,7 @@
             } catch (Exception e) {
                 // ignore, treat it like we have no keystore
                 if (debug != null) {
+                    debug.println("Debug info only. No keystore.");
                     e.printStackTrace();
                 }
                 return null;
@@ -261,7 +262,7 @@
                 loaded_one = true;
             } catch (Exception e) {
                 if (debug != null) {
-                    debug.println("error reading policy " + e);
+                    debug.println("Debug info only. Error reading policy " + e);
                     e.printStackTrace();
                 }
                 // ignore that policy
--- a/src/java.base/share/classes/sun/security/provider/DSA.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/DSA.java	Thu Dec 07 11:54:55 2017 +0000
@@ -490,18 +490,6 @@
         return printable;
     }
 
-    private static void debug(Exception e) {
-        if (debug) {
-            e.printStackTrace();
-        }
-    }
-
-    private static void debug(String s) {
-        if (debug) {
-            System.err.println(s);
-        }
-    }
-
     /**
      * Standard SHA224withDSA implementation as defined in FIPS186-3.
      */
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Thu Dec 07 11:54:55 2017 +0000
@@ -512,7 +512,8 @@
                         }
                     } catch (Exception e) {
                         if (debug != null) {
-                            debug.println("error reading policy "+e);
+                            debug.println(
+                                "Debug info only. Error reading policy " +e);
                             e.printStackTrace();
                         }
                         // ignore that policy
@@ -559,6 +560,7 @@
             } catch (Exception e) {
                 // ignore, treat it like we have no keystore
                 if (debug != null) {
+                    debug.println("Debug info only. Ignoring exception.");
                     e.printStackTrace();
                 }
             }
--- a/src/java.base/share/classes/sun/security/util/AnchorCertificates.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/util/AnchorCertificates.java	Thu Dec 07 11:54:55 2017 +0000
@@ -75,8 +75,8 @@
                 } catch (Exception e) {
                     if (debug != null) {
                         debug.println("Error parsing cacerts");
+                        e.printStackTrace();
                     }
-                    e.printStackTrace();
                 }
                 return null;
             }
--- a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Thu Dec 07 11:54:55 2017 +0000
@@ -386,8 +386,9 @@
                     if (e.getMessage() != null) {
                         debug.println(key + ":  " + e.getMessage());
                     } else {
-                        debug.println(key + ":  " + algorithm +
-                                " was disabled, no exception msg given.");
+                        debug.println("Debug info only. " +  key + ":  " +
+                            algorithm +
+                            " was disabled, no exception msg given.");
                         e.printStackTrace();
                     }
                 }
--- a/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/x509/CertificateExtensions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -124,7 +124,8 @@
                 unparseableExtensions.put(ext.getExtensionId().toString(),
                         new UnparseableExtension(ext, e));
                 if (debug != null) {
-                    debug.println("Error parsing extension: " + ext);
+                    debug.println("Debug info only." +
+                       " Error parsing extension: " + ext);
                     e.printStackTrace();
                     HexDumpEncoder h = new HexDumpEncoder();
                     System.err.println(h.encodeBuffer(ext.getExtensionValue()));
--- a/src/java.base/share/classes/sun/security/x509/X509Key.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/classes/sun/security/x509/X509Key.java	Thu Dec 07 11:54:55 2017 +0000
@@ -392,7 +392,6 @@
                 throw new InvalidKeyException ("excess key data");
 
         } catch (IOException e) {
-            // e.printStackTrace ();
             throw new InvalidKeyException("IOException: " +
                                           e.getMessage());
         }
--- a/src/java.base/share/lib/security/default.policy	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/lib/security/default.policy	Thu Dec 07 11:54:55 2017 +0000
@@ -155,7 +155,10 @@
 };
 
 grant codeBase "jrt:/jdk.internal.vm.compiler.management" {
-    permission java.security.AllPermission;
+    permission java.lang.RuntimePermission "accessClassInPackage.org.graalvm.compiler.hotspot";
+    permission java.lang.RuntimePermission "accessClassInPackage.jdk.vm.ci.runtime";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.management.spi";
+    permission java.lang.RuntimePermission "sun.management.spi.PlatformMBeanProvider.subclass";
 };
 
 grant codeBase "jrt:/jdk.jsobject" {
--- a/src/java.base/share/native/include/classfile_constants.h	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/native/include/classfile_constants.h	Thu Dec 07 11:54:55 2017 +0000
@@ -31,7 +31,7 @@
 #endif
 
 /* Classfile version number for this information */
-#define JVM_CLASSFILE_MAJOR_VERSION 53
+#define JVM_CLASSFILE_MAJOR_VERSION 54
 #define JVM_CLASSFILE_MINOR_VERSION 0
 
 /* Flags */
--- a/src/java.base/share/native/libjava/System.c	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.base/share/native/libjava/System.c	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, 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
@@ -114,7 +114,7 @@
 #define VENDOR_URL_BUG "http://bugreport.java.com/bugreport/"
 #endif
 
-#define JAVA_MAX_SUPPORTED_VERSION 53
+#define JAVA_MAX_SUPPORTED_VERSION 54
 #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
 
 #ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
--- a/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -22,22 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package com.sun.jmx.remote.security;
 
 import com.sun.jmx.mbeanserver.GetPropertyAction;
 import com.sun.jmx.mbeanserver.Util;
-import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FilePermission;
 import java.io.IOException;
 import java.security.AccessControlException;
 import java.security.AccessController;
 import java.util.Arrays;
-import java.util.Hashtable;
 import java.util.Map;
-import java.util.Properties;
 
 import javax.security.auth.*;
 import javax.security.auth.callback.*;
@@ -59,10 +54,7 @@
  * the access control file for JMX remote management or in a Java security
  * policy.
  *
- * <p> The password file comprises a list of key-value pairs as specified in
- * {@link Properties}. The key represents a user's name and the value is its
- * associated cleartext password. By default, the following password file is
- * used:
+ * By default, the following password file is used:
  * <pre>
  *     ${java.home}/conf/management/jmxremote.password
  * </pre>
@@ -105,6 +97,11 @@
  * <dd> if <code>true</code>, this module clears the username and password
  *      stored in the module's shared state after both phases of authentication
  *      (login and commit) have completed.</dd>
+ *
+ * <dt> <code>hashPasswords</code> </dt>
+ * <dd> if <code>true</code>, this module replaces each clear text password
+ * with its hash, if present. </dd>
+ *
  * </dl>
  */
 public class FileLoginModule implements LoginModule {
@@ -135,6 +132,7 @@
     private boolean tryFirstPass = false;
     private boolean storePass = false;
     private boolean clearPass = false;
+    private boolean hashPasswords = false;
 
     // Authentication status
     private boolean succeeded = false;
@@ -154,7 +152,7 @@
     private String passwordFileDisplayName;
     private boolean userSuppliedPasswordFile;
     private boolean hasJavaHomePermission;
-    private Properties userCredentials;
+    private HashedPasswordManager hashPwdMgr;
 
     /**
      * Initialize this <code>LoginModule</code>.
@@ -186,6 +184,8 @@
                 "true".equalsIgnoreCase((String)options.get("storePass"));
         clearPass =
                 "true".equalsIgnoreCase((String)options.get("clearPass"));
+        hashPasswords
+                = "true".equalsIgnoreCase((String) options.get("hashPasswords"));
 
         passwordFile = (String)options.get("passwordFile");
         passwordFileDisplayName = passwordFile;
@@ -221,17 +221,28 @@
     public boolean login() throws LoginException {
 
         try {
-            loadPasswordFile();
+            synchronized (this) {
+                if (hashPwdMgr == null) {
+                    hashPwdMgr = new HashedPasswordManager(passwordFile, hashPasswords);
+                }
+            }
+            hashPwdMgr.loadPasswords();
         } catch (IOException ioe) {
             LoginException le = new LoginException(
                     "Error: unable to load the password file: " +
                     passwordFileDisplayName);
             throw EnvHelp.initCause(le, ioe);
-        }
-
-        if (userCredentials == null) {
-            throw new LoginException
-                ("Error: unable to locate the users' credentials.");
+        } catch (SecurityException e) {
+            if (userSuppliedPasswordFile || hasJavaHomePermission) {
+                throw e;
+            } else {
+                final FilePermission fp
+                        = new FilePermission(passwordFileDisplayName, "read");
+                AccessControlException ace = new AccessControlException(
+                        "access denied " + fp.toString());
+                ace.initCause(e);
+                throw ace;
+            }
         }
 
         if (logger.debugOn()) {
@@ -437,12 +448,7 @@
         // get the username and password
         getUsernamePassword(usePasswdFromSharedState);
 
-        String localPassword;
-
-        // userCredentials is initialized in login()
-        if (((localPassword = userCredentials.getProperty(username)) == null) ||
-            (! localPassword.equals(new String(password)))) {
-
+        if (!hashPwdMgr.authenticate(username, password)) {
             // username not found or passwords do not match
             if (logger.debugOn()) {
                 logger.debug("login", "Invalid username or password");
@@ -468,38 +474,6 @@
         }
     }
 
-    /*
-     * Read the password file.
-     */
-    private void loadPasswordFile() throws IOException {
-        FileInputStream fis;
-        try {
-            fis = new FileInputStream(passwordFile);
-        } catch (SecurityException e) {
-            if (userSuppliedPasswordFile || hasJavaHomePermission) {
-                throw e;
-            } else {
-                final FilePermission fp =
-                        new FilePermission(passwordFileDisplayName, "read");
-                AccessControlException ace = new AccessControlException(
-                        "access denied " + fp.toString());
-                ace.setStackTrace(e.getStackTrace());
-                throw ace;
-            }
-        }
-        try {
-            final BufferedInputStream bis = new BufferedInputStream(fis);
-            try {
-                userCredentials = new Properties();
-                userCredentials.load(bis);
-            } finally {
-                bis.close();
-            }
-        } finally {
-            fis.close();
-        }
-    }
-
     /**
      * Get the username and password.
      * This method does not return any value.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management/share/classes/com/sun/jmx/remote/security/HashedPasswordManager.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package com.sun.jmx.remote.security;
+
+import com.sun.jmx.remote.util.ClassLogger;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileLock;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * HashedPasswordManager loads passwords from the password file and optionally
+ * hashes them.
+ * <p>
+ * <p>
+ * This class accepts Unicode UTF-8 encoded file
+ * <p>
+ * <p>
+ * Each entry in the password file contains a username followed by a password.
+ * Password can be in clear text or as a hash. Hashed passwords must follow the
+ * below format. hashedPassword = base64_encoded_64_byte_salt W
+ * base64_encoded_hash W hash_algorithm where, W = spaces,
+ * base64_encoded_64_byte_salt = 64 byte random salt, base64_encoded_hash =
+ * hash_algorithm(password + salt), hash_algorithm = Algorithm string as
+ * specified in
+ * <a href="{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
+ * </a>
+ * hash_algorithm is an optional field. If not specified, SHA3-512 will be
+ * assumed.
+ * <p>
+ * <p>
+ * If passwords are in clear, they will be over-written by their hash if hashing
+ * is requested by setting com.sun.management.jmxremote.password.toHashes
+ * property to true in the management.properties file and if the password file
+ * is writable and if the system security policy allows writing into the
+ * password file, if a security manager is configured
+ * <p>
+ * <p>
+ * In order to change the password for a role, replace the hashed password entry
+ * with a new clear text password or a new hashed password. If the new password
+ * is in clear, it will be replaced with its hash when a new login attempt is
+ * made.
+ * <p>
+ * <p>
+ * A given role should have at most one entry in this file. If a role has no
+ * entry, it has no access. If multiple entries are found for the same role
+ * name, then the last one will be used.
+ * <p>
+ * <p>
+ * <p>
+ * A user generated hashed password file can also be used instead of a
+ * clear-text password file. If generated by the user, hashed passwords must
+ * follow the format specified above.
+ */
+final public class HashedPasswordManager {
+
+    private static final class UserCredentials {
+
+        private final String userName;
+        private final String hashAlgorithm;
+        private final String b64Salt;
+        private final String b64Hash;
+
+        public UserCredentials(String userName, String hashAlgorithm, String b64Salt, String b64Hash) {
+            this.userName = userName;
+            this.hashAlgorithm = hashAlgorithm;
+            this.b64Salt = b64Salt;
+            this.b64Hash = b64Hash;
+        }
+
+        @Override
+        public String toString() {
+            return userName + " " + b64Salt + " " + b64Hash + " " + hashAlgorithm;
+        }
+    }
+
+    private static final String DefaultHashAlgorithm = "SHA3-512";
+    private static final int DefaultSaltLength = 64;
+
+    private final SecureRandom random = new SecureRandom();
+    private final Map<String, UserCredentials> userCredentialsMap = new HashMap<>();
+    private final String passwordFile;
+    private final boolean shouldHashPasswords;
+    private boolean isLogged = false;
+
+    private static final ClassLogger logger
+            = new ClassLogger("javax.management.remote.misc",
+                    "HashedPasswordManager");
+
+    /**
+     * Creates a new password manager for the input password file
+     *
+     * @param filename UTF-8 encoded input file to read passwords from
+     * @param shouldHashPasswords Request for clear passwords to be hashed
+     */
+    public HashedPasswordManager(String filename, boolean shouldHashPasswords) {
+        this.passwordFile = filename;
+        this.shouldHashPasswords = shouldHashPasswords;
+    }
+
+    private String[] getHash(String algorithm, String password) {
+        try {
+            byte[] salt = new byte[DefaultSaltLength];
+            random.nextBytes(salt);
+
+            MessageDigest digest = MessageDigest.getInstance(algorithm);
+            digest.reset();
+            digest.update(salt);
+            byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
+            String saltStr = Base64.getEncoder().encodeToString(salt);
+            String hashStr = Base64.getEncoder().encodeToString(hash);
+
+            return new String[]{saltStr, hashStr};
+        } catch (NoSuchAlgorithmException ex) {
+            if (logger.debugOn()) {
+                logger.debug("getHash", "Invalid algorithm : " + algorithm);
+            }
+            // We should never reach here as default Hash Algorithm
+            // must be always present
+            return new String[]{"", ""};
+        }
+    }
+
+    private String[] readPasswordFile() throws IOException {
+        synchronized (HashedPasswordManager.class) {
+            byte[] data;
+            File f = new File(passwordFile);
+            try (FileInputStream fin = new FileInputStream(f);
+                    FileLock lock = fin.getChannel().lock(0L, Long.MAX_VALUE, true)) {
+                data = new byte[(int) f.length()];
+                int read = fin.read(data);
+                if (read != data.length) {
+                    throw new IOException("Failed to read data from the password file");
+                }
+                lock.release();
+            }
+            String str = new String(data, StandardCharsets.UTF_8);
+            return str.split("\\r?\\n");
+        }
+    }
+
+    private void writePasswordFile(String input) throws IOException {
+        synchronized (HashedPasswordManager.class) {
+            try (FileOutputStream fout = new FileOutputStream(passwordFile);
+                    OutputStreamWriter out = new OutputStreamWriter(fout, StandardCharsets.UTF_8);
+                    FileLock lock = fout.getChannel().lock()) {
+                out.write(input);
+                lock.release();
+            }
+        }
+    }
+
+    /**
+     * Authenticate the supplied credentials against the one present in the file
+     *
+     * @param userName Input username
+     * @param inputPassword Input password
+     * @return true if authentication succeeds, false otherwise
+     */
+    public synchronized boolean authenticate(String userName, char[] inputPassword) {
+        if (userCredentialsMap.containsKey(userName)) {
+            try {
+                UserCredentials us = userCredentialsMap.get(userName);
+                byte[] salt = Base64.getDecoder().decode(us.b64Salt);
+                byte[] targetHash = Base64.getDecoder().decode(us.b64Hash);
+                MessageDigest digest = MessageDigest.getInstance(us.hashAlgorithm);
+                digest.reset();
+                digest.update(salt);
+                ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(CharBuffer.wrap(inputPassword));
+                byte[] passwordBytes = new byte[byteBuffer.limit()];
+                byteBuffer.get(passwordBytes);
+                byte[] hash = digest.digest(passwordBytes);
+                return Arrays.equals(hash, targetHash);
+            } catch (NoSuchAlgorithmException ex) {
+                if (logger.debugOn()) {
+                    logger.debug("authenticate", "Unrecognized hash algorithm : "
+                            + userCredentialsMap.get(userName).hashAlgorithm
+                            + " - for user : " + userName);
+                }
+                return false;
+            }
+        } else {
+            if (logger.debugOn()) {
+                logger.debug("authenticate", "Unknown user : " + userName);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Load passwords from the password file.
+     * <p>
+     * <p>
+     * This method should be called for every login attempt to load new/changed
+     * credentials, if any.
+     * <p>
+     * <p>
+     * If hashing is requested, clear passwords will be over-written with their
+     * SHA3-512 hash
+     *
+     * @throws IOException If unable to access the file
+     * @throws SecurityException If read/write file permissions are not granted
+     */
+    public synchronized void loadPasswords()
+            throws IOException, SecurityException {
+
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkRead(passwordFile);
+        }
+
+        AtomicBoolean hasClearPasswords = new AtomicBoolean(false);
+        StringBuilder sbuf = new StringBuilder();
+        final String header = "# The passwords in this file are hashed.\n"
+                + "# In order to change the password for a role, replace the hashed "
+                + "password entry\n"
+                + "# with a clear text password or a new hashed password. "
+                + "If the new password is in clear,\n# it will be replaced with its "
+                + "hash when a new login attempt is made.\n\n";
+
+        userCredentialsMap.clear();
+        Arrays.stream(readPasswordFile()).forEach(line -> {
+            if (line.trim().startsWith("#")) {   // Ignore comments
+                sbuf.append(line).append("\n");
+                return;
+            }
+            String[] tokens = line.split("\\s+");
+            switch (tokens.length) {
+                case 2: {
+                    // Password is in clear
+                    String[] b64str = getHash(DefaultHashAlgorithm, tokens[1]);
+                    UserCredentials us = new UserCredentials(tokens[0], DefaultHashAlgorithm, b64str[0], b64str[1]);
+                    sbuf.append(us.userName).append(" ").append(us.b64Salt).
+                            append(" ").append(us.b64Hash).append(" ").
+                            append(us.hashAlgorithm).append("\n");
+                    if (userCredentialsMap.get(tokens[0]) != null) {
+                        if (logger.debugOn()) {
+                            logger.debug("loadPasswords", "Ignoring entry for role : " + tokens[0]);
+                        }
+                    }
+                    userCredentialsMap.put(tokens[0], us);
+                    hasClearPasswords.set(true);
+                    if (logger.debugOn()) {
+                        logger.debug("loadPasswords",
+                                "Found atleast one clear password");
+                    }
+                    break;
+                }
+                case 3:
+                case 4: {
+                    // Passwords are hashed
+                    UserCredentials us = new UserCredentials(tokens[0], (tokens.length == 4 ? tokens[3] : DefaultHashAlgorithm),
+                            tokens[1], tokens[2]);
+                    sbuf.append(line).append("\n");
+                    if (userCredentialsMap.get(tokens[0]) != null) {
+                        if (logger.debugOn()) {
+                            logger.debug("loadPasswords", "Ignoring entry for role : " + tokens[0]);
+                        }
+                    }
+                    userCredentialsMap.put(tokens[0], us);
+                    break;
+                }
+                default:
+                    sbuf.append(line).append("\n");
+                    break;
+            }
+        });
+
+        if (!shouldHashPasswords && hasClearPasswords.get()) {
+            if (logger.debugOn()) {
+                logger.debug("loadPasswords",
+                        "Passwords in " + passwordFile + " are in clear but are requested "
+                        + "not to be hashed !!!");
+            }
+        }
+
+        // Check if header needs to be inserted
+        if (sbuf.indexOf("# The passwords in this file are hashed") != 0) {
+            sbuf.insert(0, header);
+        }
+
+        // Even if we are unable to write hashed passwords to password file,
+        // passwords will be hashed in memory so that jvm heap dump should not
+        // give away clear passwords
+        if (shouldHashPasswords && hasClearPasswords.get()) {
+            if (new File(passwordFile).canWrite()) {
+                writePasswordFile(sbuf.toString());
+                if (logger.debugOn()) {
+                    logger.debug("loadPasswords",
+                            "Wrote hashed passwords to file : " + passwordFile);
+                }
+            } else if (logger.debugOn() && !isLogged) {
+                isLogged = true;
+                logger.debug("loadPasswords",
+                        "Passwords in " + passwordFile + " are in clear and password file is read-only. "
+                        + "Passwords cannot be hashed !!!!");
+            }
+        }
+    }
+}
--- a/src/java.management/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.management/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -34,8 +34,6 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Properties;
-import javax.management.remote.JMXPrincipal;
 import javax.management.remote.JMXAuthenticator;
 import javax.security.auth.AuthPermission;
 import javax.security.auth.Subject;
@@ -91,10 +89,12 @@
 
         String loginConfigName = null;
         String passwordFile = null;
+        String hashPasswords = null;
 
         if (env != null) {
             loginConfigName = (String) env.get(LOGIN_CONFIG_PROP);
             passwordFile = (String) env.get(PASSWORD_FILE_PROP);
+            hashPasswords = (String) env.get(HASH_PASSWORDS);
         }
 
         try {
@@ -114,6 +114,7 @@
                 }
 
                 final String pf = passwordFile;
+                final String hashPass = hashPasswords;
                 try {
                     loginContext = AccessController.doPrivileged(
                         new PrivilegedExceptionAction<LoginContext>() {
@@ -122,7 +123,7 @@
                                                 LOGIN_CONFIG_NAME,
                                                 null,
                                                 new JMXCallbackHandler(),
-                                                new FileLoginConfig(pf));
+                                                new FileLoginConfig(pf, hashPass));
                             }
                         });
                 } catch (PrivilegedActionException pae) {
@@ -250,6 +251,8 @@
     private static final String LOGIN_CONFIG_NAME = "JMXPluggableAuthenticator";
     private static final String PASSWORD_FILE_PROP =
         "jmx.remote.x.password.file";
+    private static final String HASH_PASSWORDS =
+        "jmx.remote.x.password.toHashes";
     private static final ClassLogger logger =
         new ClassLogger("javax.management.remote.misc", LOGIN_CONFIG_NAME);
 
@@ -303,19 +306,22 @@
 
     // The option that identifies the password file to use
     private static final String PASSWORD_FILE_OPTION = "passwordFile";
+    private static final String HASH_PASSWORDS = "hashPasswords";
 
     /**
      * Creates an instance of <code>FileLoginConfig</code>
      *
      * @param passwordFile A filepath that identifies the password file to use.
      *                     If null then the default password file is used.
+     * @param hashPasswords Flag to indicate if the password file needs to be hashed
      */
-    public FileLoginConfig(String passwordFile) {
+    public FileLoginConfig(String passwordFile, String hashPasswords) {
 
         Map<String, String> options;
         if (passwordFile != null) {
             options = new HashMap<String, String>(1);
             options.put(PASSWORD_FILE_OPTION, passwordFile);
+            options.put(HASH_PASSWORDS, hashPasswords);
         } else {
             options = Collections.emptyMap();
         }
--- a/src/java.sql/share/classes/java/sql/Date.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.sql/share/classes/java/sql/Date.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,8 +27,6 @@
 
 import java.time.Instant;
 import java.time.LocalDate;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.misc.JavaLangAccess;
 
 /**
  * <P>A thin wrapper around a millisecond value that allows
@@ -46,8 +44,6 @@
  */
 public class Date extends java.util.Date {
 
-    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-
     /**
      * Constructs a <code>Date</code> object initialized with the given
      * year, month, and day.
@@ -168,7 +164,7 @@
         buf[7] = '-';
         Date.formatDecimalInt(day, buf, 8, 2);
 
-        return jla.newStringUnsafe(buf);
+        return new String(buf);
     }
 
     /**
--- a/src/java.sql/share/classes/java/sql/Time.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.sql/share/classes/java/sql/Time.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,8 +27,6 @@
 
 import java.time.Instant;
 import java.time.LocalTime;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.misc.JavaLangAccess;
 
 /**
  * <P>A thin wrapper around the <code>java.util.Date</code> class that allows the JDBC
@@ -43,8 +41,6 @@
  */
 public class Time extends java.util.Date {
 
-    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-
     /**
      * Constructs a <code>Time</code> object initialized with the
      * given values for the hour, minute, and second.
@@ -134,7 +130,7 @@
         buf[5] = ':';
         Date.formatDecimalInt(second, buf, 6, 2);
 
-        return jla.newStringUnsafe(buf);
+        return new String(buf);
     }
 
     // Override all the date operations inherited from java.util.Date;
--- a/src/java.sql/share/classes/java/sql/Timestamp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/java.sql/share/classes/java/sql/Timestamp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,8 +27,6 @@
 
 import java.time.Instant;
 import java.time.LocalDateTime;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.misc.JavaLangAccess;
 
 /**
  * <P>A thin wrapper around {@code java.util.Date} that allows
@@ -74,8 +72,6 @@
  */
 public class Timestamp extends java.util.Date {
 
-    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-
     /**
      * Constructs a {@code Timestamp} object initialized
      * with the given values.
@@ -313,7 +309,7 @@
         buf[yearSize + 15] = '.';
         Date.formatDecimalInt(tmpNanos, buf, yearSize + 16, 9 - trailingZeros);
 
-        return jla.newStringUnsafe(buf);
+        return new String(buf);
     }
 
     /**
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Thu Dec 07 11:54:55 2017 +0000
@@ -65,6 +65,8 @@
 
     private final int codeEntryAlignment;
 
+    private final boolean threadLocalHandshakes;
+
     /**
      * Container holding code bits and any other related information.
      */
@@ -279,6 +281,8 @@
 
         this.codeEntryAlignment = graalHotSpotVMConfig.codeEntryAlignment;
 
+        this.threadLocalHandshakes = graalHotSpotVMConfig.threadLocalHandshakes;
+
         // Section unique name is limited to 8 characters due to limitation on Windows.
         // Name could be longer but only first 8 characters are stored on Windows.
 
@@ -323,7 +327,8 @@
                                    TieredAOT.getValue(graalOptions),
                                    graalHotSpotVMConfig.enableContended,
                                    graalHotSpotVMConfig.restrictContended,
-                                   graphBuilderConfig.omitAssertions()
+                                   graphBuilderConfig.omitAssertions(),
+                                   graalHotSpotVMConfig.threadLocalHandshakes
         };
 
         int[] intFlags         = { graalHotSpotVMConfig.getOopEncoding().getShift(),
@@ -434,6 +439,11 @@
         return codeEntryAlignment;
     }
 
+    public boolean getThreadLocalHandshakes() {
+        return threadLocalHandshakes;
+    }
+
+
     /**
      * Gets the global AOT symbol associated with the function name.
      *
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java	Thu Dec 07 11:54:55 2017 +0000
@@ -45,6 +45,7 @@
      * @param methodInfo compiled method info
      * @param mark mark being processed
      */
+    @SuppressWarnings("fallthrough")
     void process(CompiledMethodInfo methodInfo, Mark mark) {
         MarkId markId = MarkId.getEnum((int) mark.id);
         switch (markId) {
@@ -53,6 +54,11 @@
                 break;
             case POLL_FAR:
             case POLL_RETURN_FAR:
+                if (binaryContainer.getThreadLocalHandshakes()) {
+                    // skip relocation
+                    break;
+                }
+                // fallthrough
             case CARD_TABLE_ADDRESS:
             case HEAP_TOP_ADDRESS:
             case HEAP_END_ADDRESS:
--- a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java	Thu Dec 07 11:54:55 2017 +0000
@@ -86,18 +86,23 @@
     private void loadAgentLibrary(String agentLibrary, boolean isAbsolute, String options)
         throws AgentLoadException, AgentInitializationException, IOException
     {
+        String msgPrefix = "return code: ";
         InputStream in = execute("load",
                                  agentLibrary,
                                  isAbsolute ? "true" : "false",
                                  options);
-        try {
-            int result = readInt(in);
-            if (result != 0) {
-                throw new AgentInitializationException("Agent_OnAttach failed", result);
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
+            String result = reader.readLine();
+            if (result == null) {
+                throw new AgentLoadException("Target VM did not respond");
+            } else if (result.startsWith(msgPrefix)) {
+                int retCode = Integer.parseInt(result.substring(msgPrefix.length()));
+                if (retCode != 0) {
+                    throw new AgentInitializationException("Agent_OnAttach failed", retCode);
+                }
+            } else {
+                throw new AgentLoadException(result);
             }
-        } finally {
-            in.close();
-
         }
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Dec 07 11:54:55 2017 +0000
@@ -3236,12 +3236,10 @@
                                                     make.Ident(index)).setType(elemtype);
             JCVariableDecl loopvardef = (JCVariableDecl)make.VarDef(tree.var.mods,
                                                   tree.var.name,
-                                                  tree.var.vartype, null).setType(tree.var.type);
+                                                  tree.var.vartype, loopvarinit).setType(tree.var.type);
             loopvardef.sym = tree.var.sym;
 
-            JCStatement loopVarAssign = make.Assignment(tree.var.sym, loopvarinit);
-            JCBlock body = make.
-                Block(0, List.of(loopVarAssign, tree.body));
+            JCBlock body = make.Block(0, List.of(loopvardef, tree.body));
 
             arraycachedef = translate(arraycachedef);
             result = translate(make.
@@ -3251,12 +3249,7 @@
                                        body));
             patchTargets(body, tree, result);
             JCStatement nullAssignToArr = make.Assignment(arraycache, make.Literal(BOT, null).setType(syms.botType));
-            JCStatement nullAssignToLoopVar = tree.var.type.isPrimitive() ?
-                    null :
-                    make.Assignment(tree.var.sym, make.Literal(BOT, null).setType(syms.botType));
-            result = nullAssignToLoopVar == null ?
-                    make.Block(0, List.of(arraycachedef, loopvardef, (JCStatement)result, nullAssignToArr)):
-                    make.Block(0, List.of(arraycachedef, loopvardef, (JCStatement)result, nullAssignToArr, nullAssignToLoopVar));
+            result = make.Block(0, List.of(arraycachedef, (JCStatement)result, nullAssignToArr));
         }
         /** Patch up break and continue targets. */
         private void patchTargets(JCTree body, final JCTree src, final JCTree dest) {
@@ -3310,7 +3303,7 @@
                                             types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
                                             currentMethodSym);
 
-             JCStatement init = make.
+            JCStatement init = make.
                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
                      .setType(types.erasure(iterator.type))));
 
@@ -3331,10 +3324,9 @@
             JCVariableDecl indexDef = (JCVariableDecl)make.VarDef(tree.var.mods,
                                                   tree.var.name,
                                                   tree.var.vartype,
-                                                  null).setType(tree.var.type);
+                                                  vardefinit).setType(tree.var.type);
             indexDef.sym = tree.var.sym;
-            JCStatement loopVarAssign = make.Assignment(tree.var.sym, vardefinit);
-            JCBlock body = make.Block(0, List.of(loopVarAssign, tree.body));
+            JCBlock body = make.Block(0, List.of(indexDef, tree.body));
             body.endpos = TreeInfo.endPos(tree.body);
             init = translate(init);
             result = translate(make.
@@ -3344,12 +3336,7 @@
                         body));
             patchTargets(body, tree, result);
             JCStatement nullAssignToIterator = make.Assignment(itvar, make.Literal(BOT, null).setType(syms.botType));
-            JCStatement nullAssignToLoopVar = tree.var.type.isPrimitive() ?
-                    null :
-                    make.Assignment(tree.var.sym, make.Literal(BOT, null).setType(syms.botType));
-            result = nullAssignToLoopVar == null ?
-                    make.Block(0, List.of(init, indexDef, (JCStatement)result, nullAssignToIterator)):
-                    make.Block(0, List.of(init, indexDef, (JCStatement)result, nullAssignToIterator, nullAssignToLoopVar));
+            result = make.Block(0, List.of(init, (JCStatement)result, nullAssignToIterator));
         }
 
     public void visitVarDef(JCVariableDecl tree) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -110,7 +110,8 @@
         V50(50, 0),   // JDK 1.6: stackmaps
         V51(51, 0),   // JDK 1.7
         V52(52, 0),   // JDK 1.8: lambda, type annos, param names
-        V53(53, 0);   // JDK 1.9: modules, indy string concat
+        V53(53, 0),   // JDK 1.9: modules, indy string concat
+        V54(54, 0);   // JDK 10
         Version(int major, int minor) {
             this.major = major;
             this.minor = minor;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -2684,7 +2684,7 @@
 
         minorVersion = nextChar();
         majorVersion = nextChar();
-        int maxMajor = 53; // Version.MAX().major;  //******* TEMPORARY *******
+        int maxMajor = Version.MAX().major;
         int maxMinor = Version.MAX().minor;
         if (majorVersion > maxMajor ||
             majorVersion * 1000 + minorVersion <
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -1815,15 +1815,8 @@
         acount += writeExtraClassAttributes(c);
 
         poolbuf.appendInt(JAVA_MAGIC);
-
-        if (c.owner.kind == MDL) {
-            // temporarily overide to force use of v53 for module-info.class
-            poolbuf.appendChar(0);
-            poolbuf.appendChar(53);
-        } else {
-            poolbuf.appendChar(target.minorVersion);
-            poolbuf.appendChar(target.majorVersion);
-        }
+        poolbuf.appendChar(target.minorVersion);
+        poolbuf.appendChar(target.majorVersion);
 
         writePool(c.pool);
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java	Thu Dec 07 11:54:55 2017 +0000
@@ -63,8 +63,8 @@
     /** JDK 9. */
     JDK1_9("1.9", 53, 0),
 
-    /** JDK 10, initially an alias for 9 */
-    JDK1_10("1.10", 53, 0);
+    /** JDK 10. */
+    JDK1_10("1.10", 54, 0);
 
     private static final Context.Key<Target> targetKey = new Context.Key<>();
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Dec 07 11:54:55 2017 +0000
@@ -197,9 +197,18 @@
         for (ModuleSymbol msym : modules.allModules()) {
             S sym = nameToSymbol(msym, nameStr, clazz);
 
-            if (sym != null) {
-                if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
-                    //do not add packages without members:
+            if (sym == null)
+                continue;
+
+            if (clazz == ClassSymbol.class) {
+                // Always include classes
+                found.add(sym);
+            } else if (clazz == PackageSymbol.class) {
+                // In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages.
+                // For example, if a module contains classes or package info in package p.q.r, it will also appear
+                // to have additional packages p.q and p, even though these packages have no content other
+                // than the subpackage.  We don't want those empty packages showing up in searches for p or p.q.
+                if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) {
                     found.add(sym);
                 }
             }
--- a/src/jdk.hotspot.agent/macosx/native/libsaproc/BsdDebuggerLocal.c	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/BsdDebuggerLocal.c	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -298,9 +298,6 @@
 #ifdef i386
 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
 #endif
-#ifdef ia64
-#define NPRGREG IA64_REG_COUNT
-#endif
 #ifdef amd64
 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
 #endif
@@ -335,14 +332,6 @@
 
 #endif /* i386 */
 
-#if ia64
-  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
-  int i;
-  for (i = 0; i < NPRGREG; i++ ) {
-    regs[i] = 0xDEADDEAD;
-  }
-#endif /* ia64 */
-
 #ifdef amd64
 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -35,7 +35,6 @@
 import sun.jvm.hotspot.debugger.MachineDescriptionAMD64;
 import sun.jvm.hotspot.debugger.MachineDescriptionPPC64;
 import sun.jvm.hotspot.debugger.MachineDescriptionAArch64;
-import sun.jvm.hotspot.debugger.MachineDescriptionIA64;
 import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86;
 import sun.jvm.hotspot.debugger.MachineDescriptionSPARC32Bit;
 import sun.jvm.hotspot.debugger.MachineDescriptionSPARC64Bit;
@@ -556,10 +555,8 @@
             machDesc = new MachineDescriptionIntelX86();
         } else if (cpu.equals("amd64")) {
             machDesc = new MachineDescriptionAMD64();
-        } else if (cpu.equals("ia64")) {
-            machDesc = new MachineDescriptionIA64();
         } else {
-            throw new DebuggerException("Win32 supported under x86, amd64 and ia64 only");
+            throw new DebuggerException("Win32 supported under x86 and amd64 only");
         }
 
         // Note we do not use a cache for the local debugger in server
@@ -586,8 +583,6 @@
 
         if (cpu.equals("x86")) {
             machDesc = new MachineDescriptionIntelX86();
-        } else if (cpu.equals("ia64")) {
-            machDesc = new MachineDescriptionIA64();
         } else if (cpu.equals("amd64")) {
             machDesc = new MachineDescriptionAMD64();
         } else if (cpu.equals("ppc64")) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIA64.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, 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 sun.jvm.hotspot.debugger;
-
-public class MachineDescriptionIA64 extends MachineDescriptionTwosComplement implements MachineDescription {
-  public long getAddressSize() {
-    return 8;
-  }
-
-  public boolean isLP64() {
-    return true;
-  }
-
-  public boolean isBigEndian() {
-    return false;
-  }
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -216,11 +216,7 @@
             // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
             // size must be adjusted to be the hardware's page size.
             // (FIXME: should pick this up from the debugger.)
-            if (getCPU().equals("ia64")) {
-              initCache(16384, parseCacheNumPagesProperty(1024));
-            } else {
-              initCache(4096, parseCacheNumPagesProperty(4096));
-            }
+            initCache(4096, parseCacheNumPagesProperty(4096));
         }
 
         isDarwin = getOS().equals("darwin");
@@ -575,11 +571,6 @@
 
     public CDebugger getCDebugger() {
       if (cdbg == null) {
-         String cpu = getCPU();
-         if (cpu.equals("ia64") ) {
-            // IA-64 is not supported because of stack-walking issues
-            return null;
-         }
          cdbg = new BsdCDebugger(this);
       }
       return cdbg;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, 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 sun.jvm.hotspot.debugger.ia64;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-
-/** Specifies the thread context on ia64 platform; only a sub-portion
-    of the context is guaranteed to be present on all operating
-    systems. */
-
-public abstract class IA64ThreadContext implements ThreadContext {
-  // Refer to winnt.h CONTEXT structure - Nov 2001 edition Platform SDK
-  // only a relevant subset of CONTEXT structure is used here.
-  // For eg. floating point registers are ignored.
-
-  // NOTE: the indices for the various registers must be maintained as
-  // listed across various operating systems. However, only a
-  // subset of the registers' values are guaranteed to be present
-
-  // global registers r0-r31
-  public static final int GR0  = 0;
-  public static final int GR1  = 1;
-  public static final int GR2  = 2;
-  public static final int GR3  = 3;
-  public static final int GR4  = 4;
-  public static final int GR5  = 5;
-  public static final int GR6  = 6;
-  public static final int GR7  = 7;
-  public static final int GR8  = 8;
-  public static final int GR9  = 9;
-  public static final int GR10 = 10;
-  public static final int GR11 = 11;
-  public static final int GR12 = 12;
-  public static final int SP = GR12;
-  public static final int GR13 = 13;
-  public static final int GR14 = 14;
-  public static final int GR15 = 15;
-  public static final int GR16 = 16;
-  public static final int GR17 = 17;
-  public static final int GR18 = 18;
-  public static final int GR19 = 19;
-  public static final int GR20 = 20;
-  public static final int GR21 = 21;
-  public static final int GR22 = 22;
-  public static final int GR23 = 23;
-  public static final int GR24 = 24;
-  public static final int GR25 = 25;
-  public static final int GR26 = 26;
-  public static final int GR27 = 27;
-  public static final int GR28 = 28;
-  public static final int GR29 = 29;
-  public static final int GR30 = 30;
-  public static final int GR31 = 31;
-
-  // Nat bits for r1-r31
-  public static final int INT_NATS = 32;
-
-  // predicates
-  public static final int PREDS    = 33;
-
-  // branch registers
-  public static final int BR0      = 34;
-  public static final int BR_RP    = BR0;
-  public static final int BR1      = 35;
-  public static final int BR2      = 36;
-  public static final int BR3      = 37;
-  public static final int BR4      = 38;
-  public static final int BR5      = 39;
-  public static final int BR6      = 40;
-  public static final int BR7      = 41;
-
-  // application registers
-  public static final int AP_UNAT  = 42; // User Nat Collection register
-  public static final int AP_LC    = 43; // Loop counter register
-  public static final int AP_EC    = 43; // Epilog counter register
-  public static final int AP_CCV   = 45; // CMPXCHG value register
-  public static final int AP_DCR   = 46; // Default control register
-
-  // register stack info
-  public static final int RS_PFS   = 47; // Previous function state
-  public static final int AP_PFS   = RS_PFS;
-  public static final int RS_BSP   = 48; // Backing store pointer
-  public static final int AR_BSP   = RS_BSP;
-  public static final int RS_BSPSTORE = 49;
-  public static final int AP_BSPSTORE = RS_BSPSTORE;
-  public static final int RS_RSC   = 50;     // RSE configuration
-  public static final int AP_RSC   = RS_RSC;
-  public static final int RS_RNAT  = 51; // RSE Nat collection register
-  public static final int AP_RNAT  = RS_RNAT;
-
-  // trap status register
-  public static final int ST_IPSR  = 52; // Interuption Processor Status
-  public static final int ST_IIP   = 53; // Interruption IP
-  public static final int ST_IFS   = 54; // Interruption Function State
-
-  // debug registers
-  public static final int DB_I0    = 55;
-  public static final int DB_I1    = 56;
-  public static final int DB_I2    = 57;
-  public static final int DB_I3    = 58;
-  public static final int DB_I4    = 59;
-  public static final int DB_I5    = 60;
-  public static final int DB_I6    = 61;
-  public static final int DB_I7    = 62;
-
-  public static final int DB_D0    = 63;
-  public static final int DB_D1    = 64;
-  public static final int DB_D2    = 65;
-  public static final int DB_D3    = 66;
-  public static final int DB_D4    = 67;
-  public static final int DB_D5    = 68;
-  public static final int DB_D6    = 69;
-  public static final int DB_D7    = 70;
-
-  public static final int NPRGREG  = 71;
-
-  private static final String[] regNames = {
-     "GR0", "GR1", "GR2", "GR3", "GR4", "GR5", "GR6", "GR7", "GR8",
-     "GR9", "GR10", "GR11", "GR12", "GR13", "GR14", "GR15", "GR16",
-     "GR17","GR18", "GR19", "GR20", "GR21", "GR22", "GR23", "GR24",
-     "GR25","GR26", "GR27", "GR28", "GR29", "GR30", "GR31",
-     "INT_NATS", "PREDS",
-     "BR0", "BR1", "BR2", "BR3", "BR4", "BR5", "BR6", "BR7",
-     "AP_UNAT", "AP_LC", "AP_EC", "AP_CCV", "AP_DCR",
-     "RS_FPS", "RS_BSP", "RS_BSPSTORE", "RS_RSC", "RS_RNAT",
-     "ST_IPSR", "ST_IIP", "ST_IFS",
-     "DB_I0", "DB_I1", "DB_I2", "DB_I3", "DB_I4", "DB_I5", "DB_I6", "DB_I7",
-     "DB_D0", "DB_D1", "DB_D2", "DB_D3", "DB_D4", "DB_D5", "DB_D6", "DB_D7"
-  };
-
-  private long[] data;
-
-  public IA64ThreadContext() {
-    data = new long[NPRGREG];
-  }
-
-  public int getNumRegisters() {
-    return NPRGREG;
-  }
-
-  public String getRegisterName(int index) {
-    return regNames[index];
-  }
-
-  public void setRegister(int index, long value) {
-    data[index] = value;
-  }
-
-  public long getRegister(int index) {
-    return data[index];
-  }
-
-  public CFrame getTopFrame(Debugger dbg) {
-    return null;
-  }
-
-  /** This can't be implemented in this class since we would have to
-      tie the implementation to, for example, the debugging system */
-  public abstract void setRegisterAsAddress(int index, Address value);
-
-  /** This can't be implemented in this class since we would have to
-      tie the implementation to, for example, the debugging system */
-  public abstract Address getRegisterAsAddress(int index);
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -210,11 +210,7 @@
             // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
             // size must be adjusted to be the hardware's page size.
             // (FIXME: should pick this up from the debugger.)
-            if (getCPU().equals("ia64")) {
-              initCache(16384, parseCacheNumPagesProperty(1024));
-            } else {
-              initCache(4096, parseCacheNumPagesProperty(4096));
-            }
+            initCache(4096, parseCacheNumPagesProperty(4096));
         }
 
         workerThread = new LinuxDebuggerLocalWorkerThread(this);
@@ -560,11 +556,6 @@
 
     public CDebugger getCDebugger() {
       if (cdbg == null) {
-         String cpu = getCPU();
-         if (cpu.equals("ia64") ) {
-            // IA-64 is not supported because of stack-walking issues
-            return null;
-         }
          cdbg = new LinuxCDebugger(this);
       }
       return cdbg;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -27,7 +27,6 @@
 import java.lang.reflect.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.linux.amd64.*;
-import sun.jvm.hotspot.debugger.linux.ia64.*;
 import sun.jvm.hotspot.debugger.linux.x86.*;
 import sun.jvm.hotspot.debugger.linux.ppc64.*;
 import sun.jvm.hotspot.debugger.linux.sparc.*;
@@ -39,8 +38,6 @@
          return new LinuxX86ThreadContext(dbg);
       } else if (cpu.equals("amd64")) {
          return new LinuxAMD64ThreadContext(dbg);
-      } else if (cpu.equals("ia64")) {
-         return new LinuxIA64ThreadContext(dbg);
       } else if (cpu.equals("sparc")) {
          return new LinuxSPARCThreadContext(dbg);
       }  else if (cpu.equals("ppc64")) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/ia64/LinuxIA64ThreadContext.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.jvm.hotspot.debugger.linux.ia64;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.ia64.*;
-import sun.jvm.hotspot.debugger.linux.*;
-
-public class LinuxIA64ThreadContext extends IA64ThreadContext {
-  private LinuxDebugger debugger;
-
-  public LinuxIA64ThreadContext(LinuxDebugger debugger) {
-    super();
-    this.debugger = debugger;
-  }
-
-  public void setRegisterAsAddress(int index, Address value) {
-    setRegister(index, debugger.getAddressValue(value));
-  }
-
-  public Address getRegisterAsAddress(int index) {
-    return debugger.newAddress(getRegister(index));
-  }
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -30,10 +30,8 @@
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.amd64.*;
 import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.debugger.ia64.*;
 import sun.jvm.hotspot.debugger.windbg.amd64.*;
 import sun.jvm.hotspot.debugger.windbg.x86.*;
-import sun.jvm.hotspot.debugger.windbg.ia64.*;
 import sun.jvm.hotspot.debugger.win32.coff.*;
 import sun.jvm.hotspot.debugger.cdbg.*;
 import sun.jvm.hotspot.debugger.cdbg.basic.BasicDebugEvent;
@@ -115,8 +113,6 @@
        threadFactory = new WindbgX86ThreadFactory(this);
     } else if (cpu.equals("amd64")) {
        threadFactory = new WindbgAMD64ThreadFactory(this);
-    } else if (cpu.equals("ia64")) {
-       threadFactory = new WindbgIA64ThreadFactory(this);
     }
 
     if (useCache) {
@@ -231,11 +227,7 @@
 
   public CDebugger getCDebugger() throws DebuggerException {
     if (cdbg == null) {
-      // FIXME: CDebugger is not yet supported for IA64 because
-      // of native stack walking issues.
-      if (! getCPU().equals("ia64")) {
-         cdbg = new WindbgCDebugger(this);
-      }
+      cdbg = new WindbgCDebugger(this);
     }
     return cdbg;
   }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64Thread.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.jvm.hotspot.debugger.windbg.ia64;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.ia64.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-
-class WindbgIA64Thread implements ThreadProxy {
-  private WindbgDebugger debugger;
-  private long           sysId;
-  private boolean        gotID;
-  private long           id;
-
-  /** The address argument must be the address of the HANDLE of the
-      desired thread in the target process. */
-  WindbgIA64Thread(WindbgDebugger debugger, Address addr) {
-    this.debugger = debugger;
-    // FIXME: size of data fetched here should be configurable.
-    // However, making it so would produce a dependency on the "types"
-    // package from the debugger package, which is not desired.
-
-    // another hack here is that we use sys thread id instead of handle.
-    // windbg can't get details based on handles it seems.
-    // I assume that osThread_win32 thread struct has _thread_id (which
-    // sys thread id) just after handle field.
-
-    this.sysId   = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
-    gotID = false;
-  }
-
-  WindbgIA64Thread(WindbgDebugger debugger, long sysId) {
-    this.debugger = debugger;
-    this.sysId    = sysId;
-    gotID         = false;
-  }
-
-  public ThreadContext getContext() throws IllegalThreadStateException {
-    long[] data = debugger.getThreadIntegerRegisterSet(getThreadID());
-    WindbgIA64ThreadContext context = new WindbgIA64ThreadContext(debugger);
-    for (int i = 0; i < data.length; i++) {
-      context.setRegister(i, data[i]);
-    }
-    return context;
-  }
-
-  public boolean canSetContext() throws DebuggerException {
-    return false;
-  }
-
-  public void setContext(ThreadContext thrCtx)
-    throws IllegalThreadStateException, DebuggerException {
-    throw new DebuggerException("Unimplemented");
-  }
-
-  public boolean equals(Object obj) {
-    if ((obj == null) || !(obj instanceof WindbgIA64Thread)) {
-      return false;
-    }
-
-    return (((WindbgIA64Thread) obj).getThreadID() == getThreadID());
-  }
-
-  public int hashCode() {
-    return (int) getThreadID();
-  }
-
-  public String toString() {
-    return Long.toString(getThreadID());
-  }
-
-  /** Retrieves the thread ID of this thread by examining the Thread
-      Information Block. */
-  private long getThreadID() {
-    if (!gotID) {
-       id = debugger.getThreadIdFromSysId(sysId);
-    }
-
-    return id;
-  }
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64ThreadContext.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.jvm.hotspot.debugger.windbg.ia64;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.ia64.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-
-class WindbgIA64ThreadContext extends IA64ThreadContext {
-  private WindbgDebugger debugger;
-
-  public WindbgIA64ThreadContext(WindbgDebugger debugger) {
-    super();
-    this.debugger = debugger;
-  }
-
-  public void setRegisterAsAddress(int index, Address value) {
-    setRegister(index, debugger.getAddressValue(value));
-  }
-
-  public Address getRegisterAsAddress(int index) {
-    return debugger.newAddress(getRegister(index));
-  }
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/ia64/WindbgIA64ThreadFactory.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.jvm.hotspot.debugger.windbg.ia64;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-
-public class WindbgIA64ThreadFactory implements WindbgThreadFactory {
-  private WindbgDebugger debugger;
-
-  public WindbgIA64ThreadFactory(WindbgDebugger debugger) {
-    this.debugger = debugger;
-  }
-
-  public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
-    return new WindbgIA64Thread(debugger, threadIdentifierAddr);
-  }
-
-  public ThreadProxy createThreadWrapper(long id) {
-    return new WindbgIA64Thread(debugger, id);
-  }
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Dec 07 11:54:55 2017 +0000
@@ -474,20 +474,48 @@
   }
 
   // same as enum InnerClassAttributeOffset in VM code.
-  public static interface InnerClassAttributeOffset {
+  private static class InnerClassAttributeOffset {
     // from JVM spec. "InnerClasses" attribute
-    public static final int innerClassInnerClassInfoOffset = 0;
-    public static final int innerClassOuterClassInfoOffset = 1;
-    public static final int innerClassInnerNameOffset = 2;
-    public static final int innerClassAccessFlagsOffset = 3;
-    public static final int innerClassNextOffset = 4;
-  };
+    public static int innerClassInnerClassInfoOffset;
+    public static int innerClassOuterClassInfoOffset;
+    public static int innerClassInnerNameOffset;
+    public static int innerClassAccessFlagsOffset;
+    public static int innerClassNextOffset;
+    static {
+      VM.registerVMInitializedObserver(new Observer() {
+          public void update(Observable o, Object data) {
+              initialize(VM.getVM().getTypeDataBase());
+          }
+      });
+    }
 
-  public static interface EnclosingMethodAttributeOffset {
-    public static final int enclosing_method_class_index_offset = 0;
-    public static final int enclosing_method_method_index_offset = 1;
-    public static final int enclosing_method_attribute_size = 2;
-  };
+    private static synchronized void initialize(TypeDataBase db) {
+      innerClassInnerClassInfoOffset = db.lookupIntConstant(
+          "InstanceKlass::inner_class_inner_class_info_offset").intValue();
+      innerClassOuterClassInfoOffset = db.lookupIntConstant(
+          "InstanceKlass::inner_class_outer_class_info_offset").intValue();
+      innerClassInnerNameOffset = db.lookupIntConstant(
+          "InstanceKlass::inner_class_inner_name_offset").intValue();
+      innerClassAccessFlagsOffset = db.lookupIntConstant(
+          "InstanceKlass::inner_class_access_flags_offset").intValue();
+      innerClassNextOffset = db.lookupIntConstant(
+          "InstanceKlass::inner_class_next_offset").intValue();
+    }
+  }
+
+  private static class EnclosingMethodAttributeOffset {
+    public static int enclosingMethodAttributeSize;
+    static {
+      VM.registerVMInitializedObserver(new Observer() {
+          public void update(Observable o, Object data) {
+              initialize(VM.getVM().getTypeDataBase());
+          }
+      });
+    }
+    private static synchronized void initialize(TypeDataBase db) {
+      enclosingMethodAttributeSize = db.lookupIntConstant("InstanceKlass::enclosing_method_attribute_size").intValue();
+    }
+  }
 
   // refer to compute_modifier_flags in VM code.
   public long computeModifierFlags() {
@@ -498,11 +526,11 @@
     if (length > 0) {
        if (Assert.ASSERTS_ENABLED) {
           Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
-                      length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
+                      length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosingMethodAttributeSize,
                       "just checking");
        }
        for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
-          if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
+          if (i == length - EnclosingMethodAttributeOffset.enclosingMethodAttributeSize) {
               break;
           }
           int ioff = innerClassList.at(i +
@@ -547,11 +575,11 @@
     if (length > 0) {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
-                     length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
+                     length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosingMethodAttributeSize,
                      "just checking");
        }
        for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
-         if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
+         if (i == length - EnclosingMethodAttributeOffset.enclosingMethodAttributeSize) {
              break;
          }
          int ioff = innerClassList.at(i +
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Oop.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Oop.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -202,8 +202,7 @@
 
   public boolean verify() { return true;}
 
-  // Package-private routine to speed up ObjectHeap.newOop
-  static Klass getKlassForOopHandle(OopHandle handle) {
+  public static Klass getKlassForOopHandle(OopHandle handle) {
     if (handle == null) {
       return null;
     }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -41,6 +41,7 @@
 
   // java.lang.Class fields
   static int klassOffset;
+  static int arrayKlassOffset;
   static IntField oopSizeField;
 
   static {
@@ -56,6 +57,7 @@
     // find them from InstanceKlass for java.lang.Class.
     Type jlc = db.lookupType("java_lang_Class");
     klassOffset = (int) jlc.getCIntegerField("_klass_offset").getValue();
+    arrayKlassOffset = (int) jlc.getCIntegerField("_array_klass_offset").getValue();
     int oopSizeOffset = (int) jlc.getCIntegerField("_oop_size_offset").getValue();
     oopSizeField = new IntField(new NamedFieldIdentifier("oop_size"), oopSizeOffset, true);
   }
@@ -69,4 +71,23 @@
   public static long getOopSize(Oop aClass) {
     return java_lang_Class.oopSizeField.getValue(aClass);
   }
+
+  /**
+   * Returns the Java name for this Java mirror
+   */
+  public static String asExternalName(Oop aClass) {
+    Klass k = java_lang_Class.asKlass(aClass);
+    if (k == null) { // primitive array
+      BasicType type = BasicType.T_VOID;
+      ArrayKlass ak = (ArrayKlass)Metadata.instantiateWrapperFor(
+                             aClass.getHandle().getAddressAt(arrayKlassOffset));
+      if (ak != null) {
+        type = BasicType.intToBasicType(ak.getElementType());
+      }
+      return type.getName();
+    } else {
+      return k.getName().asString();
+    }
+  }
+
 }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/BasicType.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/BasicType.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,113 +24,160 @@
 
 package sun.jvm.hotspot.runtime;
 
+import java.util.Observer;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+
 /** Encapsulates the BasicType enum in globalDefinitions.hpp in the
     VM. */
 
 public class BasicType {
-  public static final int tBoolean     = 4;
-  public static final int tChar        = 5;
-  public static final int tFloat       = 6;
-  public static final int tDouble      = 7;
-  public static final int tByte        = 8;
-  public static final int tShort       = 9;
-  public static final int tInt         = 10;
-  public static final int tLong        = 11;
-  public static final int tObject      = 12;
-  public static final int tArray       = 13;
-  public static final int tVoid        = 14;
-  public static final int tAddress     = 15;
-  public static final int tNarrowOop   = 16;
-  public static final int tMetadata    = 17;
-  public static final int tNarrowKlass = 18;
-  public static final int tConflict    = 19;
-  public static final int tIllegal     = 99;
+  public static final BasicType T_BOOLEAN = new BasicType();
+  public static final BasicType T_CHAR = new BasicType();
+  public static final BasicType T_FLOAT = new BasicType();
+  public static final BasicType T_DOUBLE = new BasicType();
+  public static final BasicType T_BYTE = new BasicType();
+  public static final BasicType T_SHORT = new BasicType();
+  public static final BasicType T_INT = new BasicType();
+  public static final BasicType T_LONG = new BasicType();
+  public static final BasicType T_OBJECT = new BasicType();
+  public static final BasicType T_ARRAY = new BasicType();
+  public static final BasicType T_VOID = new BasicType();
+  public static final BasicType T_ADDRESS = new BasicType();
+  public static final BasicType T_NARROWOOP = new BasicType();
+  public static final BasicType T_METADATA = new BasicType();
+  public static final BasicType T_NARROWKLASS = new BasicType();
+  public static final BasicType T_CONFLICT = new BasicType();
+  public static final BasicType T_ILLEGAL = new BasicType();
 
-  public static final BasicType T_BOOLEAN = new BasicType(tBoolean);
-  public static final BasicType T_CHAR = new BasicType(tChar);
-  public static final BasicType T_FLOAT = new BasicType(tFloat);
-  public static final BasicType T_DOUBLE = new BasicType(tDouble);
-  public static final BasicType T_BYTE = new BasicType(tByte);
-  public static final BasicType T_SHORT = new BasicType(tShort);
-  public static final BasicType T_INT = new BasicType(tInt);
-  public static final BasicType T_LONG = new BasicType(tLong);
-  public static final BasicType T_OBJECT = new BasicType(tObject);
-  public static final BasicType T_ARRAY = new BasicType(tArray);
-  public static final BasicType T_VOID = new BasicType(tVoid);
-  public static final BasicType T_ADDRESS = new BasicType(tAddress);
-  public static final BasicType T_NARROWOOP = new BasicType(tNarrowOop);
-  public static final BasicType T_METADATA = new BasicType(tMetadata);
-  public static final BasicType T_NARROWKLASS = new BasicType(tNarrowKlass);
-  public static final BasicType T_CONFLICT = new BasicType(tConflict);
-  public static final BasicType T_ILLEGAL = new BasicType(tIllegal);
+  static {
+    VM.registerVMInitializedObserver(
+        (o, d) -> initialize(VM.getVM().getTypeDataBase()));
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    T_BOOLEAN.setType(db.lookupIntConstant("T_BOOLEAN").intValue());
+    T_CHAR.setType(db.lookupIntConstant("T_CHAR").intValue());
+    T_FLOAT.setType(db.lookupIntConstant("T_FLOAT").intValue());
+    T_DOUBLE.setType(db.lookupIntConstant("T_DOUBLE").intValue());
+    T_BYTE.setType(db.lookupIntConstant("T_BYTE").intValue());
+    T_SHORT.setType(db.lookupIntConstant("T_SHORT").intValue());
+    T_INT.setType(db.lookupIntConstant("T_INT").intValue());
+    T_LONG.setType(db.lookupIntConstant("T_LONG").intValue());
+    T_OBJECT.setType(db.lookupIntConstant("T_OBJECT").intValue());
+    T_ARRAY.setType(db.lookupIntConstant("T_ARRAY").intValue());
+    T_VOID.setType(db.lookupIntConstant("T_VOID").intValue());
+    T_ADDRESS.setType(db.lookupIntConstant("T_ADDRESS").intValue());
+    T_NARROWOOP.setType(db.lookupIntConstant("T_NARROWOOP").intValue());
+    T_METADATA.setType(db.lookupIntConstant("T_METADATA").intValue());
+    T_NARROWKLASS.setType(db.lookupIntConstant("T_NARROWKLASS").intValue());
+    T_CONFLICT.setType(db.lookupIntConstant("T_CONFLICT").intValue());
+    T_ILLEGAL.setType(db.lookupIntConstant("T_ILLEGAL").intValue());
+  }
 
   public static int getTBoolean() {
-    return tBoolean;
+    return T_BOOLEAN.getType();
   }
 
   public static int getTChar() {
-    return tChar;
+    return T_CHAR.getType();
   }
 
   public static int getTFloat() {
-    return tFloat;
+    return T_FLOAT.getType();
   }
 
   public static int getTDouble() {
-    return tDouble;
+    return T_DOUBLE.getType();
   }
 
   public static int getTByte() {
-    return tByte;
+    return T_BYTE.getType();
   }
 
   public static int getTShort() {
-    return tShort;
+    return T_SHORT.getType();
   }
 
   public static int getTInt() {
-    return tInt;
+    return T_INT.getType();
   }
 
   public static int getTLong() {
-    return tLong;
+    return T_LONG.getType();
   }
 
   public static int getTObject() {
-    return tObject;
+    return T_OBJECT.getType();
   }
 
   public static int getTArray() {
-    return tArray;
+    return T_ARRAY.getType();
   }
 
   public static int getTVoid() {
-    return tVoid;
+    return T_VOID.getType();
   }
 
   public static int getTAddress() {
-    return tAddress;
+    return T_ADDRESS.getType();
   }
 
   public static int getTNarrowOop() {
-    return tNarrowOop;
+    return T_NARROWOOP.getType();
   }
 
   public static int getTMetadata() {
-    return tMetadata;
+    return T_METADATA.getType();
   }
 
   public static int getTNarrowKlass() {
-    return tNarrowKlass;
+    return T_NARROWKLASS.getType();
   }
 
   /** For stack value type with conflicting contents */
   public static int getTConflict() {
-    return tConflict;
+    return T_CONFLICT.getType();
   }
 
   public static int getTIllegal() {
-    return tIllegal;
+    return T_ILLEGAL.getType();
+  }
+
+  public static BasicType intToBasicType(int i) {
+    if (i == T_BOOLEAN.getType()) {
+      return T_BOOLEAN;
+    } else if (i == T_CHAR.getType()) {
+      return T_CHAR;
+    } else if (i == T_FLOAT.getType()) {
+      return T_FLOAT;
+    } else if (i == T_DOUBLE.getType()) {
+      return T_DOUBLE;
+    } else if (i == T_BYTE.getType()) {
+      return T_BYTE;
+    } else if (i == T_SHORT.getType()) {
+      return T_SHORT;
+    } else if (i == T_INT.getType()) {
+      return T_INT;
+    } else if (i == T_LONG.getType()) {
+      return T_LONG;
+    } else if (i == T_OBJECT.getType()) {
+      return T_OBJECT;
+    } else if (i == T_ARRAY.getType()) {
+      return T_ARRAY;
+    } else if (i == T_VOID.getType()) {
+      return T_VOID;
+    } else if (i == T_ADDRESS.getType()) {
+      return T_ADDRESS;
+    } else if (i == T_NARROWOOP.getType()) {
+      return T_NARROWOOP;
+    } else if (i == T_METADATA.getType()) {
+      return T_METADATA;
+    } else if (i == T_NARROWKLASS.getType()) {
+      return T_NARROWKLASS;
+    } else {
+      return T_ILLEGAL;
+    }
   }
 
   public static BasicType charToBasicType(char c) {
@@ -158,8 +205,49 @@
     return type;
   }
 
+  public String getName() {
+    if (type == T_BOOLEAN.getType()) {
+      return "boolean";
+    } else if (type == T_CHAR.getType()) {
+      return "char";
+    } else if (type == T_FLOAT.getType()) {
+      return "float";
+    } else if (type == T_DOUBLE.getType()) {
+      return "double";
+    } else if (type == T_BYTE.getType()) {
+      return "byte";
+    } else if (type == T_SHORT.getType()) {
+      return "short";
+    } else if (type == T_INT.getType()) {
+      return "int";
+    } else if (type == T_LONG.getType()) {
+      return "long";
+    } else if (type == T_OBJECT.getType()) {
+      return "object";
+    } else if (type == T_ARRAY.getType()) {
+      return "array";
+    } else if (type == T_VOID.getType()) {
+      return "void";
+    } else if (type == T_ADDRESS.getType()) {
+      return "address";
+    } else if (type == T_NARROWOOP.getType()) {
+      return "narrow oop";
+    } else if (type == T_METADATA.getType()) {
+      return "metadata";
+    } else if (type == T_NARROWKLASS.getType()) {
+      return "narrow klass";
+    } else if (type == T_CONFLICT.getType()) {
+      return "conflict";
+    } else {
+      return "ILLEGAL TYPE";
+    }
+  }
+
   //-- Internals only below this point
-  private BasicType(int type) {
+  private BasicType() {
+  }
+
+  private void setType(int type) {
     this.type = type;
   }
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/BasicTypeSize.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/BasicTypeSize.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -24,22 +24,48 @@
 
 package sun.jvm.hotspot.runtime;
 
+import java.util.Observer;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+
 /** Encapsulates the BasicTypeSize enum in globalDefinitions.hpp in
     the VM. */
 
 public class BasicTypeSize {
-  private static boolean initialized = false;
-  private static int tBooleanSize = 1;
-  private static int tCharSize    = 1;
-  private static int tFloatSize   = 1;
-  private static int tDoubleSize  = 2;
-  private static int tByteSize    = 1;
-  private static int tShortSize   = 1;
-  private static int tIntSize     = 1;
-  private static int tLongSize    = 2;
-  private static int tObjectSize  = 1;
-  private static int tArraySize   = 1;
-  private static int tVoidSize    = 0;
+  private static int tBooleanSize;
+  private static int tCharSize;
+  private static int tFloatSize;
+  private static int tDoubleSize;
+  private static int tByteSize;
+  private static int tShortSize;
+  private static int tIntSize;
+  private static int tLongSize;
+  private static int tObjectSize;
+  private static int tArraySize;
+  private static int tNarrowOopSize;
+  private static int tNarrowKlassSize;
+  private static int tVoidSize;
+
+  static {
+    VM.registerVMInitializedObserver(
+        (o, d) -> initialize(VM.getVM().getTypeDataBase()));
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    tBooleanSize     = db.lookupIntConstant("T_BOOLEAN_size").intValue();
+    tCharSize        = db.lookupIntConstant("T_INT_size").intValue();
+    tFloatSize       = db.lookupIntConstant("T_FLOAT_size").intValue();
+    tDoubleSize      = db.lookupIntConstant("T_DOUBLE_size").intValue();
+    tByteSize        = db.lookupIntConstant("T_BYTE_size").intValue();
+    tShortSize       = db.lookupIntConstant("T_SHORT_size").intValue();
+    tIntSize         = db.lookupIntConstant("T_INT_size").intValue();
+    tLongSize        = db.lookupIntConstant("T_LONG_size").intValue();
+    tObjectSize      = db.lookupIntConstant("T_OBJECT_size").intValue();
+    tArraySize       = db.lookupIntConstant("T_ARRAY_size").intValue();
+    tNarrowOopSize   = db.lookupIntConstant("T_NARROWOOP_size").intValue();
+    tNarrowKlassSize = db.lookupIntConstant("T_NARROWKLASS_size").intValue();
+    tVoidSize        = db.lookupIntConstant("T_VOID_size").intValue();
+  }
 
   public static int getTBooleanSize() {
     return tBooleanSize;
@@ -81,6 +107,14 @@
     return tArraySize;
   }
 
+  public static int getTNarrowOopSize() {
+    return tNarrowOopSize;
+  }
+
+  public static int getTNarrowKlassSize() {
+    return tNarrowKlassSize;
+  }
+
   public static int getTVoidSize() {
     return tVoidSize;
   }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -127,12 +127,12 @@
   }
 
   /** Returns List<MonitorInfo> */
-  public List   getMonitors() {
+  public List<MonitorInfo> getMonitors() {
     List monitors = getScope().getMonitors();
     if (monitors == null) {
-      return new ArrayList();
+      return new ArrayList<>();
     }
-    List result = new ArrayList(monitors.size());
+    List<MonitorInfo> result = new ArrayList<>(monitors.size());
     for (int i = 0; i < monitors.size(); i++) {
       MonitorValue mv = (MonitorValue) monitors.get(i);
       ScopeValue ov = mv.owner();
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/InterpretedVFrame.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -108,8 +108,8 @@
   }
 
   /** Returns List<MonitorInfo> */
-  public List   getMonitors() {
-    List result = new ArrayList(5);
+  public List<MonitorInfo> getMonitors() {
+    List<MonitorInfo> result = new ArrayList<>(5);
     for (BasicObjectLock current = getFrame().interpreterFrameMonitorEnd();
          current.address().lessThan(getFrame().interpreterFrameMonitorBegin().address());
          current = getFrame().nextMonitorInInterpreterFrame(current)) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -28,14 +28,19 @@
 import java.util.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.utilities.*;
+import sun.jvm.hotspot.debugger.*;
 
 public abstract class JavaVFrame extends VFrame {
+
+  private static final String ADDRESS_FORMAT = VM.getVM().isLP64() ? "0x%016x"
+                                                                   : "0x%08x";
+
   /** JVM state */
   public abstract Method getMethod();
   public abstract int    getBCI();
   public abstract StackValueCollection getLocals();
   public abstract StackValueCollection getExpressions();
-  public abstract List   getMonitors();    // List<MonitorInfo>
+  public abstract List<MonitorInfo> getMonitors();
 
   /** Test operation */
   public boolean isJavaFrame() { return true; }
@@ -49,9 +54,112 @@
   // FIXME: not yet implemented
   //  public Address getPendingMonitor(int frameCount);
 
+  public void printLockedObjectClassName(PrintStream tty,
+                                         OopHandle hobj, String lockState) {
+    if (hobj.asLongValue() != 0L) {
+      tty.format("\t- %s <" + ADDRESS_FORMAT + "> ",
+                 lockState, hobj.asLongValue());
+
+      Klass klass = Oop.getKlassForOopHandle(hobj);
+      String klassName = klass.getName().asString();
+      tty.print("(a ");
+      if (klassName.equals("java/lang/Class")) {
+        Oop obj = VM.getVM().getObjectHeap().newOop(hobj);
+        klassName = java_lang_Class.asExternalName(obj);
+        tty.print("java.lang.Class for ");
+      }
+      tty.println(klassName.replace('/', '.') + ")");
+    }
+  }
+
+  private String identifyLockState(MonitorInfo monitor, String waitingState) {
+    Mark mark = new Mark(monitor.owner());
+    if (mark.hasMonitor() &&
+        ( // we have marked ourself as pending on this monitor
+          mark.monitor().equals(thread.getCurrentPendingMonitor()) ||
+          // we are not the owner of this monitor
+          !mark.monitor().isEntered(thread)
+        )) {
+      return waitingState;
+    }
+    return "locked";
+  }
+
   /** Printing used during stack dumps */
-  // FIXME: not yet implemented
-  //  void print_lock_info(int frame_count);
+  public void printLockInfo(PrintStream tty, int frameCount) {
+    // If this is the first frame and it is java.lang.Object.wait(...)
+    // then print out the receiver. Locals are not always available,
+    // e.g., compiled native frames have no scope so there are no locals.
+    if (frameCount == 0) {
+      if (getMethod().getName().asString().equals("wait") &&
+          getMethod().getMethodHolder().getName().asString().equals("java/lang/Object")) {
+        String waitState = "waiting on"; // assume we are waiting
+        // If earlier in the output we reported java.lang.Thread.State ==
+        // "WAITING (on object monitor)" and now we report "waiting on", then
+        // we are still waiting for notification or timeout. Otherwise if
+        // we earlier reported java.lang.Thread.State == "BLOCKED (on object
+        // monitor)", then we are actually waiting to re-lock the monitor.
+        // At this level we can't distinguish the two cases to report
+        // "waited on" rather than "waiting on" for the second case.
+        StackValueCollection locs = getLocals();
+        if (!locs.isEmpty()) {
+          StackValue sv = locs.get(0);
+          if (sv.getType() == BasicType.getTObject()) {
+            OopHandle o = sv.getObject();
+            printLockedObjectClassName(tty, o, waitState);
+          }
+        } else {
+          tty.println("\t- " + waitState + " <no object reference available>");
+        }
+      } else if (thread.getCurrentParkBlocker() != null) {
+        Oop obj = thread.getCurrentParkBlocker();
+        Klass k = obj.getKlass();
+        tty.format("\t- parking to wait for <" + ADDRESS_FORMAT + "> (a %s)",
+                   obj.getHandle().asLongValue(), k.getName().asString());
+        tty.println();
+      }
+    }
+
+    // Print out all monitors that we have locked, or are trying to lock,
+    // including re-locking after being notified or timing out in a wait().
+    List<MonitorInfo> mons = getMonitors();
+    if (!mons.isEmpty()) {
+      boolean foundFirstMonitor = false;
+      for (int index = mons.size() - 1; index >= 0; index--) {
+        MonitorInfo monitor = mons.get(index);
+        if (monitor.eliminated() && isCompiledFrame()) { // Eliminated in compiled code
+          if (monitor.ownerIsScalarReplaced()) {
+            Klass k = Oop.getKlassForOopHandle(monitor.ownerKlass());
+            tty.println("\t- eliminated <owner is scalar replaced> (a " + k.getName().asString() + ")");
+          } else if (monitor.owner() != null) {
+            printLockedObjectClassName(tty, monitor.owner(), "eliminated");
+          }
+          continue;
+        }
+        if (monitor.owner() != null) {
+          // the monitor is associated with an object, i.e., it is locked
+          String lockState = "locked";
+          if (!foundFirstMonitor && frameCount == 0) {
+            // If this is the first frame and we haven't found an owned
+            // monitor before, then we need to see if we have completed
+            // the lock or if we are blocked trying to acquire it. Only
+            // an inflated monitor that is first on the monitor list in
+            // the first frame can block us on a monitor enter.
+            lockState = identifyLockState(monitor, "waiting to lock");
+          } else if (frameCount != 0) {
+            // This is not the first frame so we either own this monitor
+            // or we owned the monitor before and called wait(). Because
+            // wait() could have been called on any monitor in a lower
+            // numbered frame on the stack, we have to check all the
+            // monitors on the list for this frame.
+            lockState = identifyLockState(monitor, "waiting to re-lock in wait()");
+          }
+          printLockedObjectClassName(tty, monitor.owner(), lockState);
+          foundFirstMonitor = true;
+        }
+      }
+    }
+  }
 
   /** Printing operations */
 
@@ -73,22 +181,6 @@
 
     printStackValuesOn(tty, "locals",      getLocals());
     printStackValuesOn(tty, "expressions", getExpressions());
-
-    // List<MonitorInfo>
-    // FIXME: not yet implemented
-    //    List list = getMonitors();
-    //    if (list.isEmpty()) {
-    //      return;
-    //    }
-    //    for (int index = 0; index < list.size(); index++) {
-    //      MonitorInfo monitor = (MonitorInfo) list.get(index);
-    //      tty.print("\t  obj\t");
-    //      monitor.getOwner().printValueOn(tty);
-    //      tty.println();
-    //      tty.print("\t  ");
-    //      monitor.lock().printOn(tty);
-    //      tty.println();
-    //    }
   }
 
   public void printActivation(int index) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectSynchronizer.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectSynchronizer.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,9 +44,7 @@
     Type type;
     try {
       type = db.lookupType("ObjectSynchronizer");
-      AddressField blockListField;
-      blockListField = type.getAddressField("gBlockList");
-      gBlockListAddr = blockListField.getValue();
+      gBlockList = type.getAddressField("gBlockList").getValue();
       blockSize = db.lookupIntConstant("ObjectSynchronizer::_BLOCKSIZE").intValue();
       defaultCacheLineSize = db.lookupIntConstant("DEFAULT_CACHE_LINE_SIZE").intValue();
     } catch (RuntimeException e) { }
@@ -84,7 +82,7 @@
   }
 
   public static Iterator objectMonitorIterator() {
-    if (gBlockListAddr != null) {
+    if (gBlockList != null) {
       return new ObjectMonitorIterator();
     } else {
       return null;
@@ -97,7 +95,7 @@
     // and are not included by this Iterator. May add them later.
 
     ObjectMonitorIterator() {
-      blockAddr = gBlockListAddr;
+      blockAddr = gBlockList;
       index = blockSize - 1;
       block = new ObjectMonitor(blockAddr);
     }
@@ -131,7 +129,7 @@
     private Address blockAddr;
   }
 
-  private static Address gBlockListAddr;
+  private static Address gBlockList;
   private static int blockSize;
   private static int defaultCacheLineSize;
   private static long objectMonitorTypeSize;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/PerfDataEntry.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/PerfDataEntry.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -92,14 +92,29 @@
         return (flags() & 0x1) != 0;
     }
 
-    // NOTE: Keep this in sync with PerfData::Units enum in VM code
-    public interface PerfDataUnits {
-        public static final int U_None   = 1;
-        public static final int U_Bytes  = 2;
-        public static final int U_Ticks  = 3;
-        public static final int U_Events = 4;
-        public static final int U_String = 5;
-        public static final int U_Hertz  = 6;
+    private static class PerfDataUnits {
+        public static int U_None;
+        public static int U_Bytes;
+        public static int U_Ticks;
+        public static int U_Events;
+        public static int U_String;
+        public static int U_Hertz;
+
+        static {
+            VM.registerVMInitializedObserver(new Observer() {
+                public void update(Observable o, Object data) {
+                    initialize(VM.getVM().getTypeDataBase());
+                }
+            });
+        }
+        private static synchronized void initialize(TypeDataBase db) {
+            U_None = db.lookupIntConstant("PerfData::U_None");
+            U_Bytes = db.lookupIntConstant("PerfData::U_Bytes");
+            U_Ticks = db.lookupIntConstant("PerfData::U_Ticks");
+            U_Events = db.lookupIntConstant("PerfData::U_Events");
+            U_String = db.lookupIntConstant("PerfData::U_String");
+            U_Hertz = db.lookupIntConstant("PerfData::U_Hertz");
+        }
     }
 
     // returns one of the constants in PerfDataUnits
@@ -107,13 +122,6 @@
         return (int) dataUnitsField.getValue(addr);
     }
 
-    // NOTE: Keep this in sync with PerfData::Variability enum in VM code
-    public interface PerfDataVariability {
-        public static final int V_Constant  = 1;
-        public static final int V_Monotonic = 2;
-        public static final int V_Variable  = 3;
-    }
-
     // returns one of the constants in PerfDataVariability
     public int dataVariability() {
         return (int) dataVariabilityField.getValue(addr);
@@ -131,7 +139,7 @@
     public boolean booleanValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tBoolean, "not a boolean");
+                        dataType() == BasicType.getTBoolean(), "not a boolean");
         }
         return addr.getJBooleanAt(dataOffset());
     }
@@ -139,7 +147,7 @@
     public char charValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tChar, "not a char");
+                        dataType() == BasicType.getTChar(), "not a char");
         }
         return addr.getJCharAt(dataOffset());
     }
@@ -147,7 +155,7 @@
     public byte byteValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tByte, "not a byte");
+                        dataType() == BasicType.getTByte(), "not a byte");
         }
         return addr.getJByteAt(dataOffset());
 
@@ -156,7 +164,7 @@
     public short shortValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tShort, "not a short");
+                        dataType() == BasicType.getTShort(), "not a short");
         }
         return addr.getJShortAt(dataOffset());
     }
@@ -164,7 +172,7 @@
     public int intValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tInt, "not an int");
+                        dataType() == BasicType.getTInt(), "not an int");
         }
         return addr.getJIntAt(dataOffset());
     }
@@ -172,7 +180,7 @@
     public long longValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tLong, "not a long");
+                        dataType() == BasicType.getTLong(), "not a long");
         }
         return addr.getJLongAt(dataOffset());
     }
@@ -180,7 +188,7 @@
     public float floatValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tFloat, "not a float");
+                        dataType() == BasicType.getTFloat(), "not a float");
         }
         return addr.getJFloatAt(dataOffset());
     }
@@ -188,7 +196,7 @@
     public double doubleValue() {
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(vectorLength() == 0 &&
-                        dataType() == BasicType.tDouble, "not a double");
+                        dataType() == BasicType.getTDouble(), "not a double");
         }
         return addr.getJDoubleAt(dataOffset());
     }
@@ -197,7 +205,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tBoolean, "not a boolean vector");
+                        dataType() == BasicType.getTBoolean(), "not a boolean vector");
         }
         boolean[] res = new boolean[len];
         final int off = dataOffset();
@@ -212,7 +220,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tChar, "not a char vector");
+                        dataType() == BasicType.getTChar(), "not a char vector");
         }
         char[] res = new char[len];
         final int off = dataOffset();
@@ -227,7 +235,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tByte, "not a byte vector");
+                        dataType() == BasicType.getTByte(), "not a byte vector");
         }
         byte[] res = new byte[len];
         final int off = dataOffset();
@@ -242,7 +250,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tShort, "not a short vector");
+                        dataType() == BasicType.getTShort(), "not a short vector");
         }
         short[] res = new short[len];
         final int off = dataOffset();
@@ -257,7 +265,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tInt, "not an int vector");
+                        dataType() == BasicType.getTInt(), "not an int vector");
         }
         int[] res = new int[len];
         final int off = dataOffset();
@@ -272,7 +280,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tLong, "not a long vector");
+                        dataType() == BasicType.getTLong(), "not a long vector");
         }
         long[] res = new long[len];
         final int off = dataOffset();
@@ -287,7 +295,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tFloat, "not a float vector");
+                        dataType() == BasicType.getTFloat(), "not a float vector");
         }
         float[] res = new float[len];
         final int off = dataOffset();
@@ -302,7 +310,7 @@
         int len = vectorLength();
         if (Assert.ASSERTS_ENABLED) {
             Assert.that(len > 0 &&
-                        dataType() == BasicType.tDouble, "not a double vector");
+                        dataType() == BasicType.getTDouble(), "not a double vector");
         }
         double[] res = new double[len];
         final int off = dataOffset();
@@ -319,38 +327,27 @@
         int len = vectorLength();
         String str = null;
         if (len == 0) { // scalar
-            switch (dataType) {
-            case BasicType.tBoolean:
+            if (dataType == BasicType.getTBoolean()) {
                 str = Boolean.toString(booleanValue());
-                break;
-            case BasicType.tChar:
+            } else if (dataType == BasicType.getTChar()) {
                 str = "'" + Character.toString(charValue()) + "'";
-                break;
-            case BasicType.tByte:
+            } else if (dataType == BasicType.getTByte()) {
                 str = Byte.toString(byteValue());
-                break;
-            case BasicType.tShort:
+            } else if (dataType == BasicType.getTShort()) {
                 str = Short.toString(shortValue());
-                break;
-            case BasicType.tInt:
+            } else if (dataType ==  BasicType.getTInt()) {
                 str = Integer.toString(intValue());
-                break;
-            case BasicType.tLong:
+            } else if (dataType == BasicType.getTLong()) {
                 str = Long.toString(longValue());
-                break;
-            case BasicType.tFloat:
+            } else if (dataType == BasicType.getTFloat()) {
                 str = Float.toString(floatValue());
-                break;
-            case BasicType.tDouble:
+            } else if (dataType == BasicType.getTDouble()) {
                 str = Double.toString(doubleValue());
-                break;
-            default:
+            } else {
                 str = "<unknown scalar value>";
-                break;
             }
         } else { // vector
-            switch (dataType) {
-            case BasicType.tBoolean: {
+            if (dataType == BasicType.getTBoolean()) {
                 boolean[] res = booleanArrayValue();
                 StringBuffer buf = new StringBuffer();
                 buf.append('[');
@@ -360,26 +357,17 @@
                 }
                 buf.append(']');
                 str = buf.toString();
-                break;
-            }
-
-            case BasicType.tChar: {
+            } else if (dataType == BasicType.getTChar()) {
                 // char[] is returned as a String
                 str = new String(charArrayValue());
-                break;
-            }
-
-            case BasicType.tByte: {
+            } else if (dataType == BasicType.getTByte()) {
                 // byte[] is returned as a String
                 try {
                     str = new String(byteArrayValue(), "US-ASCII");
                 } catch (java.io.UnsupportedEncodingException e) {
                     str = "can't decode string : " + e.getMessage();
                 }
-                break;
-            }
-
-            case BasicType.tShort: {
+            } else if (dataType == BasicType.getTShort()) {
                 short[] res = shortArrayValue();
                 StringBuffer buf = new StringBuffer();
                 buf.append('[');
@@ -389,10 +377,7 @@
                 }
                 buf.append(']');
                 str = buf.toString();
-                break;
-            }
-
-            case BasicType.tInt: {
+            } else if (dataType ==  BasicType.getTInt()) {
                 int[] res = intArrayValue();
                 StringBuffer buf = new StringBuffer();
                 buf.append('[');
@@ -402,10 +387,7 @@
                 }
                 buf.append(']');
                 str = buf.toString();
-                break;
-            }
-
-            case BasicType.tLong: {
+            } else if (dataType == BasicType.getTLong()) {
                 long[] res = longArrayValue();
                 StringBuffer buf = new StringBuffer();
                 buf.append('[');
@@ -415,10 +397,7 @@
                 }
                 buf.append(']');
                 str = buf.toString();
-                break;
-            }
-
-            case BasicType.tFloat: {
+            } else if (dataType == BasicType.getTFloat()) {
                 float[] res = floatArrayValue();
                 StringBuffer buf = new StringBuffer();
                 buf.append('[');
@@ -428,10 +407,7 @@
                 }
                 buf.append(']');
                 str = buf.toString();
-                break;
-            }
-
-            case BasicType.tDouble: {
+            } else if (dataType == BasicType.getTDouble()) {
                 double[] res = doubleArrayValue();
                 StringBuffer buf = new StringBuffer();
                 buf.append('[');
@@ -441,33 +417,22 @@
                 }
                 buf.append(']');
                 str = buf.toString();
-                break;
-            }
-
-            default:
+            } else {
                 str = "<unknown vector value>";
-                break;
             }
         }
 
         // add units
-        switch (dataUnits()) {
-        case PerfDataUnits.U_None:
-            break;
-        case PerfDataUnits.U_Bytes:
+        int dataUnitsValue = dataUnits();
+
+        if (dataUnitsValue == PerfDataUnits.U_Bytes) {
             str += " byte(s)";
-            break;
-        case PerfDataUnits.U_Ticks:
+        } else if (dataUnitsValue == PerfDataUnits.U_Ticks) {
             str += " tick(s)";
-            break;
-        case PerfDataUnits.U_Events:
+        } else if (dataUnitsValue == PerfDataUnits.U_Events) {
             str += " event(s)";
-            break;
-        case PerfDataUnits.U_String:
-            break;
-        case PerfDataUnits.U_Hertz:
+        } else if (dataUnitsValue == PerfDataUnits.U_Hertz) {
             str += " Hz";
-            break;
         }
 
         return str;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -117,10 +117,7 @@
       return null;
     }
     Frame s = fr.realSender(tempMap);
-    // ia64 in 1.4.1 only has java frames and no entryFrame
-    // so "s" can be null here for the first frame.
     if (s == null) {
-      Assert.that(VM.getVM().getCPU().equals("ia64"), "Only ia64 should have null here");
       return null;
     }
     if (s.isFirstFrame()) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java	Thu Dec 07 11:54:55 2017 +0000
@@ -76,6 +76,8 @@
                 if (cur.isJavaThread()) {
                     cur.printThreadInfoOn(tty);
                     try {
+                        int count = 0;
+
                         for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
                             Method method = vf.getMethod();
                             tty.print(" - " + method.externalNameAndSignature() +
@@ -109,6 +111,7 @@
                             }
 
                             tty.println(")");
+                            vf.printLockInfo(tty, count++);
                         }
                     } catch (Exception e) {
                         tty.println("Error occurred during stack walking:");
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/PackageNameFilter.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/PackageNameFilter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -50,10 +50,14 @@
     }
 
     public boolean canInclude(InstanceKlass kls) {
-        String klassName = kls.getName().asString().replace('/', '.');
+        if (pkgList == null) {
+            // Dump everything
+            return true;
+        }
         final int len = pkgList.length;
         if (len == 0)
             return true;
+        String klassName = kls.getName().asString().replace('/', '.');
         for (int i=0; i < len; i++)
             if (klassName.startsWith((String) pkgList[i] )) return true;
         return false;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1910,6 +1910,7 @@
       buf.append(thread.getThreadState().toString());
       buf.br();
       buf.beginTag("pre");
+      int count = 0;
       for (JavaVFrame vf = thread.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
          Method method = vf.getMethod();
          buf.append(" - ");
@@ -1954,6 +1955,19 @@
          }
          buf.append(")");
          buf.br();
+
+         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+         PrintStream printStream = new PrintStream(bytes);
+         try (printStream) {
+             vf.printLockInfo(printStream, count++);
+             for (String line : bytes.toString().split("\n")) {
+                 if (genHTML) {
+                     line = line.replace("<", "&lt;").replace(">", "&gt;");
+                 }
+                 buf.append(line);
+                 buf.br();
+             }
+         }
       }
 
       buf.endTag("pre");
--- a/src/jdk.hotspot.agent/solaris/native/libsaproc/libproc.h	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.hotspot.agent/solaris/native/libsaproc/libproc.h	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -77,14 +77,14 @@
 typedef uint32_t syscall_t;     /* holds a syscall instruction */
 #endif  /* sparc */
 
-#if defined(__i386) || defined(__ia64)
+#if defined(__i386)
 #define R_PC    EIP
 #define R_SP    UESP
 #define R_RVAL1 EAX             /* register holding a function return value */
 #define R_RVAL2 EDX             /* 32 more bits for a 64-bit return value */
 #define SYSCALL 0x9a            /* syscall (lcall) instruction opcode */
 typedef uchar_t syscall_t[7];   /* holds a syscall instruction */
-#endif  /* __i386 || __ia64 */
+#endif  /* __i386 */
 
 #define R_RVAL  R_RVAL1         /* simple function return value register */
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Thu Dec 07 11:54:55 2017 +0000
@@ -352,17 +352,18 @@
      */
     private enum OpAssertion {
         ByteAssertion(CPU, CPU, BYTE),
-        IntegerAssertion(CPU, CPU, WORD, DWORD, QWORD),
-        No16BitAssertion(CPU, CPU, DWORD, QWORD),
-        No32BitAssertion(CPU, CPU, WORD, QWORD),
-        QwordOnlyAssertion(CPU, CPU, QWORD),
-        FloatingAssertion(XMM, XMM, SS, SD, PS, PD),
-        PackedFloatingAssertion(XMM, XMM, PS, PD),
+        ByteOrLargerAssertion(CPU, CPU, BYTE, WORD, DWORD, QWORD),
+        WordOrLargerAssertion(CPU, CPU, WORD, DWORD, QWORD),
+        DwordOrLargerAssertion(CPU, CPU, DWORD, QWORD),
+        WordOrDwordAssertion(CPU, CPU, WORD, QWORD),
+        QwordAssertion(CPU, CPU, QWORD),
+        FloatAssertion(XMM, XMM, SS, SD, PS, PD),
+        PackedFloatAssertion(XMM, XMM, PS, PD),
         SingleAssertion(XMM, XMM, SS),
         DoubleAssertion(XMM, XMM, SD),
         PackedDoubleAssertion(XMM, XMM, PD),
-        IntToFloatingAssertion(XMM, CPU, DWORD, QWORD),
-        FloatingToIntAssertion(CPU, XMM, DWORD, QWORD);
+        IntToFloatAssertion(XMM, CPU, DWORD, QWORD),
+        FloatToIntAssertion(CPU, XMM, DWORD, QWORD);
 
         private final RegisterCategory resultCategory;
         private final RegisterCategory inputCategory;
@@ -772,25 +773,25 @@
      */
     public static class AMD64RMOp extends AMD64RROp {
         // @formatter:off
-        public static final AMD64RMOp IMUL   = new AMD64RMOp("IMUL",         P_0F, 0xAF);
+        public static final AMD64RMOp IMUL   = new AMD64RMOp("IMUL",         P_0F, 0xAF, OpAssertion.ByteOrLargerAssertion);
         public static final AMD64RMOp BSF    = new AMD64RMOp("BSF",          P_0F, 0xBC);
         public static final AMD64RMOp BSR    = new AMD64RMOp("BSR",          P_0F, 0xBD);
         public static final AMD64RMOp POPCNT = new AMD64RMOp("POPCNT", 0xF3, P_0F, 0xB8, CPUFeature.POPCNT);
         public static final AMD64RMOp TZCNT  = new AMD64RMOp("TZCNT",  0xF3, P_0F, 0xBC, CPUFeature.BMI1);
         public static final AMD64RMOp LZCNT  = new AMD64RMOp("LZCNT",  0xF3, P_0F, 0xBD, CPUFeature.LZCNT);
-        public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB",       P_0F, 0xB6, false, true, OpAssertion.IntegerAssertion);
-        public static final AMD64RMOp MOVZX  = new AMD64RMOp("MOVZX",        P_0F, 0xB7, OpAssertion.No16BitAssertion);
-        public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB",       P_0F, 0xBE, false, true, OpAssertion.IntegerAssertion);
-        public static final AMD64RMOp MOVSX  = new AMD64RMOp("MOVSX",        P_0F, 0xBF, OpAssertion.No16BitAssertion);
-        public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD",             0x63, OpAssertion.QwordOnlyAssertion);
+        public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB",       P_0F, 0xB6, false, true, OpAssertion.WordOrLargerAssertion);
+        public static final AMD64RMOp MOVZX  = new AMD64RMOp("MOVZX",        P_0F, 0xB7, OpAssertion.DwordOrLargerAssertion);
+        public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB",       P_0F, 0xBE, false, true, OpAssertion.WordOrLargerAssertion);
+        public static final AMD64RMOp MOVSX  = new AMD64RMOp("MOVSX",        P_0F, 0xBF, OpAssertion.DwordOrLargerAssertion);
+        public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD",             0x63, OpAssertion.QwordAssertion);
         public static final AMD64RMOp MOVB   = new AMD64RMOp("MOVB",               0x8A, OpAssertion.ByteAssertion);
         public static final AMD64RMOp MOV    = new AMD64RMOp("MOV",                0x8B);
 
         // MOVD/MOVQ and MOVSS/MOVSD are the same opcode, just with different operand size prefix
-        public static final AMD64RMOp MOVD   = new AMD64RMOp("MOVD",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
-        public static final AMD64RMOp MOVQ   = new AMD64RMOp("MOVQ",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
-        public static final AMD64RMOp MOVSS  = new AMD64RMOp("MOVSS",        P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
-        public static final AMD64RMOp MOVSD  = new AMD64RMOp("MOVSD",        P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
+        public static final AMD64RMOp MOVD   = new AMD64RMOp("MOVD",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
+        public static final AMD64RMOp MOVQ   = new AMD64RMOp("MOVQ",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
+        public static final AMD64RMOp MOVSS  = new AMD64RMOp("MOVSS",        P_0F, 0x10, OpAssertion.FloatAssertion, CPUFeature.SSE);
+        public static final AMD64RMOp MOVSD  = new AMD64RMOp("MOVSD",        P_0F, 0x10, OpAssertion.FloatAssertion, CPUFeature.SSE);
 
         // TEST is documented as MR operation, but it's symmetric, and using it as RM operation is more convenient.
         public static final AMD64RMOp TESTB  = new AMD64RMOp("TEST",               0x84, OpAssertion.ByteAssertion);
@@ -822,7 +823,7 @@
         }
 
         protected AMD64RMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) {
-            this(opcode, prefix1, prefix2, op, OpAssertion.IntegerAssertion, feature);
+            this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature);
         }
 
         protected AMD64RMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@@ -1014,7 +1015,7 @@
         }
 
         protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) {
-            this(opcode, prefix1, prefix2, op, OpAssertion.IntegerAssertion, feature);
+            this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature);
         }
 
         protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@@ -1114,12 +1115,12 @@
 
         // MOVD and MOVQ are the same opcode, just with different operand size prefix
         // Note that as MR opcodes, they have reverse operand order, so the IntToFloatingAssertion must be used.
-        public static final AMD64MROp MOVD   = new AMD64MROp("MOVD",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
-        public static final AMD64MROp MOVQ   = new AMD64MROp("MOVQ",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
+        public static final AMD64MROp MOVD   = new AMD64MROp("MOVD",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
+        public static final AMD64MROp MOVQ   = new AMD64MROp("MOVQ",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
 
         // MOVSS and MOVSD are the same opcode, just with different operand size prefix
-        public static final AMD64MROp MOVSS  = new AMD64MROp("MOVSS",        P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
-        public static final AMD64MROp MOVSD  = new AMD64MROp("MOVSD",        P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
+        public static final AMD64MROp MOVSS  = new AMD64MROp("MOVSS",        P_0F, 0x11, OpAssertion.FloatAssertion, CPUFeature.SSE);
+        public static final AMD64MROp MOVSD  = new AMD64MROp("MOVSD",        P_0F, 0x11, OpAssertion.FloatAssertion, CPUFeature.SSE);
         // @formatter:on
 
         protected AMD64MROp(String opcode, int op) {
@@ -1131,7 +1132,7 @@
         }
 
         protected AMD64MROp(String opcode, int prefix, int op) {
-            this(opcode, prefix, op, OpAssertion.IntegerAssertion);
+            this(opcode, prefix, op, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64MROp(String opcode, int prefix, int op, OpAssertion assertion) {
@@ -1279,7 +1280,7 @@
         public static final AMD64MOp INC  = new AMD64MOp("INC",  0xFF, 0);
         public static final AMD64MOp DEC  = new AMD64MOp("DEC",  0xFF, 1);
         public static final AMD64MOp PUSH = new AMD64MOp("PUSH", 0xFF, 6);
-        public static final AMD64MOp POP  = new AMD64MOp("POP",  0x8F, 0, OpAssertion.No32BitAssertion);
+        public static final AMD64MOp POP  = new AMD64MOp("POP",  0x8F, 0, OpAssertion.WordOrDwordAssertion);
         // @formatter:on
 
         private final int ext;
@@ -1289,7 +1290,7 @@
         }
 
         protected AMD64MOp(String opcode, int prefix, int op, int ext) {
-            this(opcode, prefix, op, ext, OpAssertion.IntegerAssertion);
+            this(opcode, prefix, op, ext, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64MOp(String opcode, int op, int ext, OpAssertion assertion) {
@@ -1327,7 +1328,7 @@
         private final int ext;
 
         protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext) {
-            this(opcode, immIsByte, op, ext, OpAssertion.IntegerAssertion);
+            this(opcode, immIsByte, op, ext, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext, OpAssertion assertion) {
@@ -1369,7 +1370,7 @@
         // @formatter:on
 
         protected AMD64RMIOp(String opcode, boolean immIsByte, int op) {
-            this(opcode, immIsByte, 0, op, OpAssertion.IntegerAssertion);
+            this(opcode, immIsByte, 0, op, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64RMIOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion) {
@@ -1504,16 +1505,16 @@
 
     public static class SSEOp extends AMD64RMOp {
         // @formatter:off
-        public static final SSEOp CVTSI2SS  = new SSEOp("CVTSI2SS",  0xF3, P_0F, 0x2A, OpAssertion.IntToFloatingAssertion);
-        public static final SSEOp CVTSI2SD  = new SSEOp("CVTSI2SS",  0xF2, P_0F, 0x2A, OpAssertion.IntToFloatingAssertion);
-        public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatingToIntAssertion);
-        public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatingToIntAssertion);
-        public static final SSEOp UCOMIS    = new SSEOp("UCOMIS",          P_0F, 0x2E, OpAssertion.PackedFloatingAssertion);
+        public static final SSEOp CVTSI2SS  = new SSEOp("CVTSI2SS",  0xF3, P_0F, 0x2A, OpAssertion.IntToFloatAssertion);
+        public static final SSEOp CVTSI2SD  = new SSEOp("CVTSI2SS",  0xF2, P_0F, 0x2A, OpAssertion.IntToFloatAssertion);
+        public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatToIntAssertion);
+        public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatToIntAssertion);
+        public static final SSEOp UCOMIS    = new SSEOp("UCOMIS",          P_0F, 0x2E, OpAssertion.PackedFloatAssertion);
         public static final SSEOp SQRT      = new SSEOp("SQRT",            P_0F, 0x51);
-        public static final SSEOp AND       = new SSEOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatingAssertion);
-        public static final SSEOp ANDN      = new SSEOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatingAssertion);
-        public static final SSEOp OR        = new SSEOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatingAssertion);
-        public static final SSEOp XOR       = new SSEOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatingAssertion);
+        public static final SSEOp AND       = new SSEOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatAssertion);
+        public static final SSEOp ANDN      = new SSEOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatAssertion);
+        public static final SSEOp OR        = new SSEOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatAssertion);
+        public static final SSEOp XOR       = new SSEOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatAssertion);
         public static final SSEOp ADD       = new SSEOp("ADD",             P_0F, 0x58);
         public static final SSEOp MUL       = new SSEOp("MUL",             P_0F, 0x59);
         public static final SSEOp CVTSS2SD  = new SSEOp("CVTSS2SD",        P_0F, 0x5A, OpAssertion.SingleAssertion);
@@ -1525,7 +1526,7 @@
         // @formatter:on
 
         protected SSEOp(String opcode, int prefix, int op) {
-            this(opcode, prefix, op, OpAssertion.FloatingAssertion);
+            this(opcode, prefix, op, OpAssertion.FloatAssertion);
         }
 
         protected SSEOp(String opcode, int prefix, int op, OpAssertion assertion) {
@@ -1539,10 +1540,10 @@
 
     public static class AVXOp extends AMD64RRMOp {
         // @formatter:off
-        public static final AVXOp AND       = new AVXOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatingAssertion);
-        public static final AVXOp ANDN      = new AVXOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatingAssertion);
-        public static final AVXOp OR        = new AVXOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatingAssertion);
-        public static final AVXOp XOR       = new AVXOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatingAssertion);
+        public static final AVXOp AND       = new AVXOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatAssertion);
+        public static final AVXOp ANDN      = new AVXOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatAssertion);
+        public static final AVXOp OR        = new AVXOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatAssertion);
+        public static final AVXOp XOR       = new AVXOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatAssertion);
         public static final AVXOp ADD       = new AVXOp("ADD",             P_0F, 0x58);
         public static final AVXOp MUL       = new AVXOp("MUL",             P_0F, 0x59);
         public static final AVXOp SUB       = new AVXOp("SUB",             P_0F, 0x5C);
@@ -1552,7 +1553,7 @@
         // @formatter:on
 
         protected AVXOp(String opcode, int prefix, int op) {
-            this(opcode, prefix, op, OpAssertion.FloatingAssertion);
+            this(opcode, prefix, op, OpAssertion.FloatAssertion);
         }
 
         protected AVXOp(String opcode, int prefix, int op, OpAssertion assertion) {
@@ -1595,10 +1596,10 @@
             byteMrOp = new AMD64MROp(opcode, 0, baseOp, OpAssertion.ByteAssertion);
             byteRmOp = new AMD64RMOp(opcode, 0, baseOp | 0x02, OpAssertion.ByteAssertion);
 
-            immOp = new AMD64MIOp(opcode, false, 0, 0x81, code, OpAssertion.IntegerAssertion);
-            immSxOp = new AMD64MIOp(opcode, true, 0, 0x83, code, OpAssertion.IntegerAssertion);
-            mrOp = new AMD64MROp(opcode, 0, baseOp | 0x01, OpAssertion.IntegerAssertion);
-            rmOp = new AMD64RMOp(opcode, 0, baseOp | 0x03, OpAssertion.IntegerAssertion);
+            immOp = new AMD64MIOp(opcode, false, 0, 0x81, code, OpAssertion.WordOrLargerAssertion);
+            immSxOp = new AMD64MIOp(opcode, true, 0, 0x83, code, OpAssertion.WordOrLargerAssertion);
+            mrOp = new AMD64MROp(opcode, 0, baseOp | 0x01, OpAssertion.WordOrLargerAssertion);
+            rmOp = new AMD64RMOp(opcode, 0, baseOp | 0x03, OpAssertion.WordOrLargerAssertion);
         }
 
         public AMD64MIOp getMIOpcode(OperandSize size, boolean sx) {
@@ -1647,9 +1648,9 @@
         public final AMD64MIOp miOp;
 
         private AMD64Shift(String opcode, int code) {
-            m1Op = new AMD64MOp(opcode, 0, 0xD1, code, OpAssertion.IntegerAssertion);
-            mcOp = new AMD64MOp(opcode, 0, 0xD3, code, OpAssertion.IntegerAssertion);
-            miOp = new AMD64MIOp(opcode, true, 0, 0xC1, code, OpAssertion.IntegerAssertion);
+            m1Op = new AMD64MOp(opcode, 0, 0xD1, code, OpAssertion.WordOrLargerAssertion);
+            mcOp = new AMD64MOp(opcode, 0, 0xD3, code, OpAssertion.WordOrLargerAssertion);
+            miOp = new AMD64MIOp(opcode, true, 0, 0xC1, code, OpAssertion.WordOrLargerAssertion);
         }
     }
 
@@ -1967,6 +1968,12 @@
         }
     }
 
+    public final void lead(Register dst, AMD64Address src) {
+        prefix(src, dst);
+        emitByte(0x8D);
+        emitOperandHelper(dst, src, 0);
+    }
+
     public final void leaq(Register dst, AMD64Address src) {
         prefixq(src, dst);
         emitByte(0x8D);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLoweringByUse.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLoweringByUse.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,8 +24,6 @@
 
 package org.graalvm.compiler.core.aarch64;
 
-import jdk.vm.ci.aarch64.AArch64Kind;
-import jdk.vm.ci.meta.JavaConstant;
 import org.graalvm.compiler.asm.aarch64.AArch64Address;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.NumUtil;
@@ -34,9 +32,11 @@
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
 import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
 
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.meta.JavaConstant;
+
 public class AArch64AddressLoweringByUse extends AddressLoweringByUsePhase.AddressLoweringByUse {
     private AArch64LIRKindTool kindtool;
 
@@ -46,9 +46,7 @@
 
     @Override
     public AddressNode lower(ValueNode use, Stamp stamp, AddressNode address) {
-        if (address instanceof RawAddressNode) {
-            return doLower(stamp, address.getBase(), null);
-        } else if (address instanceof OffsetAddressNode) {
+        if (address instanceof OffsetAddressNode) {
             OffsetAddressNode offsetAddress = (OffsetAddressNode) address;
             return doLower(stamp, offsetAddress.getBase(), offsetAddress.getOffset());
         } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -88,7 +89,7 @@
             }
         }
 
-        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
+        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
         gen.setResult(this, new AArch64AddressValue(kind, baseValue, indexValue, (int) displacement, scaleFactor, addressingMode));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.memory.Access;
 
 import jdk.vm.ci.aarch64.AArch64Kind;
@@ -45,7 +46,7 @@
     }
 
     protected AArch64Kind getMemoryKind(Access access) {
-        return (AArch64Kind) gen.getLIRKind(access.asNode().stamp()).getPlatformKind();
+        return (AArch64Kind) gen.getLIRKind(access.asNode().stamp(NodeView.DEFAULT)).getPlatformKind();
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AllocatorTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AllocatorTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,7 +44,7 @@
 
     @Test
     public void test1() {
-        testAllocation("test1snippet", 3, 1, 0);
+        testAllocation("test1snippet", 3, 0, 0);
     }
 
     public static long test1snippet(long x) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,24 +25,23 @@
 
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
 import org.graalvm.compiler.nodes.calc.NegateNode;
-import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
 
 import jdk.vm.ci.meta.JavaConstant;
 
 public class AMD64AddressLowering extends AddressLowering {
-    @Override
-    public AddressNode lower(ValueNode address) {
-        return lower(address, null);
-    }
+    private static final int ADDRESS_BITS = 64;
 
     @Override
     public AddressNode lower(ValueNode base, ValueNode offset) {
@@ -54,9 +53,15 @@
             changed = improve(graph, base.getDebug(), ret, false, false);
         } while (changed);
 
+        assert checkAddressBitWidth(ret.getBase());
+        assert checkAddressBitWidth(ret.getIndex());
         return graph.unique(ret);
     }
 
+    private static boolean checkAddressBitWidth(ValueNode value) {
+        return value == null || value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(value.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
+    }
+
     /**
      * Tries to optimize addresses so that they match the AMD64-specific addressing mode better
      * (base + index * scale + displacement).
@@ -148,7 +153,7 @@
                 if (base == ret.getBase()) {
                     ret.setBase(originalBase);
                 } else if (ret.getBase() != null) {
-                    ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase())));
+                    ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase(), NodeView.DEFAULT)));
                 }
             }
 
@@ -156,7 +161,7 @@
                 if (index == ret.getIndex()) {
                     ret.setIndex(originalIndex);
                 } else if (ret.getIndex() != null) {
-                    ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex())));
+                    ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex(), NodeView.DEFAULT)));
                 }
             }
             return improved;
@@ -168,12 +173,12 @@
 
     private static ValueNode considerNegation(StructuredGraph graph, ValueNode value, boolean negate) {
         if (negate && value != null) {
-            return graph.maybeAddOrUnique(NegateNode.create(value));
+            return graph.maybeAddOrUnique(NegateNode.create(value, NodeView.DEFAULT));
         }
         return value;
     }
 
-    private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
+    private static ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
         if (node == null) {
             return null;
         }
@@ -182,30 +187,26 @@
         if (c != null) {
             return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
         } else {
-            if (node.stamp() instanceof IntegerStamp) {
-                if (node instanceof ZeroExtendNode && (((ZeroExtendNode) node).getInputBits() == 32)) {
-                    /*
-                     * we can't just swallow all zero-extends as we might encounter something like
-                     * the following: ZeroExtend(Add(negativeValue, positiveValue)).
-                     *
-                     * if we swallow the zero-extend in this case and subsequently optimize the add,
-                     * we might end up with a negative value that has less than 64 bits in base or
-                     * index. such a value would require sign extension instead of zero-extension
-                     * but the backend can only do zero-extension. if we ever want to optimize that
-                     * further, we would also need to be careful about over-/underflows.
-                     *
-                     * furthermore, we also can't swallow zero-extends with less than 32 bits as
-                     * most of these values are immediately sign-extended to 32 bit by the backend
-                     * (therefore, the subsequent implicit zero-extension to 64 bit won't do what we
-                     * expect).
-                     */
-                    ValueNode value = ((ZeroExtendNode) node).getValue();
-                    if (!mightBeOptimized(value)) {
-                        // if the value is not optimized further by the address lowering, then we
-                        // can safely rely on the backend doing the implicitly zero-extension.
-                        return value;
-                    }
-                }
+            if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
+                assert PrimitiveStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
+
+                /*
+                 * we can't swallow zero-extends because of multiple reasons:
+                 *
+                 * a) we might encounter something like the following: ZeroExtend(Add(negativeValue,
+                 * positiveValue)). if we swallow the zero-extend in this case and subsequently
+                 * optimize the add, we might end up with a negative value that has less than 64
+                 * bits in base or index. such a value would require sign extension instead of
+                 * zero-extension but the backend can only do (implicit) zero-extension by using a
+                 * larger register (e.g., rax instead of eax).
+                 *
+                 * b) our backend does not guarantee that the upper half of a 64-bit register equals
+                 * 0 if a 32-bit value is stored in there.
+                 *
+                 * c) we also can't swallow zero-extends with less than 32 bits as most of these
+                 * values are immediately sign-extended to 32 bit by the backend (therefore, the
+                 * subsequent implicit zero-extension to 64 bit won't do what we expect).
+                 */
 
                 if (node instanceof AddNode) {
                     AddNode add = (AddNode) node;
@@ -221,13 +222,6 @@
         return node;
     }
 
-    /**
-     * This method returns true for all nodes that might be optimized by the address lowering.
-     */
-    protected boolean mightBeOptimized(ValueNode value) {
-        return value instanceof AddNode || value instanceof LeftShiftNode || value instanceof NegateNode || value instanceof ZeroExtendNode;
-    }
-
     private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift, boolean negateExtractedDisplacement) {
         if (c.getJavaKind().isNumericInteger()) {
             long delta = c.asLong() << shift;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -113,7 +114,7 @@
             }
         }
 
-        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
+        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
         gen.setResult(this, new AMD64AddressValue(kind, baseValue, indexValue, scale, displacement));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java	Thu Dec 07 11:54:55 2017 +0000
@@ -99,8 +99,9 @@
 import org.graalvm.compiler.lir.amd64.AMD64Binary;
 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
 import org.graalvm.compiler.lir.amd64.AMD64ClearRegisterOp;
+import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp;
 import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp;
-import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp;
+import org.graalvm.compiler.lir.amd64.AMD64Move;
 import org.graalvm.compiler.lir.amd64.AMD64MulDivOp;
 import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
 import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
@@ -287,14 +288,33 @@
         return ((AMD64Kind) kind).isInteger();
     }
 
+    private Variable emitBaseOffsetLea(LIRKind resultKind, Value base, int offset, OperandSize size) {
+        Variable result = getLIRGen().newVariable(resultKind);
+        AMD64AddressValue address = new AMD64AddressValue(resultKind, getLIRGen().asAllocatable(base), offset);
+        getLIRGen().append(new AMD64Move.LeaOp(result, address, size));
+        return result;
+    }
+
     @Override
     public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
         TargetDescription target = getLIRGen().target();
         boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX);
         switch ((AMD64Kind) a.getPlatformKind()) {
             case DWORD:
+                if (isJavaConstant(b) && !setFlags) {
+                    long displacement = asJavaConstant(b).asLong();
+                    if (NumUtil.isInt(displacement) && displacement != 1 && displacement != -1) {
+                        return emitBaseOffsetLea(resultKind, a, (int) displacement, OperandSize.DWORD);
+                    }
+                }
                 return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags);
             case QWORD:
+                if (isJavaConstant(b) && !setFlags) {
+                    long displacement = asJavaConstant(b).asLong();
+                    if (NumUtil.isInt(displacement) && displacement != 1 && displacement != -1) {
+                        return emitBaseOffsetLea(resultKind, a, (int) displacement, OperandSize.QWORD);
+                    }
+                }
                 return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags);
             case SINGLE:
                 if (isAvx) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
 import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
 
+import org.graalvm.compiler.asm.amd64.AMD64Assembler;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
 import org.graalvm.compiler.debug.GraalError;
@@ -85,7 +86,7 @@
     @Override
     public AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
         if (src instanceof AMD64AddressValue) {
-            return new LeaOp(dst, (AMD64AddressValue) src);
+            return new LeaOp(dst, (AMD64AddressValue) src, AMD64Assembler.OperandSize.QWORD);
         } else if (isConstantValue(src)) {
             return createLoad(dst, asConstant(src));
         } else if (isRegister(src) || isStackSlotValue(dst)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Thu Dec 07 11:54:55 2017 +0000
@@ -60,6 +60,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
@@ -478,7 +479,7 @@
     @MatchRule("(Write object Narrow=narrow)")
     public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
         return builder -> {
-            LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
+            LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp(NodeView.DEFAULT));
             getArithmeticLIRGenerator().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
             return null;
         };
@@ -504,10 +505,10 @@
             @Override
             public Value evaluate(NodeLIRBuilder builder) {
                 AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-                LIRKind addressKind = LIRKind.combineDerived(getLIRGeneratorTool().getLIRKind(root.asNode().stamp()),
+                LIRKind addressKind = LIRKind.combineDerived(getLIRGeneratorTool().getLIRKind(root.asNode().stamp(NodeView.DEFAULT)),
                                 address.getBase(), address.getIndex());
                 AMD64AddressValue newAddress = address.withKind(addressKind);
-                LIRKind readKind = getLIRGeneratorTool().getLIRKind(root.stamp());
+                LIRKind readKind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
                 return getArithmeticLIRGenerator().emitZeroExtendMemory((AMD64Kind) readKind.getPlatformKind(),
                                 root.getResultBits(), newAddress, getState(access));
             }
@@ -517,7 +518,7 @@
     @MatchRule("(SignExtend (Narrow=narrow Read=access))")
     @MatchRule("(SignExtend (Narrow=narrow FloatingRead=access))")
     public ComplexMatchResult signExtendNarrowRead(SignExtendNode root, NarrowNode narrow, LIRLowerableAccess access) {
-        LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp());
+        LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp(NodeView.DEFAULT));
         return emitSignExtendMemory(access, narrow.getResultBits(), root.getResultBits(), kind);
     }
 
@@ -554,7 +555,7 @@
     @MatchRule("(Reinterpret FloatingRead=access)")
     public ComplexMatchResult reinterpret(ReinterpretNode root, LIRLowerableAccess access) {
         return builder -> {
-            LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp());
+            LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
             return emitReinterpretMemory(kind, access);
         };
 
@@ -563,7 +564,7 @@
     @MatchRule("(Write object Reinterpret=reinterpret)")
     public ComplexMatchResult writeReinterpret(WriteNode root, ReinterpretNode reinterpret) {
         return builder -> {
-            LIRKind kind = getLIRGeneratorTool().getLIRKind(reinterpret.getValue().stamp());
+            LIRKind kind = getLIRGeneratorTool().getLIRKind(reinterpret.getValue().stamp(NodeView.DEFAULT));
             AllocatableValue value = getLIRGeneratorTool().asAllocatable(operand(reinterpret.getValue()));
 
             AMD64AddressValue address = (AMD64AddressValue) operand(root.getAddress());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java	Thu Dec 07 11:54:55 2017 +0000
@@ -251,22 +251,34 @@
     }
 
     public static Stamp[] createParameterStamps(Assumptions assumptions, ResolvedJavaMethod method) {
-        Signature sig = method.getSignature();
-        Stamp[] result = new Stamp[sig.getParameterCount(!method.isStatic())];
+        return createParameterStamps(assumptions, method, false);
+    }
+
+    public static Stamp[] createParameterStamps(Assumptions assumptions, ResolvedJavaMethod method, boolean trustInterfaceTypes) {
+        Signature signature = method.getSignature();
+        Stamp[] result = new Stamp[signature.getParameterCount(method.hasReceiver())];
+
         int index = 0;
-
-        if (!method.isStatic()) {
-            result[index++] = StampFactory.objectNonNull(TypeReference.create(assumptions, method.getDeclaringClass()));
+        ResolvedJavaType accessingClass = method.getDeclaringClass();
+        if (method.hasReceiver()) {
+            if (trustInterfaceTypes) {
+                result[index++] = StampFactory.objectNonNull(TypeReference.createTrusted(assumptions, accessingClass));
+            } else {
+                result[index++] = StampFactory.objectNonNull(TypeReference.create(assumptions, accessingClass));
+            }
         }
 
-        int max = sig.getParameterCount(false);
-        ResolvedJavaType accessingClass = method.getDeclaringClass();
-        for (int i = 0; i < max; i++) {
-            JavaType type = sig.getParameterType(i, accessingClass);
+        for (int i = 0; i < signature.getParameterCount(false); i++) {
+            JavaType type = signature.getParameterType(i, accessingClass);
             JavaKind kind = type.getJavaKind();
+
             Stamp stamp;
             if (kind == JavaKind.Object && type instanceof ResolvedJavaType) {
-                stamp = StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) type));
+                if (trustInterfaceTypes) {
+                    stamp = StampFactory.object(TypeReference.createTrusted(assumptions, (ResolvedJavaType) type));
+                } else {
+                    stamp = StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) type));
+                }
             } else {
                 stamp = StampFactory.forKind(kind);
             }
@@ -284,16 +296,28 @@
         if (returnType.getJavaKind() == JavaKind.Object && returnType instanceof ResolvedJavaType) {
             ResolvedJavaType resolvedJavaType = (ResolvedJavaType) returnType;
             TypeReference reference = TypeReference.create(assumptions, resolvedJavaType);
-            if (resolvedJavaType.isInterface()) {
-                ResolvedJavaType implementor = resolvedJavaType.getSingleImplementor();
-                if (implementor != null && !resolvedJavaType.equals(implementor)) {
-                    TypeReference uncheckedType = TypeReference.createTrusted(assumptions, implementor);
-                    return StampPair.create(StampFactory.object(reference, nonNull), StampFactory.object(uncheckedType, nonNull));
+            ResolvedJavaType elementalType = resolvedJavaType.getElementalType();
+            if (elementalType.isInterface()) {
+                assert reference == null || !reference.getType().equals(resolvedJavaType);
+                TypeReference uncheckedType;
+                ResolvedJavaType elementalImplementor = elementalType.getSingleImplementor();
+                if (elementalImplementor != null && !elementalType.equals(elementalImplementor)) {
+                    ResolvedJavaType implementor = elementalImplementor;
+                    ResolvedJavaType t = resolvedJavaType;
+                    while (t.isArray()) {
+                        implementor = implementor.getArrayClass();
+                        t = t.getComponentType();
+                    }
+                    uncheckedType = TypeReference.createTrusted(assumptions, implementor);
+                } else {
+                    uncheckedType = TypeReference.createTrusted(assumptions, resolvedJavaType);
                 }
+                return StampPair.create(StampFactory.object(reference, nonNull), StampFactory.object(uncheckedType, nonNull));
             }
             return StampPair.createSingle(StampFactory.object(reference, nonNull));
         } else {
             return StampPair.createSingle(StampFactory.forKind(returnType.getJavaKind()));
         }
     }
+
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCAddressLowering.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCAddressLowering.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,11 +34,6 @@
 public class SPARCAddressLowering extends AddressLowering {
 
     @Override
-    public AddressNode lower(ValueNode address) {
-        return lower(address, 0);
-    }
-
-    @Override
     public AddressNode lower(ValueNode base, ValueNode offset) {
         JavaConstant immBase = asImmediate(base);
         if (immBase != null && SPARCAssembler.isSimm13(immBase)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCImmediateAddressNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCImmediateAddressNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.sparc.SPARCImmediateAddressValue;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -59,7 +60,7 @@
 
         AllocatableValue baseValue = tool.asAllocatable(gen.operand(base));
 
-        LIRKind kind = tool.getLIRKind(stamp());
+        LIRKind kind = tool.getLIRKind(stamp(NodeView.DEFAULT));
         AllocatableValue baseReference = LIRKind.derivedBaseFromValue(baseValue);
         if (baseReference != null) {
             kind = kind.makeDerivedReference(baseReference);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIndexedAddressNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIndexedAddressNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.sparc.SPARCIndexedAddressValue;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -61,7 +62,7 @@
         AllocatableValue baseReference = LIRKind.derivedBaseFromValue(baseValue);
         AllocatableValue indexReference = LIRKind.derivedBaseFromValue(indexValue);
 
-        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
+        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
         gen.setResult(this, new SPARCIndexedAddressValue(kind, baseValue, indexValue));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIntegerCompareCanonicalizationPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIntegerCompareCanonicalizationPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -59,7 +60,7 @@
     }
 
     private static void min32(CompareNode enode, ValueNode v) {
-        Stamp s = v.stamp();
+        Stamp s = v.stamp(NodeView.DEFAULT);
         if (s instanceof IntegerStamp) {
             int bits = ((IntegerStamp) s).getBits();
             if (bits != 32 && bits != 64) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
 
+import org.graalvm.compiler.nodes.NodeView;
 import org.junit.Test;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
@@ -223,7 +224,7 @@
         @Input private ValueNode iv;
 
         protected IVPropertyNode(IVProperty property, ValueNode iv) {
-            super(TYPE, iv.stamp().unrestricted());
+            super(TYPE, iv.stamp(NodeView.DEFAULT).unrestricted());
             this.property = property;
             this.iv = iv;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -166,7 +166,8 @@
         ImprovementSavingCanonicalizer c2 = new ImprovementSavingCanonicalizer();
         StructuredGraph g2 = parseForCompile(getResolvedJavaMethod("test2Snippet"));
         new CanonicalizerPhase(c2).apply(g2, htc);
-        Assert.assertTrue(c1.savedCycles > c2.savedCycles);
+        Assert.assertEquals(0, c1.savedCycles);
+        Assert.assertEquals(0, c2.savedCycles);
     }
 
     private static void prepareGraphForLoopFrequencies(StructuredGraph g, HighTierContext htc) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UncheckedInterfaceProviderTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, 2017, 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.graalvm.compiler.core.test;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+
+import jdk.vm.ci.meta.ResolvedJavaType;
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.nodeinfo.Verbosity;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.debug.BlackholeNode;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
+import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
+import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
+import org.graalvm.compiler.nodes.type.StampTool;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class UncheckedInterfaceProviderTest extends GraalCompilerTest {
+    private Runnable interfaceField;
+    private Runnable[] interfaceArrayField;
+
+    public void snippet(Runnable interfaceParameter, Runnable[] interfaceArrayParameter) {
+        GraalDirectives.blackhole(interfaceParameter);
+        GraalDirectives.blackhole(interfaceArrayParameter);
+        GraalDirectives.blackhole(interfaceField);
+        GraalDirectives.blackhole(interfaceArrayField);
+        GraalDirectives.blackhole(interfaceReturn());
+        GraalDirectives.blackhole(interfaceArrayReturn());
+        GraalDirectives.blackhole(interfaceReturnException());
+        GraalDirectives.blackhole(interfaceArrayReturnException());
+    }
+
+    public static Runnable interfaceReturn() {
+        return new A();
+    }
+
+    public static Runnable[] interfaceArrayReturn() {
+        return new Runnable[]{new A(), new B(), new C(), new D()};
+    }
+
+    public static Runnable interfaceReturnException() {
+        return new A();
+    }
+
+    public static Runnable[] interfaceArrayReturnException() {
+        return new Runnable[]{new A(), new B(), new C(), new D()};
+    }
+
+    @Override
+    protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        if (method.getName().startsWith("interfaceReturn") || method.getName().startsWith("interfaceArrayReturn")) {
+            if (method.getName().equals("Exception")) {
+                return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
+            }
+            return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
+        }
+        return super.bytecodeParserShouldInlineInvoke(b, method, args);
+    }
+
+    @BeforeClass
+    public static void setup() {
+        interfaceArrayReturn();
+    }
+
+    @Test
+    public void test() {
+        StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
+        for (BlackholeNode b : graph.getNodes().filter(BlackholeNode.class)) {
+            Assert.assertThat(b.getValue(), is(instanceOf(UncheckedInterfaceProvider.class)));
+            Stamp uncheckedStamp = ((UncheckedInterfaceProvider) b.getValue()).uncheckedStamp();
+            String context = b.getValue().toString(Verbosity.Debugger);
+            Assert.assertNotNull(context, uncheckedStamp);
+            ResolvedJavaType uncheckedType = StampTool.typeOrNull(uncheckedStamp);
+            ResolvedJavaType type = StampTool.typeOrNull(b.getValue());
+            Assert.assertEquals(context, arrayDepth(type), arrayDepth(uncheckedType));
+            Assert.assertTrue(context + ": " + type, type == null || type.getElementalType().isJavaLangObject());
+            Assert.assertNotNull(context, uncheckedType);
+            Assert.assertTrue(context, uncheckedType.getElementalType().isInterface());
+        }
+    }
+
+    private static int arrayDepth(ResolvedJavaType type) {
+        int depth = 0;
+        ResolvedJavaType t = type;
+        while (t != null && t.isArray()) {
+            depth += 1;
+            t = t.getComponentType();
+        }
+        return depth;
+    }
+
+    public static class A implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+
+    public static class B implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+
+    public static class C implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+
+    public static class D implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -22,14 +22,7 @@
  */
 package org.graalvm.compiler.core.test.deopt;
 
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.InvalidInstalledCodeException;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-import org.junit.Assert;
-import org.junit.Test;
-
+import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -37,16 +30,19 @@
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.Test;
 
-/**
- * In the following tests, the usages of local variable "a" are replaced with the integer constant
- * 0. Then canonicalization is applied and it is verified that the resulting graph is equal to the
- * graph of the method that just has a "return 1" statement in it.
- */
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class CompiledMethodTest extends GraalCompilerTest {
 
     public static Object testMethod(Object arg1, Object arg2, Object arg3) {
-        return arg1 + " " + arg2 + " " + arg3;
+        String res = arg1 + " " + arg2 + " " + arg3;
+        return GraalDirectives.inCompiledCode() ? res : "interpreter";
     }
 
     Object f1;
@@ -55,6 +51,12 @@
         return f1 + " " + arg1 + " " + arg2 + " " + arg3;
     }
 
+    /**
+     * Usages of the constant {@code " "} are replaced with the constant {@code "-"} and it is
+     * verified that executing the compiled code produces a result that the preserves the node
+     * replacement unless deoptimization occurs (e.g., due to -Xcomp causing profiles to be
+     * missing).
+     */
     @Test
     public void test1() {
         final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod");
@@ -71,7 +73,10 @@
         InstalledCode compiledMethod = getCode(javaMethod, graph);
         try {
             Object result = compiledMethod.executeVarargs("1", "2", "3");
-            Assert.assertEquals("1-2-3", result);
+            if (!"1-2-3".equals(result)) {
+                // Deoptimization probably occurred
+                Assert.assertEquals("interpreter", result);
+            }
         } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeUnsafeStoreTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (c) 2016, 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.graalvm.compiler.core.test.ea;
+
+import java.lang.reflect.Field;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.junit.Test;
+
+import sun.misc.Unsafe;
+
+/**
+ * Exercise a mix of unsafe and normal reads ands writes in situations where EA might attempt to
+ * fold the operations.
+ */
+public class PartialEscapeUnsafeStoreTest extends GraalCompilerTest {
+
+    private static final Unsafe unsafe = initUnsafe();
+
+    private static Unsafe initUnsafe() {
+        try {
+            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafe.setAccessible(true);
+            return (Unsafe) theUnsafe.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe", e);
+        }
+    }
+
+    private static final long byteArrayBaseOffset = unsafe.arrayBaseOffset(byte[].class);
+    private static byte byteValue = 0x61;
+
+    public static byte[] testByteArrayWithCharStoreSnippet(char v) {
+        byte[] b = new byte[8];
+        unsafe.putChar(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithCharStore() {
+        test("testByteArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static byte[] testByteArrayWithShortStoreSnippet(short v) {
+        byte[] b = new byte[8];
+        unsafe.putShort(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithShortStore() {
+        test("testByteArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static byte[] testByteArrayWithIntStoreSnippet(int v) {
+        byte[] b = new byte[8];
+        unsafe.putInt(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithIntStore() {
+        test("testByteArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static byte[] testByteArrayWithLongStoreSnippet(long v) {
+        byte[] b = new byte[8];
+        unsafe.putLong(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithLongStore() {
+        test("testByteArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static byte[] testByteArrayWithFloatStoreSnippet(float v) {
+        byte[] b = new byte[8];
+        unsafe.putFloat(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithFloatStore() {
+        test("testByteArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static byte[] testByteArrayWithDoubleStoreSnippet(double v) {
+        byte[] b = new byte[8];
+        unsafe.putDouble(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithDoubleStore() {
+        test("testByteArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long charArrayBaseOffset = unsafe.arrayBaseOffset(char[].class);
+    private static char charValue = 0x4142;
+
+    public static char[] testCharArrayWithByteStoreSnippet(byte v) {
+        char[] b = new char[4];
+        unsafe.putByte(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithByteStore() {
+        test("testCharArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static char[] testCharArrayWithShortStoreSnippet(short v) {
+        char[] b = new char[4];
+        unsafe.putShort(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithShortStore() {
+        test("testCharArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static char[] testCharArrayWithIntStoreSnippet(int v) {
+        char[] b = new char[4];
+        unsafe.putInt(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithIntStore() {
+        test("testCharArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static char[] testCharArrayWithLongStoreSnippet(long v) {
+        char[] b = new char[4];
+        unsafe.putLong(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithLongStore() {
+        test("testCharArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static char[] testCharArrayWithFloatStoreSnippet(float v) {
+        char[] b = new char[4];
+        unsafe.putFloat(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithFloatStore() {
+        test("testCharArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static char[] testCharArrayWithDoubleStoreSnippet(double v) {
+        char[] b = new char[4];
+        unsafe.putDouble(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithDoubleStore() {
+        test("testCharArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long shortArrayBaseOffset = unsafe.arrayBaseOffset(short[].class);
+    private static short shortValue = 0x1112;
+
+    public static short[] testShortArrayWithByteStoreSnippet(byte v) {
+        short[] b = new short[4];
+        unsafe.putByte(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithByteStore() {
+        test("testShortArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static short[] testShortArrayWithCharStoreSnippet(char v) {
+        short[] b = new short[4];
+        unsafe.putChar(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithCharStore() {
+        test("testShortArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static short[] testShortArrayWithIntStoreSnippet(int v) {
+        short[] b = new short[4];
+        unsafe.putInt(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithIntStore() {
+        test("testShortArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static short[] testShortArrayWithLongStoreSnippet(long v) {
+        short[] b = new short[4];
+        unsafe.putLong(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithLongStore() {
+        test("testShortArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static short[] testShortArrayWithFloatStoreSnippet(float v) {
+        short[] b = new short[4];
+        unsafe.putFloat(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithFloatStore() {
+        test("testShortArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static short[] testShortArrayWithDoubleStoreSnippet(double v) {
+        short[] b = new short[4];
+        unsafe.putDouble(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithDoubleStore() {
+        test("testShortArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long intArrayBaseOffset = unsafe.arrayBaseOffset(int[].class);
+    private static int intValue = 0x01020304;
+
+    public static int[] testIntArrayWithByteStoreSnippet(byte v) {
+        int[] b = new int[4];
+        unsafe.putByte(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithByteStore() {
+        test("testIntArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static int[] testIntArrayWithCharStoreSnippet(char v) {
+        int[] b = new int[4];
+        unsafe.putChar(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithCharStore() {
+        test("testIntArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static int[] testIntArrayWithShortStoreSnippet(short v) {
+        int[] b = new int[4];
+        unsafe.putShort(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithShortStore() {
+        test("testIntArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static int[] testIntArrayWithLongStoreSnippet(long v) {
+        int[] b = new int[4];
+        unsafe.putLong(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithLongStore() {
+        test("testIntArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static int[] testIntArrayWithFloatStoreSnippet(float v) {
+        int[] b = new int[4];
+        unsafe.putFloat(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithFloatStore() {
+        test("testIntArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static int[] testIntArrayWithDoubleStoreSnippet(double v) {
+        int[] b = new int[4];
+        unsafe.putDouble(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithDoubleStore() {
+        test("testIntArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long longArrayBaseOffset = unsafe.arrayBaseOffset(long[].class);
+    private static long longValue = 0x31323334353637L;
+
+    public static long[] testLongArrayWithByteStoreSnippet(byte v) {
+        long[] b = new long[4];
+        unsafe.putByte(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithByteStore() {
+        test("testLongArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static long[] testLongArrayWithCharStoreSnippet(char v) {
+        long[] b = new long[4];
+        unsafe.putChar(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithCharStore() {
+        test("testLongArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static long[] testLongArrayWithShortStoreSnippet(short v) {
+        long[] b = new long[4];
+        unsafe.putShort(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithShortStore() {
+        test("testLongArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static long[] testLongArrayWithIntStoreSnippet(int v) {
+        long[] b = new long[4];
+        unsafe.putInt(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithIntStore() {
+        test("testLongArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static long[] testLongArrayWithFloatStoreSnippet(float v) {
+        long[] b = new long[4];
+        unsafe.putFloat(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithFloatStore() {
+        test("testLongArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static long[] testLongArrayWithDoubleStoreSnippet(double v) {
+        long[] b = new long[4];
+        unsafe.putDouble(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithDoubleStore() {
+        test("testLongArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long floatArrayBaseOffset = unsafe.arrayBaseOffset(float[].class);
+    private static float floatValue = Float.NaN;
+
+    public static float[] testFloatArrayWithByteStoreSnippet(byte v) {
+        float[] b = new float[4];
+        unsafe.putByte(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithByteStore() {
+        test("testFloatArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static float[] testFloatArrayWithCharStoreSnippet(char v) {
+        float[] b = new float[4];
+        unsafe.putChar(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithCharStore() {
+        test("testFloatArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static float[] testFloatArrayWithShortStoreSnippet(short v) {
+        float[] b = new float[4];
+        unsafe.putShort(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithShortStore() {
+        test("testFloatArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static float[] testFloatArrayWithIntStoreSnippet(int v) {
+        float[] b = new float[4];
+        unsafe.putInt(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithIntStore() {
+        test("testFloatArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static float[] testFloatArrayWithLongStoreSnippet(long v) {
+        float[] b = new float[4];
+        unsafe.putLong(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithLongStore() {
+        test("testFloatArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static float[] testFloatArrayWithDoubleStoreSnippet(double v) {
+        float[] b = new float[4];
+        unsafe.putDouble(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithDoubleStore() {
+        test("testFloatArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long doubleArrayBaseOffset = unsafe.arrayBaseOffset(double[].class);
+    private static double doubleValue = Double.NaN;
+    private static final int byteSize = 1;
+    private static final int charSize = 2;
+    private static final int shortSize = 2;
+    private static final int intSize = 4;
+    private static final int floatSize = 4;
+    private static final int longSize = 8;
+    private static final int doubleSize = 8;
+
+    public static double[] testDoubleArrayWithByteStoreSnippet(byte v) {
+        double[] b = new double[4];
+        unsafe.putByte(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithByteStore() {
+        test("testDoubleArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static double[] testDoubleArrayWithCharStoreSnippet(char v) {
+        double[] b = new double[4];
+        unsafe.putChar(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithCharStore() {
+        test("testDoubleArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static double[] testDoubleArrayWithShortStoreSnippet(short v) {
+        double[] b = new double[4];
+        unsafe.putShort(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithShortStore() {
+        test("testDoubleArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static double[] testDoubleArrayWithIntStoreSnippet(int v) {
+        double[] b = new double[4];
+        unsafe.putInt(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithIntStore() {
+        test("testDoubleArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static double[] testDoubleArrayWithLongStoreSnippet(long v) {
+        double[] b = new double[4];
+        unsafe.putLong(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithLongStore() {
+        test("testDoubleArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static double[] testDoubleArrayWithFloatStoreSnippet(float v) {
+        double[] b = new double[4];
+        unsafe.putFloat(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithFloatStore() {
+        test("testDoubleArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static byte testByteArrayWithCharStoreAndReadSnippet(char v) {
+        byte[] b = new byte[4];
+        unsafe.putChar(b, byteArrayBaseOffset, v);
+        return b[(byteSize / charSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithCharStoreAndRead() {
+        test("testByteArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static byte testByteArrayWithShortStoreAndReadSnippet(short v) {
+        byte[] b = new byte[4];
+        unsafe.putShort(b, byteArrayBaseOffset, v);
+        return b[(byteSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithShortStoreAndRead() {
+        test("testByteArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static byte testByteArrayWithIntStoreAndReadSnippet(int v) {
+        byte[] b = new byte[4];
+        unsafe.putInt(b, byteArrayBaseOffset, v);
+        return b[(byteSize / intSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithIntStoreAndRead() {
+        test("testByteArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static byte testByteArrayWithLongStoreAndReadSnippet(long v) {
+        byte[] b = new byte[4];
+        unsafe.putLong(b, byteArrayBaseOffset, v);
+        return b[(byteSize / longSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithLongStoreAndRead() {
+        test("testByteArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static byte testByteArrayWithFloatStoreAndReadSnippet(float v) {
+        byte[] b = new byte[4];
+        unsafe.putFloat(b, byteArrayBaseOffset, v);
+        return b[(byteSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithFloatStoreAndRead() {
+        test("testByteArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static byte testByteArrayWithDoubleStoreAndReadSnippet(double v) {
+        byte[] b = new byte[4];
+        unsafe.putDouble(b, byteArrayBaseOffset, v);
+        return b[(byteSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithDoubleStoreAndRead() {
+        test("testByteArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static char testCharArrayWithByteStoreAndReadSnippet(byte v) {
+        char[] b = new char[4];
+        unsafe.putByte(b, charArrayBaseOffset, v);
+        return b[(charSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithByteStoreAndRead() {
+        test("testCharArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static char testCharArrayWithShortStoreAndReadSnippet(short v) {
+        char[] b = new char[4];
+        unsafe.putShort(b, charArrayBaseOffset, v);
+        return b[(charSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithShortStoreAndRead() {
+        test("testCharArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static char testCharArrayWithIntStoreAndReadSnippet(int v) {
+        char[] b = new char[4];
+        unsafe.putInt(b, charArrayBaseOffset, v);
+        return b[(charSize / intSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithIntStoreAndRead() {
+        test("testCharArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static char testCharArrayWithLongStoreAndReadSnippet(long v) {
+        char[] b = new char[4];
+        unsafe.putLong(b, charArrayBaseOffset, v);
+        return b[(charSize / longSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithLongStoreAndRead() {
+        test("testCharArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static char testCharArrayWithFloatStoreAndReadSnippet(float v) {
+        char[] b = new char[4];
+        unsafe.putFloat(b, charArrayBaseOffset, v);
+        return b[(charSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithFloatStoreAndRead() {
+        test("testCharArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static char testCharArrayWithDoubleStoreAndReadSnippet(double v) {
+        char[] b = new char[4];
+        unsafe.putDouble(b, charArrayBaseOffset, v);
+        return b[(charSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithDoubleStoreAndRead() {
+        test("testCharArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static short testShortArrayWithByteStoreAndReadSnippet(byte v) {
+        short[] b = new short[4];
+        unsafe.putByte(b, shortArrayBaseOffset, v);
+        return b[(shortSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithByteStoreAndRead() {
+        test("testShortArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static short testShortArrayWithCharStoreAndReadSnippet(char v) {
+        short[] b = new short[4];
+        unsafe.putChar(b, shortArrayBaseOffset, v);
+        return b[(shortSize / charSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithCharStoreAndRead() {
+        test("testShortArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static short testShortArrayWithIntStoreAndReadSnippet(int v) {
+        short[] b = new short[4];
+        unsafe.putInt(b, shortArrayBaseOffset, v);
+        return b[(shortSize / intSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithIntStoreAndRead() {
+        test("testShortArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static short testShortArrayWithLongStoreAndReadSnippet(long v) {
+        short[] b = new short[4];
+        unsafe.putLong(b, shortArrayBaseOffset, v);
+        return b[(shortSize / longSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithLongStoreAndRead() {
+        test("testShortArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static short testShortArrayWithFloatStoreAndReadSnippet(float v) {
+        short[] b = new short[4];
+        unsafe.putFloat(b, shortArrayBaseOffset, v);
+        return b[(shortSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithFloatStoreAndRead() {
+        test("testShortArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static short testShortArrayWithDoubleStoreAndReadSnippet(double v) {
+        short[] b = new short[4];
+        unsafe.putDouble(b, shortArrayBaseOffset, v);
+        return b[(shortSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithDoubleStoreAndRead() {
+        test("testShortArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static int testIntArrayWithByteStoreAndReadSnippet(byte v) {
+        int[] b = new int[4];
+        unsafe.putByte(b, intArrayBaseOffset, v);
+        return b[(intSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithByteStoreAndRead() {
+        test("testIntArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static int testIntArrayWithCharStoreAndReadSnippet(char v) {
+        int[] b = new int[4];
+        unsafe.putChar(b, intArrayBaseOffset, v);
+        return b[(intSize / charSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithCharStoreAndRead() {
+        test("testIntArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static int testIntArrayWithShortStoreAndReadSnippet(short v) {
+        int[] b = new int[4];
+        unsafe.putShort(b, intArrayBaseOffset, v);
+        return b[(intSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithShortStoreAndRead() {
+        test("testIntArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static int testIntArrayWithLongStoreAndReadSnippet(long v) {
+        int[] b = new int[4];
+        unsafe.putLong(b, intArrayBaseOffset, v);
+        return b[(intSize / longSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithLongStoreAndRead() {
+        test("testIntArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static int testIntArrayWithFloatStoreAndReadSnippet(float v) {
+        int[] b = new int[4];
+        unsafe.putFloat(b, intArrayBaseOffset, v);
+        return b[(intSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithFloatStoreAndRead() {
+        test("testIntArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static int testIntArrayWithDoubleStoreAndReadSnippet(double v) {
+        int[] b = new int[4];
+        unsafe.putDouble(b, intArrayBaseOffset, v);
+        return b[(intSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithDoubleStoreAndRead() {
+        test("testIntArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static long testLongArrayWithByteStoreAndReadSnippet(byte v) {
+        long[] b = new long[4];
+        unsafe.putByte(b, longArrayBaseOffset, v);
+        return b[(longSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithByteStoreAndRead() {
+        test("testLongArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static long testLongArrayWithCharStoreAndReadSnippet(char v) {
+        long[] b = new long[4];
+        unsafe.putChar(b, longArrayBaseOffset, v);
+        return b[(longSize / charSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithCharStoreAndRead() {
+        test("testLongArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static long testLongArrayWithShortStoreAndReadSnippet(short v) {
+        long[] b = new long[4];
+        unsafe.putShort(b, longArrayBaseOffset, v);
+        return b[(longSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithShortStoreAndRead() {
+        test("testLongArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static long testLongArrayWithIntStoreAndReadSnippet(int v) {
+        long[] b = new long[4];
+        unsafe.putInt(b, longArrayBaseOffset, v);
+        return b[(longSize / intSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithIntStoreAndRead() {
+        test("testLongArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static long testLongArrayWithFloatStoreAndReadSnippet(float v) {
+        long[] b = new long[4];
+        unsafe.putFloat(b, longArrayBaseOffset, v);
+        return b[(longSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithFloatStoreAndRead() {
+        test("testLongArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static long testLongArrayWithDoubleStoreAndReadSnippet(double v) {
+        long[] b = new long[4];
+        unsafe.putDouble(b, longArrayBaseOffset, v);
+        return b[(longSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithDoubleStoreAndRead() {
+        test("testLongArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static float testFloatArrayWithByteStoreAndReadSnippet(byte v) {
+        float[] b = new float[4];
+        unsafe.putByte(b, floatArrayBaseOffset, v);
+        return b[(floatSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithByteStoreAndRead() {
+        test("testFloatArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static float testFloatArrayWithCharStoreAndReadSnippet(char v) {
+        float[] b = new float[4];
+        unsafe.putChar(b, floatArrayBaseOffset, v);
+        return b[(floatSize / charSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithCharStoreAndRead() {
+        test("testFloatArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static float testFloatArrayWithShortStoreAndReadSnippet(short v) {
+        float[] b = new float[4];
+        unsafe.putShort(b, floatArrayBaseOffset, v);
+        return b[(floatSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithShortStoreAndRead() {
+        test("testFloatArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static float testFloatArrayWithIntStoreAndReadSnippet(int v) {
+        float[] b = new float[4];
+        unsafe.putInt(b, floatArrayBaseOffset, v);
+        return b[(floatSize / intSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithIntStoreAndRead() {
+        test("testFloatArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static float testFloatArrayWithLongStoreAndReadSnippet(long v) {
+        float[] b = new float[4];
+        unsafe.putLong(b, floatArrayBaseOffset, v);
+        return b[(floatSize / longSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithLongStoreAndRead() {
+        test("testFloatArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static float testFloatArrayWithDoubleStoreAndReadSnippet(double v) {
+        float[] b = new float[4];
+        unsafe.putDouble(b, floatArrayBaseOffset, v);
+        return b[(floatSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithDoubleStoreAndRead() {
+        test("testFloatArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static double testDoubleArrayWithByteStoreAndReadSnippet(byte v) {
+        double[] b = new double[4];
+        unsafe.putByte(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithByteStoreAndRead() {
+        test("testDoubleArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static double testDoubleArrayWithCharStoreAndReadSnippet(char v) {
+        double[] b = new double[4];
+        unsafe.putChar(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / charSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithCharStoreAndRead() {
+        test("testDoubleArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static double testDoubleArrayWithShortStoreAndReadSnippet(short v) {
+        double[] b = new double[4];
+        unsafe.putShort(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithShortStoreAndRead() {
+        test("testDoubleArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static double testDoubleArrayWithIntStoreAndReadSnippet(int v) {
+        double[] b = new double[4];
+        unsafe.putInt(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / intSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithIntStoreAndRead() {
+        test("testDoubleArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static double testDoubleArrayWithLongStoreAndReadSnippet(long v) {
+        double[] b = new double[4];
+        unsafe.putLong(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / longSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithLongStoreAndRead() {
+        test("testDoubleArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static double testDoubleArrayWithFloatStoreAndReadSnippet(float v) {
+        double[] b = new double[4];
+        unsafe.putFloat(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithFloatStoreAndRead() {
+        test("testDoubleArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2012, 2016, 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.graalvm.compiler.core.test.inlining;
+
+import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine;
+import static org.graalvm.compiler.test.SubprocessUtil.java;
+import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugDumpScope;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.InvokeNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.StructuredGraph.Builder;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.nodes.java.TypeSwitchNode;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
+import org.graalvm.compiler.phases.common.inlining.InliningPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+public class PolymorphicInliningTest extends GraalCompilerTest {
+
+    @Test
+    public void testInSubprocess() throws InterruptedException, IOException {
+        String recursionPropName = getClass().getName() + ".recursion";
+        if (Boolean.getBoolean(recursionPropName)) {
+            testPolymorphicInlining();
+            testPolymorphicNotInlining();
+            testMegamorphicInlining();
+            testMegamorphicNotInlining();
+        } else {
+            List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine());
+            NotInlinableSubClass.class.getCanonicalName();
+            vmArgs.add("-XX:CompileCommand=dontinline,org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest$NotInlinableSubClass.publicOverriddenMethod");
+            vmArgs.add("-D" + recursionPropName + "=true");
+            SubprocessUtil.Subprocess proc = java(vmArgs, "com.oracle.mxtool.junit.MxJUnitWrapper", getClass().getName());
+            if (proc.exitCode != 0) {
+                Assert.fail(String.format("non-zero exit code %d for command:%n%s", proc.exitCode, proc));
+            }
+        }
+    }
+
+    public int polymorphicCallsite(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testPolymorphicInlining() {
+        for (int i = 0; i < 10000; i++) {
+            if (i % 2 == 0) {
+                polymorphicCallsite(Receivers.subClassA);
+            } else {
+                polymorphicCallsite(Receivers.subClassB);
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite", false);
+        // This callsite should be inlined with a TypeCheckedInliningViolated deoptimization.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 0);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 1);
+        assertTrue(getNodeCount(graph, DeoptimizeNode.class) >= 1);
+    }
+
+    /**
+     * This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
+     * interference of the receiver type profile from different unit tests.
+     */
+    public int polymorphicCallsite1(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testPolymorphicNotInlining() {
+        for (int i = 0; i < 10000; i++) {
+            if (i % 2 == 0) {
+                polymorphicCallsite1(Receivers.subClassA);
+            } else {
+                polymorphicCallsite1(Receivers.notInlinableSubClass);
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite1", false);
+        // This callsite should not be inlined due to one of the potential callee method is not
+        // inlinable.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 0);
+    }
+
+    /**
+     * This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
+     * interference of the receiver type profile from different unit tests.
+     */
+    public int polymorphicCallsite2(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testMegamorphicInlining() {
+        // Construct a receiver type profile that exceeds the max type width (by default 8 in JVMCI,
+        // specified by -XX:TypeProfileWidth).
+        for (int i = 0; i < 2000; i++) {
+            // Ensure the following receiver type is within the type profile.
+            polymorphicCallsite2(Receivers.subClassA);
+        }
+        for (int i = 0; i < 10000; i++) {
+            switch (i % 20) {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                case 5:
+                case 6:
+                case 7:
+                    // Probability: 40%
+                    // Ensure the probability is greater than
+                    // GraalOptions.MegamorphicInliningMinMethodProbability (by default 0.33D);
+                    polymorphicCallsite2(Receivers.subClassA);
+                    break;
+                case 8:
+                    polymorphicCallsite2(Receivers.subClassB);
+                    break;
+                case 9:
+                    polymorphicCallsite2(Receivers.subClassC);
+                    break;
+                case 10:
+                    polymorphicCallsite2(Receivers.subClassD);
+                    break;
+                case 11:
+                    polymorphicCallsite2(Receivers.subClassE);
+                    break;
+                case 12:
+                    polymorphicCallsite2(Receivers.subClassF);
+                    break;
+                case 13:
+                    polymorphicCallsite2(Receivers.subClassG);
+                    break;
+                case 14:
+                    polymorphicCallsite2(Receivers.subClassH);
+                    break;
+                default:
+                    // Probability: 25%
+                    polymorphicCallsite2(Receivers.notInlinableSubClass);
+                    break;
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite2", false);
+        // This callsite should be inlined with a fallback invocation.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 1);
+    }
+
+    /**
+     * This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
+     * interference of the receiver type profile from different unit tests.
+     */
+    public int polymorphicCallsite3(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testMegamorphicNotInlining() {
+        for (int i = 0; i < 10000; i++) {
+            switch (i % 10) {
+                case 0:
+                case 1:
+                    polymorphicCallsite3(Receivers.subClassA);
+                    break;
+                case 2:
+                    polymorphicCallsite3(Receivers.subClassB);
+                    break;
+                case 3:
+                    polymorphicCallsite3(Receivers.subClassC);
+                    break;
+                case 4:
+                    polymorphicCallsite3(Receivers.subClassD);
+                    break;
+                case 5:
+                    polymorphicCallsite3(Receivers.subClassE);
+                    break;
+                case 6:
+                    polymorphicCallsite3(Receivers.subClassF);
+                    break;
+                case 7:
+                    polymorphicCallsite3(Receivers.subClassG);
+                    break;
+                case 8:
+                    polymorphicCallsite3(Receivers.subClassH);
+                    break;
+                default:
+                    polymorphicCallsite3(Receivers.notInlinableSubClass);
+                    break;
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite3", false);
+        // This callsite should not be inlined due to non of the potential callee method exceeds the
+        // probability specified by GraalOptions.MegamorphicInliningMinMethodProbability.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 0);
+    }
+
+    @SuppressWarnings("try")
+    private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
+        DebugContext debug = getDebugContext();
+        try (DebugContext.Scope s = debug.scope("InliningTest", new DebugDumpScope(snippet, true))) {
+            ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+            Builder builder = builder(method, AllowAssumptions.YES, debug);
+            StructuredGraph graph = eagerInfopointMode ? parse(builder, getDebugGraphBuilderSuite()) : parse(builder, getEagerGraphBuilderSuite());
+            try (DebugContext.Scope s2 = debug.scope("Inlining", graph)) {
+                PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode
+                                ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true))
+                                : getDefaultGraphBuilderSuite();
+                HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
+                debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
+                new CanonicalizerPhase().apply(graph, context);
+                new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
+                debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
+                new CanonicalizerPhase().apply(graph, context);
+                new DeadCodeEliminationPhase().apply(graph);
+                return graph;
+            }
+        } catch (Throwable e) {
+            throw debug.handle(e);
+        }
+    }
+
+    private static int getNodeCount(StructuredGraph graph, Class<? extends Node> nodeClass) {
+        return graph.getNodes().filter(nodeClass).count();
+    }
+
+    private static final class Receivers {
+        static final SubClassA subClassA = new SubClassA();
+        static final SubClassB subClassB = new SubClassB();
+        static final SubClassC subClassC = new SubClassC();
+        static final SubClassD subClassD = new SubClassD();
+        static final SubClassE subClassE = new SubClassE();
+        static final SubClassF subClassF = new SubClassF();
+        static final SubClassG subClassG = new SubClassG();
+        static final SubClassH subClassH = new SubClassH();
+
+        static final NotInlinableSubClass notInlinableSubClass = new NotInlinableSubClass();
+    }
+
+    private abstract static class SuperClass {
+
+        public abstract int publicOverriddenMethod();
+
+    }
+
+    private static class SubClassA extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'A';
+        }
+
+    }
+
+    private static class SubClassB extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'B';
+        }
+
+    }
+
+    private static class SubClassC extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'C';
+        }
+
+    }
+
+    private static class SubClassD extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'D';
+        }
+
+    }
+
+    private static class SubClassE extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'E';
+        }
+
+    }
+
+    private static class SubClassF extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'F';
+        }
+
+    }
+
+    private static class SubClassG extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'G';
+        }
+
+    }
+
+    private static class SubClassH extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'H';
+        }
+
+    }
+
+    private static final class NotInlinableSubClass extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'X';
+        }
+
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -81,6 +81,7 @@
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoweredCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -243,7 +244,7 @@
     }
 
     protected LIRKind getExactPhiKind(PhiNode phi) {
-        LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp()));
+        LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp(NodeView.DEFAULT)));
         /* Collect reference information. */
         for (int i = 0; i < phi.valueCount() && !derivedKind.isUnknownReference(); i++) {
             ValueNode node = phi.valueAt(i);
@@ -255,7 +256,7 @@
                 valueKind = value.getValueKind(LIRKind.class);
             } else {
                 assert isPhiInputFromBackedge(phi, i) : String.format("Input %s to phi node %s is not yet available although it is not coming from a loop back edge", node, phi);
-                LIRKind kind = gen.getLIRKind(node.stamp());
+                LIRKind kind = gen.getLIRKind(node.stamp(NodeView.DEFAULT));
                 valueKind = gen.toRegisterKind(kind);
             }
             /* Merge the reference information of the derived kind and the input. */
@@ -448,7 +449,7 @@
     }
 
     protected void emitNode(ValueNode node) {
-        if (node.getDebug().isLogEnabled() && node.stamp().isEmpty()) {
+        if (node.getDebug().isLogEnabled() && node.stamp(NodeView.DEFAULT).isEmpty()) {
             node.getDebug().log("This node has an empty stamp, we are emitting dead code(?): %s", node);
         }
         setSourcePosition(node.getNodeSourcePosition());
@@ -477,7 +478,8 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp());
+            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue + " " +
+                            getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT));
             setResult(param, gen.emitMove(paramValue));
         }
     }
@@ -506,7 +508,7 @@
     }
 
     protected LIRKind getPhiKind(PhiNode phi) {
-        return gen.getLIRKind(phi.stamp());
+        return gen.getLIRKind(phi.stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -529,13 +531,13 @@
     }
 
     private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        LIRKind kind = gen.getLIRKind(node.getValue().stamp());
+        LIRKind kind = gen.getLIRKind(node.getValue().stamp(NodeView.DEFAULT));
         Value nullValue = gen.emitConstant(kind, JavaConstant.NULL_POINTER);
         gen.emitCompareBranch(kind.getPlatformKind(), operand(node.getValue()), nullValue, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind();
+        PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
         gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
@@ -558,12 +560,12 @@
     public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) {
         if (node instanceof IsNullNode) {
             IsNullNode isNullNode = (IsNullNode) node;
-            LIRKind kind = gen.getLIRKind(isNullNode.getValue().stamp());
+            LIRKind kind = gen.getLIRKind(isNullNode.getValue().stamp(NodeView.DEFAULT));
             Value nullValue = gen.emitConstant(kind, JavaConstant.NULL_POINTER);
             return gen.emitConditionalMove(kind.getPlatformKind(), operand(isNullNode.getValue()), nullValue, Condition.EQ, false, trueValue, falseValue);
         } else if (node instanceof CompareNode) {
             CompareNode compare = (CompareNode) node;
-            PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind();
+            PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
             return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
         } else if (node instanceof LogicConstantNode) {
             return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
@@ -579,7 +581,8 @@
     public void emitInvoke(Invoke x) {
         LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
         FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
-        CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()), callTarget.signature(), gen);
+        CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess()),
+                        callTarget.signature(), gen);
         frameMapBuilder.callsMethod(invokeCc);
 
         Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
@@ -650,7 +653,7 @@
             if (keyCount == 1) {
                 assert defaultTarget != null;
                 double probability = x.probability(x.keySuccessor(0));
-                LIRKind kind = gen.getLIRKind(x.value().stamp());
+                LIRKind kind = gen.getLIRKind(x.value().stamp(NodeView.DEFAULT));
                 Value key = gen.emitConstant(kind, x.keyAt(0));
                 gen.emitCompareBranch(kind.getPlatformKind(), gen.load(operand(x.value())), key, Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
             } else if (x instanceof IntegerSwitchNode && x.isSorted()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/VersionsTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2013, 2017, 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.graalvm.compiler.debug.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashMap;
+import java.util.Map;
+import org.graalvm.compiler.debug.Versions;
+import org.junit.After;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+import org.junit.Test;
+
+public class VersionsTest {
+    private File temporaryDirectory;
+
+    @After
+    public void cleanUp() throws IOException {
+        if (temporaryDirectory != null) {
+            Files.walkFileTree(temporaryDirectory.toPath(), new FileVisitor<Path>() {
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+                    Files.delete(dir);
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+        temporaryDirectory = null;
+    }
+
+    @Test
+    public void emptyProperties() {
+        Path root = Paths.get("file:/");
+        Versions v = new Versions(root);
+        assertEmpty(v.withVersions(null));
+    }
+
+    @Test
+    public void emptyWithNullProperties() {
+        Path root = Paths.get("file:/");
+        Versions v = new Versions(root);
+        assertEmpty(v.withVersions(null));
+    }
+
+    @Test
+    public void readFromSameDirNullProps() throws IOException {
+        File dir = prepareReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+        Map<Object, Object> map = v.withVersions(null);
+        assertNonModifiable(map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+    }
+
+    @Test
+    public void readFromSameDir() throws IOException {
+        File dir = prepareReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+
+        Map<Object, Object> prepared = new HashMap<>();
+        prepared.put("test", "best");
+
+        Map<Object, Object> map = v.withVersions(prepared);
+        assertSame(prepared, map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+        assertEquals("best", map.get("test"));
+    }
+
+    @Test
+    public void readFromSubDirNullProps() throws IOException {
+        File dir = prepareSubReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+        Map<Object, Object> map = v.withVersions(null);
+        assertNonModifiable(map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+    }
+
+    @Test
+    public void readFromSubDir() throws IOException {
+        File dir = prepareSubReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+
+        Map<Object, Object> prepared = new HashMap<>();
+        prepared.put("test", "best");
+
+        Map<Object, Object> map = v.withVersions(prepared);
+        assertSame(prepared, map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+        assertEquals("best", map.get("test"));
+    }
+
+    private File prepareReleaseFile() throws IOException {
+        if (temporaryDirectory == null) {
+            temporaryDirectory = File.createTempFile("versions", ".tmp");
+            temporaryDirectory.delete();
+            assumeTrue(temporaryDirectory.mkdirs());
+            try (FileWriter w = new FileWriter(new File(temporaryDirectory, "release"))) {
+// @formatter:off
+                w.write(
+"OS_NAME=linux\n" +
+"OS_ARCH=amd64\n" +
+"SOURCE=\" truffle:16055f1ffaf736b7b86dcfaea53971983cd9ae0a sdk:16055f1ffaf736b7b86dcfaea53971983cd9ae0a " +
+"tools-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 graal-js:d374a8fd2733487a9f7518be6a55eb6163a779d1 " +
+"graal-nodejs:3fcaf6874c9059d5ca5f0615edaa405d66cc1b02 truffleruby:7930979c3b0af09a910accaaf3e73b2a55d2bade " +
+"fastr:079c6513b46f36abc24bce8aa6022c90576b3eaf graalpython:4cbee7853d460930c4d693970a21b73f811a4703 " +
+"sulong:2c425f92caa004b12f60428a3e7e6e2715b51f87 substratevm:fcc1292a05e807a63589e24ce6073aafdef45bb9 " +
+"compiler:16055f1ffaf736b7b86dcfaea53971983cd9ae0a substratevm-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 " +
+"vm-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 graal-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 \"\n" +
+"COMMIT_INFO={\"vm-enterprise\":{\"commit.rev\":\"fcc1292a05e807a63589e24ce6073aafdef45bb9\"," +
+"\"commit.committer\":\"Vojin Jovanovic <vojin.jovanovic@oracle.com>\",}}\n" +
+"GRAALVM_VERSION=\"0.29-dev\""
+                );
+// @formatter:on
+            }
+        }
+        return temporaryDirectory;
+    }
+
+    private File prepareSubReleaseFile() throws IOException {
+        File subdir = new File(prepareReleaseFile(), "subdir");
+        assumeTrue(subdir.mkdirs());
+        return subdir;
+    }
+
+    private static void assertEmpty(Map<?, ?> map) {
+        assertNotNull(map);
+        assertTrue(map.isEmpty());
+        assertNonModifiable(map);
+    }
+
+    private static void assertNonModifiable(Map<?, ?> map) {
+        try {
+            map.put(null, null);
+            fail("Map shall not be modifiable: " + map);
+        } catch (UnsupportedOperationException ex) {
+            // ok
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Thu Dec 07 11:54:55 2017 +0000
@@ -130,6 +130,20 @@
     }
 
     /**
+     * Adds version properties to the provided map. The version properties are read at a start of
+     * the JVM from a JVM specific location. Each property identifiers a commit of a certain
+     * component in the system. The properties added to the {@code properties} map are prefixed with
+     * {@code "version."} prefix.
+     *
+     * @param properties map to add the version properties to or {@code null}
+     * @return {@code properties} with version properties added or an unmodifiable map containing
+     *         the version properties if {@code properties == null}
+     */
+    public static Map<Object, Object> addVersionProperties(Map<Object, Object> properties) {
+        return Versions.VERSIONS.withVersions(properties);
+    }
+
+    /**
      * The immutable configuration that can be shared between {@link DebugContext} objects.
      */
     static final class Immutable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Versions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, 2017, 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.graalvm.compiler.debug;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Avoid using directly. Only public for the needs of unit testing. */
+public final class Versions {
+    static final Versions VERSIONS;
+    static {
+        String home = System.getProperty("java.home");
+        VERSIONS = new Versions(home == null ? null : new File(home).toPath());
+    }
+
+    private final Map<Object, Object> versions;
+
+    public Versions(Path home) {
+        Map<Object, Object> map = new HashMap<>();
+        ASSIGN: try {
+            Path info = findReleaseInfo(home);
+            if (info == null) {
+                break ASSIGN;
+            }
+            for (String line : Files.readAllLines(info)) {
+                final String prefix = "SOURCE=";
+                if (line.startsWith(prefix)) {
+                    for (String versionInfo : line.substring(prefix.length()).replace('"', ' ').split(" ")) {
+                        String[] idVersion = versionInfo.split(":");
+                        if (idVersion != null && idVersion.length == 2) {
+                            map.put("version." + idVersion[0], idVersion[1]);
+                        }
+                    }
+                    break ASSIGN;
+                }
+            }
+        } catch (IOException ex) {
+            // no versions file found
+        }
+        versions = Collections.unmodifiableMap(map);
+    }
+
+    public Map<Object, Object> withVersions(Map<Object, Object> properties) {
+        if (properties == null) {
+            return versions;
+        } else {
+            properties.putAll(versions);
+            return properties;
+        }
+    }
+
+    private static Path findReleaseInfo(Path jreDir) {
+        if (jreDir == null) {
+            return null;
+        }
+        Path releaseInJre = jreDir.resolve("release");
+        if (Files.exists(releaseInJre)) {
+            return releaseInJre;
+        }
+        Path jdkDir = jreDir.getParent();
+        if (jdkDir == null) {
+            return null;
+        }
+        Path releaseInJdk = jdkDir.resolve("release");
+        return Files.exists(releaseInJdk) ? releaseInJdk : null;
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotEpilogueOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotEpilogueOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -37,10 +37,18 @@
 abstract class AArch64HotSpotEpilogueOp extends AArch64BlockEndOp {
 
     private final GraalHotSpotVMConfig config;
+    private final Register thread;
+
+    protected AArch64HotSpotEpilogueOp(LIRInstructionClass<? extends AArch64HotSpotEpilogueOp> c, GraalHotSpotVMConfig config, Register thread) {
+        super(c);
+        this.config = config;
+        this.thread = thread;
+    }
 
     protected AArch64HotSpotEpilogueOp(LIRInstructionClass<? extends AArch64HotSpotEpilogueOp> c, GraalHotSpotVMConfig config) {
         super(c);
         this.config = config;
+        this.thread = null; // no safepoint
     }
 
     protected void leaveFrame(CompilationResultBuilder crb, AArch64MacroAssembler masm, boolean emitSafepoint) {
@@ -49,7 +57,7 @@
         if (emitSafepoint) {
             try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
-                AArch64HotSpotSafepointOp.emitCode(crb, masm, config, true, scratch, null);
+                AArch64HotSpotSafepointOp.emitCode(crb, masm, config, true, thread, scratch, null);
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -342,7 +342,8 @@
             operand = resultOperandFor(kind, input.getValueKind());
             emitMove(operand, input);
         }
-        append(new AArch64HotSpotReturnOp(operand, getStub() != null, config));
+        Register thread = getProviders().getRegisters().getThreadRegister();
+        append(new AArch64HotSpotReturnOp(operand, getStub() != null, config, thread));
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.nodes.DirectCallTargetNode;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -110,7 +111,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue.getValueKind() + " != " + param.stamp();
+            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
             setResult(param, gen.emitMove(paramValue));
         }
     }
@@ -118,8 +119,9 @@
     @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
+        Register thread = getGen().getProviders().getRegisters().getThreadRegister();
         Variable scratch = gen.newVariable(LIRKind.value(getGen().target().arch.getWordKind()));
-        append(new AArch64HotSpotSafepointOp(info, getGen().config, scratch));
+        append(new AArch64HotSpotSafepointOp(info, getGen().config, thread, scratch));
     }
 
     @Override
@@ -180,7 +182,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
+            sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotReturnOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotReturnOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
+import jdk.vm.ci.code.Register;
 import jdk.vm.ci.meta.Value;
 
 /**
@@ -46,8 +47,8 @@
     @Use({REG, ILLEGAL}) private Value result;
     private final boolean isStub;
 
-    public AArch64HotSpotReturnOp(Value result, boolean isStub, GraalHotSpotVMConfig config) {
-        super(TYPE, config);
+    public AArch64HotSpotReturnOp(Value result, boolean isStub, GraalHotSpotVMConfig config, Register thread) {
+        super(TYPE, config, thread);
         assert validReturnValue(result);
         this.result = result;
         this.isStub = isStub;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSafepointOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSafepointOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -50,18 +50,20 @@
     @Temp protected AllocatableValue scratchValue;
 
     private final GraalHotSpotVMConfig config;
+    private final Register thread;
 
-    public AArch64HotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, AllocatableValue scratch) {
+    public AArch64HotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, Register thread, AllocatableValue scratch) {
         super(TYPE);
         this.state = state;
         this.config = config;
+        this.thread = thread;
         this.scratchValue = scratch;
     }
 
     @Override
     public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
         Register scratch = asRegister(scratchValue);
-        emitCode(crb, masm, config, false, scratch, state);
+        emitCode(crb, masm, config, false, thread, scratch, state);
     }
 
     /**
@@ -76,7 +78,15 @@
         return !NumUtil.isSignedNbit(21, pollingPageAddress - config.codeCacheLowBound) || !NumUtil.isSignedNbit(21, pollingPageAddress - config.codeCacheHighBound);
     }
 
-    public static void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register scratch, LIRFrameState state) {
+    public static void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register thread, Register scratch, LIRFrameState state) {
+        if (config.threadLocalHandshakes) {
+            emitThreadLocalPoll(crb, masm, config, onReturn, thread, scratch, state);
+        } else {
+            emitGlobalPoll(crb, masm, config, onReturn, scratch, state);
+        }
+    }
+
+    private static void emitGlobalPoll(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register scratch, LIRFrameState state) {
         if (isPollingPageFar(config)) {
             crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
             masm.movNativeAddress(scratch, config.safepointPollingAddress);
@@ -94,4 +104,15 @@
         }
     }
 
+    private static void emitThreadLocalPoll(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register thread, Register scratch,
+                    LIRFrameState state) {
+        assert config.threadPollingPageOffset >= 0;
+        masm.ldr(64, scratch, masm.makeAddress(thread, config.threadPollingPageOffset, 8));
+        crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+        if (state != null) {
+            crb.recordInfopoint(masm.position(), state, InfopointReason.SAFEPOINT);
+        }
+        masm.ldr(32, zr, AArch64Address.createBaseRegisterOnlyAddress(scratch));
+    }
+
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/DataPatchInConstantsTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/DataPatchInConstantsTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
@@ -170,7 +171,7 @@
         @Input protected ValueNode input;
 
         protected LoadThroughPatchNode(ValueNode input) {
-            super(TYPE, input.stamp());
+            super(TYPE, input.stamp(NodeView.DEFAULT));
             this.input = input;
         }
 
@@ -179,9 +180,9 @@
             assert input.isConstant();
 
             LIRGeneratorTool gen = generator.getLIRGeneratorTool();
-            Variable ret = gen.newVariable(gen.getLIRKind(stamp()));
+            Variable ret = gen.newVariable(gen.getLIRKind(stamp(NodeView.DEFAULT)));
 
-            gen.append(new LoadThroughPatchOp(input.asConstant(), stamp() instanceof NarrowOopStamp, ret));
+            gen.append(new LoadThroughPatchOp(input.asConstant(), stamp(NodeView.DEFAULT) instanceof NarrowOopStamp, ret));
             generator.setResult(this, ret);
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Thu Dec 07 11:54:55 2017 +0000
@@ -43,6 +43,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CompressionNode;
 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
@@ -76,7 +77,7 @@
 
         @Override
         public void generate(NodeLIRBuilderTool generator) {
-            LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+            LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
             generator.setResult(this, heapBaseRegister.asValue(kind));
         }
     }
@@ -117,11 +118,6 @@
         return false;
     }
 
-    @Override
-    protected boolean mightBeOptimized(ValueNode value) {
-        return super.mightBeOptimized(value) || value instanceof CompressionNode;
-    }
-
     private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
         if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
             return false;
@@ -134,7 +130,7 @@
         }
 
         if (heapBaseRegister != null && encoding.getBase() == heapBase) {
-            if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
+            if ((!generatePIC || compression.stamp(NodeView.DEFAULT) instanceof ObjectStamp) && other == null) {
                 // With PIC it is only legal to do for oops since the base value may be
                 // different at runtime.
                 ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
@@ -142,7 +138,7 @@
             } else {
                 return false;
             }
-        } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
+        } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp(NodeView.DEFAULT) instanceof KlassPointerStamp)) {
             if (generatePIC) {
                 if (other == null) {
                     ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Dec 07 11:54:55 2017 +0000
@@ -264,7 +264,8 @@
         if (pollOnReturnScratchRegister == null) {
             pollOnReturnScratchRegister = findPollOnReturnScratchRegister();
         }
-        append(new AMD64HotSpotReturnOp(operand, getStub() != null, pollOnReturnScratchRegister, config));
+        Register thread = getProviders().getRegisters().getThreadRegister();
+        append(new AMD64HotSpotReturnOp(operand, getStub() != null, thread, pollOnReturnScratchRegister, config));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -46,6 +46,7 @@
 import org.graalvm.compiler.nodes.DirectCallTargetNode;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -113,7 +114,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue.getValueKind() + " != " + param.stamp();
+            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
             setResult(param, gen.emitMove(paramValue));
         }
     }
@@ -121,7 +122,8 @@
     @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
-        append(new AMD64HotSpotSafepointOp(info, getGen().config, this));
+        Register thread = getGen().getProviders().getRegisters().getThreadRegister();
+        append(new AMD64HotSpotSafepointOp(info, getGen().config, this, thread));
     }
 
     @Override
@@ -186,7 +188,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
+            sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotReturnOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -45,13 +45,15 @@
     public static final LIRInstructionClass<AMD64HotSpotReturnOp> TYPE = LIRInstructionClass.create(AMD64HotSpotReturnOp.class);
     @Use({REG, ILLEGAL}) protected Value value;
     private final boolean isStub;
+    private final Register thread;
     private final Register scratchForSafepointOnReturn;
     private final GraalHotSpotVMConfig config;
 
-    AMD64HotSpotReturnOp(Value value, boolean isStub, Register scratchForSafepointOnReturn, GraalHotSpotVMConfig config) {
+    AMD64HotSpotReturnOp(Value value, boolean isStub, Register thread, Register scratchForSafepointOnReturn, GraalHotSpotVMConfig config) {
         super(TYPE);
         this.value = value;
         this.isStub = isStub;
+        this.thread = thread;
         this.scratchForSafepointOnReturn = scratchForSafepointOnReturn;
         this.config = config;
     }
@@ -61,7 +63,7 @@
         leaveFrameAndRestoreRbp(crb, masm);
         if (!isStub) {
             // Every non-stub compile method must have a poll before the return.
-            AMD64HotSpotSafepointOp.emitCode(crb, masm, config, true, null, scratchForSafepointOnReturn);
+            AMD64HotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, scratchForSafepointOnReturn);
 
             /*
              * We potentially return to the interpreter, and that's an AVX-SSE transition. The only
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSafepointOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSafepointOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -58,12 +58,14 @@
     @Temp({OperandFlag.REG, OperandFlag.ILLEGAL}) private AllocatableValue temp;
 
     private final GraalHotSpotVMConfig config;
+    private final Register thread;
 
-    public AMD64HotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, NodeLIRBuilderTool tool) {
+    public AMD64HotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, NodeLIRBuilderTool tool, Register thread) {
         super(TYPE);
         this.state = state;
         this.config = config;
-        if (isPollingPageFar(config) || ImmutableCode.getValue(tool.getOptions())) {
+        this.thread = thread;
+        if (config.threadLocalHandshakes || isPollingPageFar(config) || ImmutableCode.getValue(tool.getOptions())) {
             temp = tool.getLIRGeneratorTool().newVariable(LIRKind.value(tool.getLIRGeneratorTool().target().arch.getWordKind()));
         } else {
             // Don't waste a register if it's unneeded
@@ -73,7 +75,15 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
-        emitCode(crb, asm, config, false, state, temp instanceof RegisterValue ? ((RegisterValue) temp).getRegister() : null);
+        emitCode(crb, asm, config, false, state, thread, temp instanceof RegisterValue ? ((RegisterValue) temp).getRegister() : null);
+    }
+
+    public static void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread, Register scratch) {
+        if (config.threadLocalHandshakes) {
+            emitThreadLocalPoll(crb, asm, config, atReturn, state, thread, scratch);
+        } else {
+            emitGlobalPoll(crb, asm, config, atReturn, state, scratch);
+        }
     }
 
     /**
@@ -85,7 +95,7 @@
         return config.forceUnreachable || !isInt(pollingPageAddress - config.codeCacheLowBound) || !isInt(pollingPageAddress - config.codeCacheHighBound);
     }
 
-    public static void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
+    private static void emitGlobalPoll(CompilationResultBuilder crb, AMD64MacroAssembler asm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
         assert !atReturn || state == null : "state is unneeded at return";
         if (ImmutableCode.getValue(crb.getOptions())) {
             JavaKind hostWordKind = JavaKind.Long;
@@ -123,4 +133,18 @@
             asm.testl(rax, new AMD64Address(rip, 0));
         }
     }
+
+    private static void emitThreadLocalPoll(CompilationResultBuilder crb, AMD64MacroAssembler asm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread,
+                    Register scratch) {
+        assert !atReturn || state == null : "state is unneeded at return";
+
+        assert config.threadPollingPageOffset >= 0;
+        asm.movptr(scratch, new AMD64Address(thread, config.threadPollingPageOffset));
+        crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+        final int pos = asm.position();
+        if (state != null) {
+            crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+        }
+        asm.testl(rax, new AMD64Address(scratch));
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Thu Dec 07 11:54:55 2017 +0000
@@ -190,7 +190,8 @@
             operand = resultOperandFor(javaKind, input.getValueKind());
             emitMove(operand, input);
         }
-        append(new SPARCHotSpotReturnOp(operand, getStub() != null, config, getSafepointAddressValue()));
+        Register thread = getProviders().getRegisters().getThreadRegister();
+        append(new SPARCHotSpotReturnOp(operand, getStub() != null, config, thread, getSafepointAddressValue()));
     }
 
     @Override
@@ -383,7 +384,7 @@
 
     public AllocatableValue getSafepointAddressValue() {
         if (this.safepointAddressValue == null) {
-            this.safepointAddressValue = newVariable(LIRKind.value(target().arch.getWordKind()));
+            this.safepointAddressValue = SPARCHotSpotSafepointOp.getSafepointAddressValue(this);
         }
         return this.safepointAddressValue;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -46,6 +46,7 @@
 import org.graalvm.compiler.nodes.DirectCallTargetNode;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -84,7 +85,8 @@
     @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
-        append(new SPARCHotSpotSafepointOp(info, getGen().config, gen));
+        Register thread = getGen().getProviders().getRegisters().getThreadRegister();
+        append(new SPARCHotSpotSafepointOp(info, getGen().config, thread, gen));
     }
 
     @Override
@@ -141,9 +143,7 @@
     @Override
     protected void emitPrologue(StructuredGraph graph) {
         super.emitPrologue(graph);
-        AllocatableValue var = getGen().getSafepointAddressValue();
-        append(new SPARCHotSpotSafepointOp.SPARCLoadSafepointPollAddress(var, getGen().config));
-        getGen().append(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack());
+        SPARCHotSpotSafepointOp.emitPrologue(this, getGen());
     }
 
     @Override
@@ -159,7 +159,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
+            sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotReturnOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotReturnOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -24,7 +24,6 @@
 
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
 
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -33,6 +32,7 @@
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 import org.graalvm.compiler.lir.sparc.SPARCControlFlow.ReturnOp;
 
+import jdk.vm.ci.code.Register;
 import jdk.vm.ci.meta.Value;
 
 /**
@@ -44,15 +44,17 @@
     public static final SizeEstimate SIZE = SizeEstimate.create(2);
 
     @Use({REG, ILLEGAL}) protected Value value;
-    @Use({REG}) protected Value safepointPollAddress;
+    @Use({REG, ILLEGAL}) protected Value safepointPollAddress;
     private final boolean isStub;
     private final GraalHotSpotVMConfig config;
+    private final Register thread;
 
-    SPARCHotSpotReturnOp(Value value, boolean isStub, GraalHotSpotVMConfig config, Value safepointPoll) {
+    SPARCHotSpotReturnOp(Value value, boolean isStub, GraalHotSpotVMConfig config, Register thread, Value safepointPoll) {
         super(TYPE, SIZE);
         this.value = value;
         this.isStub = isStub;
         this.config = config;
+        this.thread = thread;
         this.safepointPollAddress = safepointPoll;
     }
 
@@ -60,7 +62,7 @@
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         if (!isStub) {
             // Every non-stub compile method must have a poll before the return.
-            SPARCHotSpotSafepointOp.emitCode(crb, masm, config, true, null, asRegister(safepointPollAddress));
+            SPARCHotSpotSafepointOp.emitCode(crb, masm, config, true, null, thread, safepointPollAddress);
         }
         ReturnOp.emitCodeHelper(crb, masm);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotSafepointOp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotSafepointOp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -27,7 +27,10 @@
 
 import org.graalvm.compiler.asm.sparc.SPARCAddress;
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
+import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
+import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder;
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
@@ -39,6 +42,7 @@
 import jdk.vm.ci.code.ValueUtil;
 import jdk.vm.ci.code.site.InfopointReason;
 import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
 
 /**
  * Emits a safepoint poll.
@@ -49,23 +53,37 @@
     public static final SizeEstimate SIZE = SizeEstimate.create(9);
 
     @State protected LIRFrameState state;
-    @Use({OperandFlag.REG}) AllocatableValue safepointPollAddress;
+    @Use({OperandFlag.REG, OperandFlag.ILLEGAL}) AllocatableValue safepointPollAddress;
     private final GraalHotSpotVMConfig config;
+    private final Register thread;
 
-    public SPARCHotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, LIRGeneratorTool tool) {
+    public SPARCHotSpotSafepointOp(LIRFrameState state, GraalHotSpotVMConfig config, Register thread, LIRGeneratorTool tool) {
         super(TYPE, SIZE);
         this.state = state;
         this.config = config;
+        this.thread = thread;
         SPARCHotSpotLIRGenerator lirGen = (SPARCHotSpotLIRGenerator) tool;
         safepointPollAddress = lirGen.getSafepointAddressValue();
     }
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        emitCode(crb, masm, config, false, state, asRegister(safepointPollAddress));
+        emitCode(crb, masm, config, false, state, thread, safepointPollAddress);
     }
 
-    public static void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register safepointPollAddress) {
+    public static void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread,
+                    Value safepointPollAddress) {
+        if (config.threadLocalHandshakes) {
+            emitThreadLocalPoll(crb, masm, config, atReturn, state, thread);
+        } else {
+            emitGlobalPoll(crb, masm, config, atReturn, state, asRegister(safepointPollAddress));
+        }
+    }
+
+    /**
+     * Emit a global safepoint poll.
+     */
+    private static void emitGlobalPoll(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register safepointPollAddress) {
         crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
         if (state != null) {
             final int pos = masm.position();
@@ -74,6 +92,44 @@
         masm.ldx(new SPARCAddress(safepointPollAddress, 0), g0);
     }
 
+    /**
+     * Emit a thread-local safepoint poll.
+     */
+    private static void emitThreadLocalPoll(CompilationResultBuilder crb, SPARCMacroAssembler masm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread) {
+        assert !atReturn || state == null : "state is unneeded at return";
+
+        assert config.threadPollingPageOffset >= 0;
+
+        try (ScratchRegister scratchReg = masm.getScratchRegister()) {
+            Register scratch = scratchReg.getRegister();
+
+            masm.ldx(new SPARCAddress(thread, config.threadPollingPageOffset), scratch);
+
+            crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+            if (state != null) {
+                final int pos = masm.position();
+                crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+            }
+            masm.ldx(new SPARCAddress(scratch, 0), g0);
+        }
+    }
+
+    static AllocatableValue getSafepointAddressValue(SPARCHotSpotLIRGenerator gen) {
+        if (gen.config.threadLocalHandshakes) {
+            return Value.ILLEGAL;
+        } else {
+            return gen.newVariable(LIRKind.value(gen.target().arch.getWordKind()));
+        }
+    }
+
+    static void emitPrologue(SPARCHotSpotNodeLIRBuilder lir, SPARCHotSpotLIRGenerator gen) {
+        if (!gen.config.threadLocalHandshakes) {
+            AllocatableValue var = gen.getSafepointAddressValue();
+            lir.append(new SPARCHotSpotSafepointOp.SPARCLoadSafepointPollAddress(var, gen.config));
+            gen.append(((HotSpotDebugInfoBuilder) lir.getDebugInfoBuilder()).lockStack());
+        }
+    }
+
     public static class SPARCLoadSafepointPollAddress extends SPARCLIRInstruction {
         public static final LIRInstructionClass<SPARCLoadSafepointPollAddress> TYPE = LIRInstructionClass.create(SPARCLoadSafepointPollAddress.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(2);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -22,14 +22,15 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
-import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
-
+import jdk.vm.ci.aarch64.AArch64;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.type.Stamp;
-import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@@ -41,10 +42,8 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import jdk.vm.ci.aarch64.AArch64;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
+import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
+import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
 
 /**
  * use
@@ -55,7 +54,7 @@
  *
  * to print disassembly.
  */
-public class AheadOfTimeCompilationTest extends GraalCompilerTest {
+public class AheadOfTimeCompilationTest extends HotSpotGraalCompilerTest {
 
     public static final Object STATICFINALOBJECT = new Object();
     public static final String STATICFINALSTRING = "test string";
@@ -74,9 +73,10 @@
     public void testStaticFinalObjectAOT() {
         StructuredGraph result = compile("getStaticFinalObject", true);
         assertDeepEquals(1, getConstantNodes(result).count());
-        Stamp constantStamp = getConstantNodes(result).first().stamp();
+        Stamp constantStamp = getConstantNodes(result).first().stamp(NodeView.DEFAULT);
         Assert.assertTrue(constantStamp.toString(), constantStamp instanceof KlassPointerStamp);
-        assertDeepEquals(2, result.getNodes().filter(ReadNode.class).count());
+        int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
+        assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
     }
 
     @Test
@@ -99,8 +99,8 @@
         assertDeepEquals(1, filter.count());
         HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class);
         assertDeepEquals(type.klass(), filter.first().asConstant());
-
-        assertDeepEquals(1, result.getNodes().filter(ReadNode.class).count());
+        int expected = runtime().getVMConfig().classMirrorIsHandle ? 2 : 1;
+        assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
     }
 
     @Test
@@ -124,10 +124,10 @@
         StructuredGraph result = compile("getPrimitiveClassObject", true);
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertDeepEquals(1, filter.count());
-        Stamp constantStamp = filter.first().stamp();
+        Stamp constantStamp = filter.first().stamp(NodeView.DEFAULT);
         Assert.assertTrue(constantStamp instanceof KlassPointerStamp);
-
-        assertDeepEquals(2, result.getNodes().filter(ReadNode.class).count());
+        int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
+        assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Thu Dec 07 11:54:55 2017 +0000
@@ -143,50 +143,49 @@
     }
 
     static {
+        // These are dead
         add(IGNORE,
-                        // dead
                         "java/lang/Math.atan2(DD)D",
-                        // Used during stack walking
-                        "java/lang/Throwable.fillInStackTrace()Ljava/lang/Throwable;",
-                        // Marker intrinsic id
-                        "java/lang/invoke/MethodHandle.<compiledLambdaForm>*",
-                        // Marker intrinsic id
-                        "java/lang/invoke/MethodHandle.invoke*",
-                        // Implemented through lowering
-                        "java/lang/ref/Reference.get()Ljava/lang/Object;",
-                        // Used during stack walk
-                        "java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;",
-                        // Only used by C1
-                        "java/nio/Buffer.checkIndex(I)I",
-                        // dead
+                        "jdk/internal/misc/Unsafe.park(ZJ)V",
+                        "jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
                         "sun/misc/Unsafe.park(ZJ)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchRead(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchReadStatic(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchWrite(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchWriteStatic(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.unpark(Ljava/lang/Object;)V");
 
-        add(TO_BE_INVESTIGATED,
-                        // JDK 8
-                        "java/lang/Double.doubleToLongBits(D)J",
-                        "java/lang/Float.floatToIntBits(F)I",
+        // These only exist to assist escape analysis in C2
+        add(IGNORE,
+                        "java/lang/Throwable.fillInStackTrace()Ljava/lang/Throwable;");
+
+        // These are only used for the security handling during stack walking
+        add(IGNORE,
+                        "java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
+
+        // These are marker intrinsic ids only
+        add(IGNORE,
+                        "java/lang/invoke/MethodHandle.<compiledLambdaForm>*",
+                        "java/lang/invoke/MethodHandle.invoke*");
+
+        // These are implemented through lowering
+        add(IGNORE,
+                        "java/lang/ref/Reference.get()Ljava/lang/Object;");
+
+        // These are only used by C1
+        add(IGNORE,
+                        "java/nio/Buffer.checkIndex(I)I");
+
+        // These do general compiler optimizations and convert min/max to cmov instructions. We are
+        // ignoring them as cmovs are not necessarily beneficial.
+        add(IGNORE,
+                        "java/lang/Math.max(II)I",
+                        "java/lang/Math.min(II)I");
+
+        // These are known to be implemented down stream
+        add(IGNORE,
                         "java/lang/Integer.toString(I)Ljava/lang/String;",
-                        "java/lang/Math.decrementExact(I)I",
-                        "java/lang/Math.decrementExact(J)J",
-                        "java/lang/Math.incrementExact(I)I",
-                        "java/lang/Math.incrementExact(J)J",
-                        "java/lang/Math.max(II)I",
-                        "java/lang/Math.min(II)I",
-                        "java/lang/Math.negateExact(I)I",
-                        "java/lang/Math.negateExact(J)J",
                         "java/lang/String.<init>(Ljava/lang/String;)V",
-                        "java/lang/String.compareTo(Ljava/lang/String;)I",
-                        "java/lang/String.indexOf(Ljava/lang/String;)I",
                         "java/lang/StringBuffer.<init>()V",
                         "java/lang/StringBuffer.<init>(I)V",
                         "java/lang/StringBuffer.<init>(Ljava/lang/String;)V",
@@ -201,172 +200,11 @@
                         "java/lang/StringBuilder.append(I)Ljava/lang/StringBuilder;",
                         "java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
                         "java/lang/StringBuilder.toString()Ljava/lang/String;",
-                        "java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
                         "java/util/Arrays.copyOf([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;",
-                        "java/util/Arrays.copyOfRange([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;",
-                        "oracle/jrockit/jfr/Timing.counterTime()J",
-                        "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
-                        "oracle/jrockit/jfr/VMJFR.threadID()I",
-                        "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
-                        "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I",
-                        "sun/security/provider/SHA.implCompress([BI)V",
-                        "sun/security/provider/SHA2.implCompress([BI)V",
-                        "sun/security/provider/SHA5.implCompress([BI)V");
+                        "java/util/Arrays.copyOfRange([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;");
 
-        add(TO_BE_INVESTIGATED,
-                        // JDK 9
-                        "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
-                        "com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
-                        "java/lang/Math.fma(DDD)D",
-                        "java/lang/Math.fma(FFF)F",
-                        "java/lang/Object.notify()V",
-                        "java/lang/Object.notifyAll()V",
-                        "java/lang/StringCoding.hasNegatives([BII)Z",
-                        "java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
-                        "java/lang/StringLatin1.compareTo([B[B)I",
-                        "java/lang/StringLatin1.compareToUTF16([B[B)I",
-                        "java/lang/StringLatin1.equals([B[B)Z",
-                        "java/lang/StringLatin1.indexOf([BI[BII)I",
-                        "java/lang/StringLatin1.indexOf([B[B)I",
-                        "java/lang/StringLatin1.inflate([BI[BII)V",
-                        "java/lang/StringLatin1.inflate([BI[CII)V",
-                        "java/lang/StringUTF16.compareTo([B[B)I",
-                        "java/lang/StringUTF16.compareToLatin1([B[B)I",
-                        "java/lang/StringUTF16.compress([BI[BII)I",
-                        "java/lang/StringUTF16.compress([CI[BII)I",
-                        "java/lang/StringUTF16.equals([B[B)Z",
-                        "java/lang/StringUTF16.getChar([BI)C",
-                        "java/lang/StringUTF16.getChars([BII[CI)V",
-                        "java/lang/StringUTF16.indexOf([BI[BII)I",
-                        "java/lang/StringUTF16.indexOf([B[B)I",
-                        "java/lang/StringUTF16.indexOfChar([BIII)I",
-                        "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
-                        "java/lang/StringUTF16.indexOfLatin1([B[B)I",
-                        "java/lang/StringUTF16.putChar([BII)V",
-                        "java/lang/StringUTF16.toBytes([CII)[B",
-                        "java/lang/Thread.onSpinWait()V",
-                        "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
-                        "java/math/BigInteger.implMontgomeryMultiply([I[I[IIJ[I)[I",
-                        "java/math/BigInteger.implMontgomerySquare([I[IIJ[I)[I",
-                        "java/math/BigInteger.implMulAdd([I[IIII)I",
-                        "java/math/BigInteger.implSquareToLen([II[II)[I",
-                        "java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
-                        "java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
-                        "java/util/zip/Adler32.updateByteBuffer(IJII)I",
-                        "java/util/zip/Adler32.updateBytes(I[BII)I",
-                        "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
-                        "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
-                        "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
-                        "jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
-                        "jdk/internal/misc/Unsafe.getBooleanAcquire(Ljava/lang/Object;J)Z",
-                        "jdk/internal/misc/Unsafe.getBooleanOpaque(Ljava/lang/Object;J)Z",
-                        "jdk/internal/misc/Unsafe.getByteAcquire(Ljava/lang/Object;J)B",
-                        "jdk/internal/misc/Unsafe.getByteOpaque(Ljava/lang/Object;J)B",
-                        "jdk/internal/misc/Unsafe.getCharAcquire(Ljava/lang/Object;J)C",
-                        "jdk/internal/misc/Unsafe.getCharOpaque(Ljava/lang/Object;J)C",
-                        "jdk/internal/misc/Unsafe.getDoubleAcquire(Ljava/lang/Object;J)D",
-                        "jdk/internal/misc/Unsafe.getDoubleOpaque(Ljava/lang/Object;J)D",
-                        "jdk/internal/misc/Unsafe.getFloatAcquire(Ljava/lang/Object;J)F",
-                        "jdk/internal/misc/Unsafe.getFloatOpaque(Ljava/lang/Object;J)F",
-                        "jdk/internal/misc/Unsafe.getIntAcquire(Ljava/lang/Object;J)I",
-                        "jdk/internal/misc/Unsafe.getIntOpaque(Ljava/lang/Object;J)I",
-                        "jdk/internal/misc/Unsafe.getLongAcquire(Ljava/lang/Object;J)J",
-                        "jdk/internal/misc/Unsafe.getLongOpaque(Ljava/lang/Object;J)J",
-                        "jdk/internal/misc/Unsafe.getObjectAcquire(Ljava/lang/Object;J)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.getObjectOpaque(Ljava/lang/Object;J)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.getShortAcquire(Ljava/lang/Object;J)S",
-                        "jdk/internal/misc/Unsafe.getShortOpaque(Ljava/lang/Object;J)S",
-                        "jdk/internal/misc/Unsafe.park(ZJ)V",
-                        "jdk/internal/misc/Unsafe.putBooleanOpaque(Ljava/lang/Object;JZ)V",
-                        "jdk/internal/misc/Unsafe.putByteOpaque(Ljava/lang/Object;JB)V",
-                        "jdk/internal/misc/Unsafe.putCharOpaque(Ljava/lang/Object;JC)V",
-                        "jdk/internal/misc/Unsafe.putDoubleOpaque(Ljava/lang/Object;JD)V",
-                        "jdk/internal/misc/Unsafe.putFloatOpaque(Ljava/lang/Object;JF)V",
-                        "jdk/internal/misc/Unsafe.putIntOpaque(Ljava/lang/Object;JI)V",
-                        "jdk/internal/misc/Unsafe.putLongOpaque(Ljava/lang/Object;JJ)V",
-                        "jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
-                        "jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
-                        "jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
-                        "jdk/jfr/internal/JVM.counterTime()J",
-                        "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
-                        "jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J",
-                        "sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
-                        "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I",
-                        "sun/security/provider/SHA.implCompress0([BI)V",
-                        "sun/security/provider/SHA2.implCompress0([BI)V",
-                        "sun/security/provider/SHA5.implCompress0([BI)V");
-
-        if (!getHostArchitectureName().equals("amd64")) {
-            add(TO_BE_INVESTIGATED,
-                            // Can we implement these on non-AMD64 platforms? C2 seems to.
-                            "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
-                            "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
-                            "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
-                            "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
-                            "sun/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
-            // JDK 9
-            add(TO_BE_INVESTIGATED,
-                            "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
-                            "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
-                            "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
-                            "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
-                            "jdk/internal/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;",
-                            "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
-                            "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
-                            "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
-                            "jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
-                            "jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
-                            "jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
-                            "jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
-                            "jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
-        }
-
-        HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
-        GraalHotSpotVMConfig config = rt.getVMConfig();
-
-        /*
-         * These are known to be implemented but the platform dependent conditions for when they are
-         * enabled are complex so just ignore them all the time.
-         */
+        // These are known to be implemented but the platform dependent conditions
+        // for when they are enabled are complex so just ignore them all the time.
         add(IGNORE,
                         "java/lang/Integer.bitCount(I)I",
                         "java/lang/Integer.numberOfLeadingZeros(I)I",
@@ -375,52 +213,323 @@
                         "java/lang/Long.numberOfLeadingZeros(J)I",
                         "java/lang/Long.numberOfTrailingZeros(J)I");
 
+        // Relevant for Java flight recorder
+        add(TO_BE_INVESTIGATED,
+                        "oracle/jrockit/jfr/Timing.counterTime()J",
+                        "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
+                        "oracle/jrockit/jfr/VMJFR.threadID()I");
+
+        add(TO_BE_INVESTIGATED,
+                        // Should be fairly easy to implement - C2 intrinsifies these to use "v !=
+                        // v" to check for NaN instead of looking at the bit pattern.
+                        "java/lang/Double.doubleToLongBits(D)J",
+                        "java/lang/Float.floatToIntBits(F)I",
+
+                        // Should be trivial to implement because we already have existing nodes
+                        "java/lang/Math.decrementExact(I)I",
+                        "java/lang/Math.decrementExact(J)J",
+                        "java/lang/Math.incrementExact(I)I",
+                        "java/lang/Math.incrementExact(J)J",
+
+                        // Similar to addExact
+                        "java/lang/Math.negateExact(I)I",
+                        // Similar to addExact
+                        "java/lang/Math.negateExact(J)J",
+                        // HotSpot MacroAssembler-based intrinsic
+                        "java/lang/String.compareTo(Ljava/lang/String;)I",
+                        // HotSpot MacroAssembler-based intrinsic
+                        "java/lang/String.indexOf(Ljava/lang/String;)I",
+                        // Can share most implementation parts with with
+                        // Unsafe.allocateUninitializedArray0
+                        "java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
+                        // HotSpot MacroAssembler-based intrinsic
+                        "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
+                        // Stub based intrinsics but implementation seems complex in C2
+                        "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I");
+
+        if (isJDK9OrHigher()) {
+            // Relevant for Java flight recorder
+            add(TO_BE_INVESTIGATED,
+                            "jdk/jfr/internal/JVM.counterTime()J",
+                            "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
+                            "jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J");
+
+            add(TO_BE_INVESTIGATED,
+                            // Some logic and a stub call
+                            "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
+                            // Stub and very little logic
+                            "com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
+                            // HotSpot MacroAssembler-based intrinsic
+                            "java/lang/Math.fma(DDD)D",
+                            // HotSpot MacroAssembler-based intrinsic
+                            "java/lang/Math.fma(FFF)F",
+                            // Just a runtime call (the called C code has a better fast path)
+                            "java/lang/Object.notify()V",
+                            // Just a runtime call (the called C code has a better fast path)
+                            "java/lang/Object.notifyAll()V",
+                            // Emit pause instruction if os::is_MP()
+                            "java/lang/Thread.onSpinWait()V",
+                            // Just check if the argument is a compile time constant
+                            "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
+                            // Some logic and a runtime call
+                            "java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
+                            // Only used as a marker for vectorization?
+                            "java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
+                            // Only implemented on non-AMD64 platforms (some logic and runtime call)
+                            "java/util/zip/Adler32.updateByteBuffer(IJII)I",
+                            // Only implemented on non-AMD64 platforms (some logic and runtime call)
+                            "java/util/zip/Adler32.updateBytes(I[BII)I",
+                            // similar to CRC32.updateBytes
+                            "java/util/zip/CRC32C.updateBytes(I[BII)I",
+                            // similar to CRC32.updateDirectByteBuffer
+                            "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I",
+                            // Emits a slow and a fast path and some dispatching logic
+                            "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
+
+                            // Should be easy to implement as it seems to match the logic that is
+                            // already implemented in ValueCompareAndSwapNode. On the high-level, we
+                            // would need something similar to UnsafeCompareAndSwapNode but with a
+                            // different result type.
+                            "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
+
+                            // Should be easy to implement as we already have an implementation for
+                            // int, long, and Object.
+                            "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
+
+                            // Should be easy to implement as we already have an implementation for
+                            // int and long.
+                            "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
+                            "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
+
+                            // Should be easy to implement as we already have an implementation for
+                            // int, long, and Object.
+                            "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
+                            "jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
+
+                            // Control flow, deopts, and a cast
+                            "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
+                            // HotSpot MacroAssembler-based intrinsic
+                            "sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
+                            // Runtime call and some complex compiler logic
+                            "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
+            /*
+             * Per default, all these operations are mapped to some generic method for which we
+             * already have compiler intrinsics. Performance-wise it would be better to support them
+             * explicitly as the more generic method might be more restrictive and therefore slower
+             * than necessary.
+             */
+            add(TO_BE_INVESTIGATED,
+                            // Mapped to compareAndExchange*
+                            "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
+
+                            // Mapped to get*Volatile
+                            "jdk/internal/misc/Unsafe.getBooleanAcquire(Ljava/lang/Object;J)Z",
+                            "jdk/internal/misc/Unsafe.getBooleanOpaque(Ljava/lang/Object;J)Z",
+                            "jdk/internal/misc/Unsafe.getByteAcquire(Ljava/lang/Object;J)B",
+                            "jdk/internal/misc/Unsafe.getByteOpaque(Ljava/lang/Object;J)B",
+                            "jdk/internal/misc/Unsafe.getCharAcquire(Ljava/lang/Object;J)C",
+                            "jdk/internal/misc/Unsafe.getCharOpaque(Ljava/lang/Object;J)C",
+                            "jdk/internal/misc/Unsafe.getDoubleAcquire(Ljava/lang/Object;J)D",
+                            "jdk/internal/misc/Unsafe.getDoubleOpaque(Ljava/lang/Object;J)D",
+                            "jdk/internal/misc/Unsafe.getFloatAcquire(Ljava/lang/Object;J)F",
+                            "jdk/internal/misc/Unsafe.getFloatOpaque(Ljava/lang/Object;J)F",
+                            "jdk/internal/misc/Unsafe.getIntAcquire(Ljava/lang/Object;J)I",
+                            "jdk/internal/misc/Unsafe.getIntOpaque(Ljava/lang/Object;J)I",
+                            "jdk/internal/misc/Unsafe.getLongAcquire(Ljava/lang/Object;J)J",
+                            "jdk/internal/misc/Unsafe.getLongOpaque(Ljava/lang/Object;J)J",
+                            "jdk/internal/misc/Unsafe.getObjectAcquire(Ljava/lang/Object;J)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.getObjectOpaque(Ljava/lang/Object;J)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.getShortAcquire(Ljava/lang/Object;J)S",
+                            "jdk/internal/misc/Unsafe.getShortOpaque(Ljava/lang/Object;J)S",
+
+                            // Mapped to put*Volatile
+                            "jdk/internal/misc/Unsafe.putBooleanOpaque(Ljava/lang/Object;JZ)V",
+                            "jdk/internal/misc/Unsafe.putByteOpaque(Ljava/lang/Object;JB)V",
+                            "jdk/internal/misc/Unsafe.putCharOpaque(Ljava/lang/Object;JC)V",
+                            "jdk/internal/misc/Unsafe.putDoubleOpaque(Ljava/lang/Object;JD)V",
+                            "jdk/internal/misc/Unsafe.putFloatOpaque(Ljava/lang/Object;JF)V",
+                            "jdk/internal/misc/Unsafe.putIntOpaque(Ljava/lang/Object;JI)V",
+                            "jdk/internal/misc/Unsafe.putLongOpaque(Ljava/lang/Object;JJ)V",
+                            "jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
+                            "jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
+
+                            // Mapped to compareAndSet*
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z");
+
+            // Compact string support - HotSpot MacroAssembler-based intrinsic or complex C2 logic.
+            add(TO_BE_INVESTIGATED,
+                            "java/lang/StringCoding.hasNegatives([BII)Z",
+                            "java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
+                            "java/lang/StringLatin1.compareTo([B[B)I",
+                            "java/lang/StringLatin1.compareToUTF16([B[B)I",
+                            "java/lang/StringLatin1.equals([B[B)Z",
+                            "java/lang/StringLatin1.indexOf([BI[BII)I",
+                            "java/lang/StringLatin1.indexOf([B[B)I",
+                            "java/lang/StringLatin1.inflate([BI[BII)V",
+                            "java/lang/StringLatin1.inflate([BI[CII)V",
+                            "java/lang/StringUTF16.compareTo([B[B)I",
+                            "java/lang/StringUTF16.compareToLatin1([B[B)I",
+                            "java/lang/StringUTF16.compress([BI[BII)I",
+                            "java/lang/StringUTF16.compress([CI[BII)I",
+                            "java/lang/StringUTF16.equals([B[B)Z",
+                            "java/lang/StringUTF16.getChar([BI)C",
+                            "java/lang/StringUTF16.getChars([BII[CI)V",
+                            "java/lang/StringUTF16.indexOf([BI[BII)I",
+                            "java/lang/StringUTF16.indexOf([B[B)I",
+                            "java/lang/StringUTF16.indexOfChar([BIII)I",
+                            "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
+                            "java/lang/StringUTF16.indexOfLatin1([B[B)I",
+                            "java/lang/StringUTF16.putChar([BII)V",
+                            "java/lang/StringUTF16.toBytes([CII)[B");
+        }
+
+        if (!getHostArchitectureName().equals("amd64")) {
+            // Can we implement these on non-AMD64 platforms? C2 seems to.
+            add(TO_BE_INVESTIGATED,
+                            "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
+                            "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
+                            "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
+                            "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
+                            "sun/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
+
+            if (isJDK9OrHigher()) {
+                add(TO_BE_INVESTIGATED,
+                                "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
+                                "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
+                                "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
+                                "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
+                                "jdk/internal/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;",
+                                "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
+                                "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
+                                "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
+                                "jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
+                                "jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
+                                "jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
+                                "jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
+                                "jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
+            }
+        }
+
+        HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
+        GraalHotSpotVMConfig config = rt.getVMConfig();
+
+        /*
+         * The intrinsics down here are known to be implemented but they are not always enabled on
+         * the HotSpot side (e.g., because they require certain CPU features). So, we are ignoring
+         * them if the HotSpot config tells us that they can't be used.
+         */
+
+        // CRC32 intrinsics
         if (!config.useCRC32Intrinsics) {
-            // Registration of the CRC32 plugins is guarded by UseCRC32Intrinsics
             add(IGNORE, "java/util/zip/CRC32.update(II)I");
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE,
+                                "java/util/zip/CRC32.updateByteBuffer0(IJII)I",
+                                "java/util/zip/CRC32.updateBytes0(I[BII)I");
+            } else {
                 add(IGNORE,
                                 "java/util/zip/CRC32.updateByteBuffer(IJII)I",
                                 "java/util/zip/CRC32.updateBytes(I[BII)I");
-            } else {
-                add(IGNORE,
-                                "java/util/zip/CRC32.updateByteBuffer0(IJII)I",
-                                "java/util/zip/CRC32.updateBytes0(I[BII)I",
-                                "java/util/zip/CRC32C.updateBytes(I[BII)I",
-                                "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
-            }
-        } else {
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9) {
-                add(TO_BE_INVESTIGATED,
-                                "java/util/zip/CRC32C.updateBytes(I[BII)I",
-                                "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
             }
         }
 
+        // AES intrinsics
         if (!config.useAESIntrinsics) {
-            // Registration of the AES plugins is guarded by UseAESIntrinsics
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE,
+                                "com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V",
+                                "com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V",
+                                "com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I",
+                                "com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I");
+            } else {
                 add(IGNORE,
                                 "com/sun/crypto/provider/AESCrypt.decryptBlock([BI[BI)V",
                                 "com/sun/crypto/provider/AESCrypt.encryptBlock([BI[BI)V",
                                 "com/sun/crypto/provider/CipherBlockChaining.decrypt([BII[BI)I",
                                 "com/sun/crypto/provider/CipherBlockChaining.encrypt([BII[BI)I");
+            }
+        }
+
+        // BigInteger intrinsics
+        if (!config.useMultiplyToLenIntrinsic()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
             } else {
-                add(IGNORE,
-                                "com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V",
-                                "com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V",
-                                "com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I",
-                                "com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I");
+                add(IGNORE, "java/math/BigInteger.multiplyToLen([II[II[I)[I");
             }
         }
-        if (!config.useMultiplyToLenIntrinsic()) {
-            // Registration of the AES plugins is guarded by UseAESIntrinsics
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
-                add(IGNORE, "java/math/BigInteger.multiplyToLen([II[II[I)[I");
+        if (!config.useMulAddIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implMulAdd([I[IIII)I");
+        }
+        if (!config.useMontgomeryMultiplyIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implMontgomeryMultiply([I[I[IIJ[I)[I");
+        }
+        if (!config.useMontgomerySquareIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implMontgomerySquare([I[IIJ[I)[I");
+        }
+        if (!config.useSquareToLenIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implSquareToLen([II[II)[I");
+        }
+
+        // SHA intrinsics
+        if (!config.useSHA1Intrinsics()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "sun/security/provider/SHA.implCompress0([BI)V");
             } else {
-                add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
+                add(IGNORE, "sun/security/provider/SHA.implCompress([BI)V");
             }
         }
+        if (!config.useSHA256Intrinsics()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "sun/security/provider/SHA2.implCompress0([BI)V");
+            } else {
+                add(IGNORE, "sun/security/provider/SHA2.implCompress([BI)V");
+            }
+        }
+        if (!config.useSHA512Intrinsics()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "sun/security/provider/SHA5.implCompress0([BI)V");
+            } else {
+                add(IGNORE, "sun/security/provider/SHA5.implCompress([BI)V");
+            }
+        }
+    }
+
+    private static boolean isJDK9OrHigher() {
+        return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
     }
 
     private static String getHostArchitectureName() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -106,7 +106,12 @@
         final int maxProblems = 4;
         Probe[] probes = {
                         new Probe("To capture more information for diagnosing or reporting a compilation", maxProblems),
-                        new Probe("Retrying compilation of", maxProblems),
+                        new Probe("Retrying compilation of", maxProblems) {
+                            @Override
+                            String test() {
+                                return actualOccurrences > 0 && actualOccurrences <= maxProblems ? null : String.format("expected occurrences to be in [1 .. %d]", maxProblems);
+                            }
+                        },
                         new Probe("adjusting CompilationFailureAction from Diagnose to Print", 1),
                         new Probe("adjusting CompilationFailureAction from Print to Silent", 1),
         };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017, 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.graalvm.compiler.hotspot.test;
+
+import java.util.function.Function;
+
+import org.graalvm.compiler.test.GraalTest;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.code.stack.InspectedFrame;
+import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Create a single object which is referenced from a local, the expression stack and the lock state
+ * and then ensure that identity is maintained when the frame is forced to be materialized by
+ * {@link InspectedFrame#materializeVirtualObjects(boolean)}.
+ */
+public class HotSpotStackIntrospectionTest extends HotSpotGraalCompilerTest {
+
+    static StackIntrospection stackIntrospection = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getStackIntrospection();
+    static volatile int v;
+
+    public static void testSynchronizedSnippet(Function<Void, Void> f) {
+        Object a = new Object();
+        synchronized (a) {
+            testOnStack(a, forceFrameState(a, f), a);
+            // This object should be locked so try to notify on it
+            a.notify();
+        }
+    }
+
+    public static void testSnippet(Function<Void, Void> f) {
+        Object a = new Object();
+        testOnStack(a, forceFrameState(a, f), a);
+    }
+
+    private static void testOnStack(Object a, Object a2, Object a3) {
+        if (a != a2 || a != a3) {
+            throw new InternalError();
+        }
+    }
+
+    private static Object forceFrameState(Object a, Function<Void, Void> f) {
+        // Use a volatile store to ensure a FrameState is captured after this point.
+        v++;
+        f.apply(null);
+        return a;
+    }
+
+    @Test(timeout = 20000)
+    public void run() throws InvalidInstalledCodeException {
+        // The JDK9 bits are currently broken
+        Assume.assumeTrue(GraalTest.Java8OrEarlier);
+        test("testSnippet");
+    }
+
+    @Test(timeout = 20000)
+    public void runSynchronized() throws InvalidInstalledCodeException {
+        // The JDK9 bits are currently broken
+        Assume.assumeTrue(GraalTest.Java8OrEarlier);
+        test("testSynchronizedSnippet");
+    }
+
+    private void test(String name) throws InvalidInstalledCodeException {
+        ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(name));
+        Function<Void, Void> f = o -> {
+            stackIntrospection.iterateFrames(null, null, 0, frame -> {
+                if (frame.getMethod().equals(method)) {
+                    frame.materializeVirtualObjects(true);
+                }
+                return null;
+            });
+            return null;
+        };
+        InstalledCode code = getCode(method);
+        code.executeVarargs(f);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
+import org.graalvm.compiler.hotspot.meta.HotSpotUnsafeSubstitutions;
 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
 import org.junit.Test;
 
@@ -56,7 +57,7 @@
 
     @Test
     public void testUnsafeSubstitutions() throws Exception {
-        testGraph("unsafeCopyMemory");
+        testGraph("unsafeCopyMemory", HotSpotUnsafeSubstitutions.copyMemoryName);
     }
 
     public void unsafeCopyMemory(Object srcBase, long srcOffset, Object dstBase, long dstOffset, long bytes) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -165,6 +165,7 @@
     public final boolean usePopCountInstruction = getFlag("UsePopCountInstruction", Boolean.class);
     public final boolean useAESIntrinsics = getFlag("UseAESIntrinsics", Boolean.class);
     public final boolean useCRC32Intrinsics = getFlag("UseCRC32Intrinsics", Boolean.class);
+    public final boolean threadLocalHandshakes = getFlag("ThreadLocalHandshakes", Boolean.class, false);
 
     private final boolean useMultiplyToLenIntrinsic = getFlag("UseMultiplyToLenIntrinsic", Boolean.class);
     private final boolean useSHA1Intrinsics = getFlag("UseSHA1Intrinsics", Boolean.class);
@@ -594,6 +595,7 @@
     public final int basicLockSize = getFieldValue("CompilerToVM::Data::sizeof_BasicLock", Integer.class, "int");
     public final int basicLockDisplacedHeaderOffset = getFieldOffset("BasicLock::_displaced_header", Integer.class, "markOop");
 
+    public final int threadPollingPageOffset = getFieldOffset("Thread::_polling_page", Integer.class, "address", -1);
     public final int threadAllocatedBytesOffset = getFieldOffset("Thread::_allocated_bytes", Integer.class, "jlong");
 
     public final int tlabRefillWasteIncrement = getFlag("TLABWasteIncrement", Integer.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Dec 07 11:54:55 2017 +0000
@@ -103,6 +103,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoweredCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StartNode;
@@ -254,7 +255,7 @@
                 instanceofSnippets.lower(instanceOfDynamicNode, tool);
             } else {
                 ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub();
-                if (mirror.stamp().getStackKind() == JavaKind.Object) {
+                if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) {
                     ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror));
                     instanceOfDynamicNode.setMirror(classGetHub);
                 }
@@ -409,7 +410,7 @@
         StructuredGraph graph = n.graph();
         assert !n.getHub().isConstant();
         AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getVMConfig().klassLayoutHelperOffset);
-        n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(), null, BarrierType.NONE)));
+        n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)));
     }
 
     private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) {
@@ -422,11 +423,12 @@
         StructuredGraph graph = n.graph();
         assert !hub.isConstant() || GraalOptions.ImmutableCode.getValue(graph.getOptions());
         AddressNode mirrorAddress = createOffsetAddress(graph, hub, vmConfig.classMirrorOffset);
-        FloatingReadNode read = graph.unique(new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(),
-                        null, BarrierType.NONE));
+        FloatingReadNode read = graph.unique(
+                        new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(NodeView.DEFAULT),
+                                        null, BarrierType.NONE));
         if (vmConfig.classMirrorIsHandle) {
             AddressNode address = createOffsetAddress(graph, read, 0);
-            read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(), null, BarrierType.NONE));
+            read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
         }
         n.replaceAtUsagesAndDelete(read);
     }
@@ -439,7 +441,7 @@
         StructuredGraph graph = n.graph();
         assert !n.getValue().isConstant();
         AddressNode address = createOffsetAddress(graph, n.getValue(), runtime.getVMConfig().klassOffset);
-        FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(), null, BarrierType.NONE));
+        FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
         n.replaceAtUsagesAndDelete(read);
     }
 
@@ -448,7 +450,7 @@
             MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
             NodeInputList<ValueNode> parameters = callTarget.arguments();
             ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
-            if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
+            if (!callTarget.isStatic() && receiver.stamp(NodeView.DEFAULT) instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
                 ValueNode nonNullReceiver = createNullCheckedValue(receiver, invoke.asNode(), tool);
                 parameters.set(0, nonNullReceiver);
                 receiver = nonNullReceiver;
@@ -586,7 +588,7 @@
                 int size = osrLocal.getStackKind().getSlotCount();
                 int offset = localsOffset - (osrLocal.index() + size - 1) * wordSize;
                 AddressNode address = createOffsetAddress(graph, buffer, offset);
-                ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(), BarrierType.NONE));
+                ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(NodeView.DEFAULT), BarrierType.NONE));
                 osrLocal.replaceAndDelete(load);
                 graph.addBeforeFixed(migrationEnd, load);
             }
@@ -609,7 +611,7 @@
 
                 // load the displaced mark from the osr buffer
                 AddressNode addressDisplacedHeader = createOffsetAddress(graph, buffer, offsetDisplacedHeader);
-                ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(), BarrierType.NONE));
+                ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
                 graph.addBeforeFixed(migrationEnd, loadDisplacedHeader);
 
                 // we need to initialize the stack slot for the lock
@@ -623,7 +625,7 @@
 
                 // load the lock object from the osr buffer
                 AddressNode addressLockObject = createOffsetAddress(graph, buffer, offsetLockObject);
-                ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(), BarrierType.NONE));
+                ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
                 lock.replaceAndDelete(loadObject);
                 graph.addBeforeFixed(migrationEnd, loadObject);
             }
@@ -688,7 +690,7 @@
         }
 
         StructuredGraph graph = node.graph();
-        ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(), node.getArguments()));
+        ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(NodeView.DEFAULT), node.getArguments()));
         graph.replaceFixedWithFixed(node, foreignCallNode);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Dec 07 11:54:55 2017 +0000
@@ -66,6 +66,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -318,7 +319,7 @@
     private static boolean readMetaspaceConstantPoolElement(GraphBuilderContext b, ValueNode constantPoolOop, ValueNode index, JavaKind elementKind, WordTypes wordTypes, GraalHotSpotVMConfig config) {
         ValueNode constants = getMetaspaceConstantPool(b, constantPoolOop, wordTypes, config);
         int shift = CodeUtil.log2(wordTypes.getWordKind().getByteCount());
-        ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long)), b.add(ConstantNode.forInt(shift))));
+        ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long), NodeView.DEFAULT), b.add(ConstantNode.forInt(shift))));
         ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forLong(config.constantPoolSize))));
         AddressNode elementAddress = b.add(new OffsetAddressNode(constants, offset));
         boolean notCompressible = false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvokeDynamicPlugin.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvokeDynamicPlugin.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -136,7 +137,7 @@
 
         ConstantNode appendixNode = ConstantNode.forConstant(appendix, builder.getMetaAccess(), builder.getGraph());
 
-        Stamp appendixStamp = appendixNode.stamp();
+        Stamp appendixStamp = appendixNode.stamp(NodeView.DEFAULT);
         Stamp resolveStamp = treatAppendixAsConstant ? appendixStamp : appendixStamp.unrestricted();
         ResolveDynamicConstantNode resolveNode = new ResolveDynamicConstantNode(resolveStamp, appendixNode);
         ResolveDynamicConstantNode added = builder.append(resolveNode);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java	Thu Dec 07 11:54:55 2017 +0000
@@ -87,7 +87,7 @@
         // Need to test all fields since there no guarantee under the JMM
         // about the order in which these fields are written.
         GraalHotSpotVMConfig config = runtime.getVMConfig();
-        if (configType == null || wordTypesType == null || configType == null) {
+        if (configType == null || wordTypesType == null || runtimeType == null) {
             wordTypesType = wordTypes.getClass();
             runtimeType = runtime.getClass();
             configType = config.getClass();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java	Thu Dec 07 11:54:55 2017 +0000
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode;
 import org.graalvm.compiler.hotspot.word.PointerCastNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
 import org.graalvm.compiler.nodes.calc.IsNullNode;
@@ -102,23 +103,23 @@
                 HotspotOpcode opcode = operation.opcode();
                 ValueNode left = args[0];
                 ValueNode right = args[1];
-                assert left.stamp() instanceof MetaspacePointerStamp : left + " " + left.stamp();
-                assert right.stamp() instanceof MetaspacePointerStamp : right + " " + right.stamp();
+                assert left.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp : left + " " + left.stamp(NodeView.DEFAULT);
+                assert right.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp : right + " " + right.stamp(NodeView.DEFAULT);
                 assert opcode == POINTER_EQ || opcode == POINTER_NE;
 
                 PointerEqualsNode comparison = b.add(new PointerEqualsNode(left, right));
                 ValueNode eqValue = b.add(forBoolean(opcode == POINTER_EQ));
                 ValueNode neValue = b.add(forBoolean(opcode == POINTER_NE));
-                b.addPush(returnKind, ConditionalNode.create(comparison, eqValue, neValue));
+                b.addPush(returnKind, ConditionalNode.create(comparison, eqValue, neValue, NodeView.DEFAULT));
                 break;
 
             case IS_NULL:
                 assert args.length == 1;
                 ValueNode pointer = args[0];
-                assert pointer.stamp() instanceof MetaspacePointerStamp;
+                assert pointer.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp;
 
                 LogicNode isNull = b.addWithInputs(IsNullNode.create(pointer));
-                b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false))));
+                b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)), NodeView.DEFAULT));
                 break;
 
             case FROM_POINTER:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotCompressionNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotCompressionNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.hotspot.nodes.type.HotSpotNarrowOopStamp;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CompressionNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
@@ -45,7 +46,7 @@
     public static final NodeClass<HotSpotCompressionNode> TYPE = NodeClass.create(HotSpotCompressionNode.class);
 
     public HotSpotCompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
-        super(TYPE, op, input, HotSpotNarrowOopStamp.mkStamp(op, input.stamp(), encoding), encoding);
+        super(TYPE, op, input, HotSpotNarrowOopStamp.mkStamp(op, input.stamp(NodeView.DEFAULT), encoding), encoding);
     }
 
     public static HotSpotCompressionNode compress(ValueNode input, CompressEncoding encoding) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -42,7 +43,7 @@
     @Input ValueNode value;
 
     public InitializeKlassNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
@@ -61,7 +62,7 @@
     protected Constant constant;
 
     protected InitializeKlassStubCall(ValueNode value, ValueNode string) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.string = string;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.hotspot.word.MethodPointer;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -56,14 +57,14 @@
     protected HotSpotConstantLoadAction action;
 
     public LoadConstantIndirectlyFixedNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
 
     public LoadConstantIndirectlyFixedNode(ValueNode value, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = action;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -55,14 +56,14 @@
     protected HotSpotConstantLoadAction action;
 
     public LoadConstantIndirectlyNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
 
     public LoadConstantIndirectlyNode(ValueNode value, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = action;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -41,13 +42,13 @@
     protected HotSpotConstantLoadAction action;
 
     public ResolveConstantNode(ValueNode value, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.action = action;
     }
 
     public ResolveConstantNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -59,14 +60,14 @@
     protected HotSpotConstantLoadAction action;
 
     public ResolveConstantStubCall(ValueNode value, ValueNode string) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.string = string;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
 
     public ResolveConstantStubCall(ValueNode value, ValueNode string, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.string = string;
         this.action = action;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -59,7 +60,7 @@
     protected Constant constant;
 
     public ResolveDynamicStubCall(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -50,6 +50,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StartNode;
@@ -185,8 +186,8 @@
                  * (if a branch was not parsed for example). In cases when this is possible, we
                  * insert a guard and narrow the OSRLocal stamp at its usages.
                  */
-                Stamp narrowedStamp = proxy.value().stamp();
-                Stamp unrestrictedStamp = proxy.stamp().unrestricted();
+                Stamp narrowedStamp = proxy.value().stamp(NodeView.DEFAULT);
+                Stamp unrestrictedStamp = proxy.stamp(NodeView.DEFAULT).unrestricted();
                 ValueNode osrLocal;
                 if (i >= localsSize) {
                     osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -130,7 +131,7 @@
                 LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
                 random = loopRandomValueCache.get(loopBegin);
                 if (random == null) {
-                    PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(), loopBegin));
+                    PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(NodeView.DEFAULT), loopBegin));
                     phi.addInput(seed);
                     // X_{n+1} = a*X_n + c, using glibc-like constants
                     ValueNode a = ConstantNode.forInt(1103515245, graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ConvertNode;
@@ -118,7 +119,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        return canonical(this, tool.getMetaAccess(), tool.getConstantReflection(), tool.allUsagesAvailable(), stamp(), clazz);
+        return canonical(this, tool.getMetaAccess(), tool.getConstantReflection(), tool.allUsagesAvailable(), stamp(NodeView.DEFAULT), clazz);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Dec 07 11:54:55 2017 +0000
@@ -45,6 +45,7 @@
 import org.graalvm.compiler.nodes.CompressionNode;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
@@ -124,7 +125,7 @@
                     AddressNode address = access.getAddress();
                     if (address instanceof OffsetAddressNode) {
                         OffsetAddressNode offset = (OffsetAddressNode) address;
-                        assert offset.getBase().stamp().isCompatible(read.stamp());
+                        assert offset.getBase().stamp(NodeView.DEFAULT).isCompatible(read.stamp(NodeView.DEFAULT));
                         return offset.getBase();
                     }
                 }
@@ -370,8 +371,8 @@
         public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
             ValueNode javaObject = findReadHub(object);
             if (javaObject != null) {
-                if (javaObject.stamp() instanceof ObjectStamp) {
-                    ObjectStamp stamp = (ObjectStamp) javaObject.stamp();
+                if (javaObject.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
+                    ObjectStamp stamp = (ObjectStamp) javaObject.stamp(NodeView.DEFAULT);
                     HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess());
                     if (type.isArray() && !type.getComponentType().isPrimitive()) {
                         int layout = type.layoutHelper();
@@ -437,7 +438,7 @@
         public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
             TypeReference constantType = StampTool.typeReferenceOrNull(object);
             if (constantType != null && constantType.isExact()) {
-                return ConstantNode.forConstant(read.stamp(), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess());
+                return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess());
             }
             return read;
         }
@@ -448,7 +449,8 @@
         public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
             TypeReference constantType = StampTool.typeReferenceOrNull(object);
             if (constantType != null && constantType.isExact()) {
-                return ConstantNode.forConstant(read.stamp(), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(), tool.getMetaAccess());
+                return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(),
+                                tool.getMetaAccess());
             }
             return read;
         }
@@ -962,7 +964,7 @@
                         AssumptionResult<ResolvedJavaType> leafType = element.findLeafConcreteSubtype();
                         if (leafType != null && leafType.canRecordTo(assumptions)) {
                             leafType.recordTo(assumptions);
-                            return ConstantNode.forConstant(read.stamp(), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess());
+                            return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess());
                         }
                     }
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -65,7 +66,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object.isConstant()) {
-            assert object.stamp() instanceof AbstractObjectStamp;
+            assert object.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
             JavaConstant c = (JavaConstant) object.asConstant();
             if (ImmutableCode.getValue(tool.getOptions())) {
                 return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java	Thu Dec 07 11:54:55 2017 +0000
@@ -53,6 +53,7 @@
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.SnippetAnchorNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -332,7 +333,7 @@
             } else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) {
                 ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf;
                 Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage());
-                assert ((ObjectStamp) isAssignable.getThisClass().stamp()).nonNull();
+                assert ((ObjectStamp) isAssignable.getThisClass().stamp(NodeView.DEFAULT)).nonNull();
                 args.add("thisClassNonNull", isAssignable.getThisClass());
                 args.add("otherClass", isAssignable.getOtherClass());
                 args.add("trueValue", replacer.trueValue);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
@@ -83,7 +84,7 @@
     public boolean inferStamp() {
         if (klass instanceof LoadHubNode) {
             LoadHubNode hub = (LoadHubNode) klass;
-            Stamp hubStamp = hub.getValue().stamp();
+            Stamp hubStamp = hub.getValue().stamp(NodeView.DEFAULT);
             if (hubStamp instanceof ObjectStamp) {
                 ObjectStamp objectStamp = (ObjectStamp) hubStamp;
                 ResolvedJavaType type = objectStamp.type();
@@ -108,7 +109,7 @@
         if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
-            return canonical(this, config, klass, stamp(), tool.getConstantReflection(), tool.getMetaAccess());
+            return canonical(this, config, klass, stamp(NodeView.DEFAULT), tool.getConstantReflection(), tool.getMetaAccess());
         }
     }
 
@@ -123,7 +124,7 @@
         }
         if (klass instanceof LoadHubNode) {
             LoadHubNode hub = (LoadHubNode) klass;
-            Stamp hubStamp = hub.getValue().stamp();
+            Stamp hubStamp = hub.getValue().stamp(NodeView.DEFAULT);
             if (hubStamp instanceof ObjectStamp) {
                 ObjectStamp ostamp = (ObjectStamp) hubStamp;
                 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ostamp.type();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Thu Dec 07 11:54:55 2017 +0000
@@ -99,6 +99,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -736,7 +737,7 @@
             StructuredGraph graph = monitorenterNode.graph();
             checkBalancedMonitors(graph, tool);
 
-            assert ((ObjectStamp) monitorenterNode.object().stamp()).nonNull();
+            assert ((ObjectStamp) monitorenterNode.object().stamp(NodeView.DEFAULT)).nonNull();
 
             Arguments args;
             if (useFastLocking) {
@@ -781,7 +782,7 @@
         }
 
         public static boolean isTracingEnabledForType(ValueNode object) {
-            ResolvedJavaType type = StampTool.typeOrNull(object.stamp());
+            ResolvedJavaType type = StampTool.typeOrNull(object.stamp(NodeView.DEFAULT));
             String filter = TraceMonitorsTypeFilter.getValue(object.getOptions());
             if (filter == null) {
                 return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -62,14 +63,14 @@
 
     @Override
     protected Stamp computeStamp(ValueNode object) {
-        if (getConcreteType(object.stamp()) != null) {
-            return AbstractPointerStamp.pointerNonNull(object.stamp());
+        if (getConcreteType(object.stamp(NodeView.DEFAULT)) != null) {
+            return AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
         }
         /*
          * If this call can't be intrinsified don't report a non-null stamp, otherwise the stamp
          * would change when this is lowered back to an invoke and we might lose a null check.
          */
-        return AbstractPointerStamp.pointerMaybeNull(object.stamp());
+        return AbstractPointerStamp.pointerMaybeNull(object.stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -91,16 +92,16 @@
                     }
 
                     assert snippetGraph != null : "ObjectCloneSnippets should be installed";
-                    assert getConcreteType(stamp()) != null;
+                    assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                     return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
                 }
                 assert false : "unhandled array type " + type.getComponentType().getJavaKind();
             } else {
                 Assumptions assumptions = graph().getAssumptions();
-                type = getConcreteType(getObject().stamp());
+                type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
                 if (type != null) {
                     StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
-                    ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp())));
+                    ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
                     NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
                     newGraph.addAfterFixed(newGraph.start(), newInstance);
                     ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
@@ -111,12 +112,12 @@
                         newGraph.addBeforeFixed(returnNode, load);
                         newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
                     }
-                    assert getConcreteType(stamp()) != null;
+                    assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                     return lowerReplacement(newGraph, tool);
                 }
             }
         }
-        assert getConcreteType(stamp()) == null;
+        assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
         return null;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Thu Dec 07 11:54:55 2017 +0000
@@ -66,6 +66,7 @@
 import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
 import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode;
@@ -447,7 +448,7 @@
             }
 
             ValueNode expected = writeBarrierPre.getExpectedObject();
-            if (expected != null && expected.stamp() instanceof NarrowOopStamp) {
+            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
                 assert oopEncoding != null;
                 expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
             }
@@ -472,7 +473,7 @@
             }
 
             ValueNode expected = readBarrier.getExpectedObject();
-            if (expected != null && expected.stamp() instanceof NarrowOopStamp) {
+            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
                 assert oopEncoding != null;
                 expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
             }
@@ -503,7 +504,7 @@
             }
 
             ValueNode value = writeBarrierPost.getValue();
-            if (value.stamp() instanceof NarrowOopStamp) {
+            if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
                 assert oopEncoding != null;
                 value = HotSpotCompressionNode.uncompress(value, oopEncoding);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -143,7 +144,7 @@
         FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base));
         graph().addBeforeFixed(this, basePtr);
         Stamp wordStamp = StampFactory.forKind(runtime.getTarget().wordJavaKind);
-        ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph());
+        ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph(), NodeView.DEFAULT);
         int shift = CodeUtil.log2(getArrayIndexScale(elementKind));
         ValueNode scaledIndex = graph().unique(new LeftShiftNode(wordPos, ConstantNode.forInt(shift, graph())));
         ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerStamp(wordStamp, getArrayBaseOffset(elementKind), graph())));
@@ -160,8 +161,8 @@
             ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
             ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
             ValueNode len = getLength();
-            if (len.stamp().getStackKind() != JavaKind.Long) {
-                len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph());
+            if (len.stamp(NodeView.DEFAULT).getStackKind() != JavaKind.Long) {
+                len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph(), NodeView.DEFAULT);
             }
             ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len));
             call.setStateAfter(stateAfter());
@@ -232,8 +233,8 @@
             // Can treat as disjoint
             disjoint = true;
         }
-        PrimitiveConstant constantSrc = (PrimitiveConstant) srcPos.stamp().asConstant();
-        PrimitiveConstant constantDst = (PrimitiveConstant) destPos.stamp().asConstant();
+        PrimitiveConstant constantSrc = (PrimitiveConstant) srcPos.stamp(NodeView.DEFAULT).asConstant();
+        PrimitiveConstant constantDst = (PrimitiveConstant) destPos.stamp(NodeView.DEFAULT).asConstant();
         if (constantSrc != null && constantDst != null) {
             if (!aligned) {
                 aligned = isHeapWordAligned(constantSrc, componentKind) && isHeapWordAligned(constantDst, componentKind);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Thu Dec 07 11:54:55 2017 +0000
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -90,11 +91,12 @@
 
     private enum ArrayCopyTypeCheck {
         UNDEFINED_ARRAY_TYPE_CHECK,
-        // we know that both objects are arrays and have the same type
+        // either we know that both objects are arrays and have the same type,
+        // or we apply generic array copy snippet, which enforces type check
         NO_ARRAY_TYPE_CHECK,
         // can be used when we know that one of the objects is a primitive array
         HUB_BASED_ARRAY_TYPE_CHECK,
-        // must be used when we don't have sufficient information to use one of the others
+        // can be used when we know that one of the objects is an object array
         LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK
     }
 
@@ -232,18 +234,18 @@
 
     @Snippet(allowPartialIntrinsicArgumentMismatch = true)
     public static void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
-        if (probability(FREQUENT_PROBABILITY, length > 0)) {
-            counters.genericArraycopyDifferentTypeCounter.inc();
-            counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
-            int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
-            if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
-                /*
-                 * the stub doesn't throw the ArrayStoreException, but returns the number of copied
-                 * elements (xor'd with -1).
-                 */
-                copiedElements ^= -1;
-                System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
-            }
+        // The length > 0 check should not be placed here because generic array copy stub should
+        // enforce type check. This is fine performance-wise because this snippet is rarely used.
+        counters.genericArraycopyDifferentTypeCounter.inc();
+        counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
+        int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
+        if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+            /*
+             * the stub doesn't throw the ArrayStoreException, but returns the number of copied
+             * elements (xor'd with -1).
+             */
+            copiedElements ^= -1;
+            System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
         }
     }
 
@@ -275,21 +277,14 @@
         } else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
             KlassPointer srcHub = loadHub(nonNullSrc);
             KlassPointer destHub = loadHub(nonNullDest);
-            checkArrayType(srcHub);
-            checkArrayType(destHub);
+            if (probability(SLOW_PATH_PROBABILITY, readLayoutHelper(srcHub) != readLayoutHelper(destHub))) {
+                DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+            }
         } else {
             ReplacementsUtil.staticAssert(false, "unknown array type check");
         }
     }
 
-    private static int checkArrayType(KlassPointer nonNullHub) {
-        int layoutHelper = readLayoutHelper(nonNullHub);
-        if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        return layoutHelper;
-    }
-
     static class Counters {
         final SnippetCounter checkSuccessCounter;
         final SnippetCounter checkAIOOBECounter;
@@ -381,8 +376,8 @@
             SnippetInfo snippetInfo;
             ArrayCopyTypeCheck arrayTypeCheck;
 
-            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
-            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp(NodeView.DEFAULT));
+            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp(NodeView.DEFAULT));
             if (!canBeArray(srcType) || !canBeArray(destType)) {
                 // at least one of the objects is definitely not an array - use the native call
                 // right away as the copying will fail anyways
@@ -399,7 +394,8 @@
                 } else if (srcComponentType == null && destComponentType == null) {
                     // we don't know anything about the types - use the generic copying
                     snippetInfo = arraycopyGenericSnippet;
-                    arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+                    // no need for additional type check to avoid duplicated work
+                    arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
                 } else if (srcComponentType != null && destComponentType != null) {
                     if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
                         // it depends on the array content if the copy succeeds - we need
@@ -416,14 +412,14 @@
                 } else {
                     ResolvedJavaType nonNullComponentType = srcComponentType != null ? srcComponentType : destComponentType;
                     if (nonNullComponentType.isPrimitive()) {
-                        // one involved object is a primitive array - we can safely assume that we
-                        // are copying primitive arrays
+                        // one involved object is a primitive array - it is sufficient to directly
+                        // compare the hub.
                         snippetInfo = arraycopyExactSnippet;
                         arrayTypeCheck = ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK;
                         elementKind = nonNullComponentType.getJavaKind();
                     } else {
-                        // one involved object is an object array - we can safely assume that we are
-                        // copying object arrays that might require a store check
+                        // one involved object is an object array - the other array's element type
+                        // may be primitive or object, hence we compare the layout helper.
                         snippetInfo = arraycopyCheckcastSnippet;
                         arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
                     }
@@ -432,7 +428,12 @@
 
             // a few special cases that are easier to handle when all other variables already have a
             // value
-            if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
+            if (snippetInfo != arraycopyNativeSnippet && snippetInfo != arraycopyGenericSnippet && arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
+                // Copying 0 element between object arrays with conflicting types will not throw an
+                // exception - once we pass the preliminary element type checks that we are not
+                // mixing arrays of different basic types, ArrayStoreException is only thrown when
+                // an *astore would have thrown it. Therefore, copying null between object arrays
+                // with conflicting types will also succeed (we do not optimize for such case here).
                 snippetInfo = arraycopyZeroLengthSnippet;
             } else if (snippetInfo == arraycopyExactSnippet && shouldUnroll(arraycopy.getLength())) {
                 snippetInfo = arraycopyUnrolledSnippet;
@@ -495,8 +496,8 @@
         }
 
         public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
-            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
-            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp(NodeView.DEFAULT));
+            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp(NodeView.DEFAULT));
 
             if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
                 return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -115,9 +116,10 @@
         graph().addBeforeFixed(this, basePtr);
 
         int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
-        ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
         ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
-        ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp()), getArrayBaseOffset(JavaKind.Object), graph())));
+        ValueNode offset = graph().unique(
+                        new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp(NodeView.DEFAULT)), getArrayBaseOffset(JavaKind.Object), graph())));
         return graph().unique(new OffsetAddressNode(basePtr, offset));
     }
 
@@ -129,8 +131,8 @@
             ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
             ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
             ValueNode len = getLength();
-            if (len.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
-                len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+            if (len.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
+                len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
             }
             ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len, superCheckOffset, destElemKlass));
             call.setStateAfter(stateAfter());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
@@ -106,8 +107,8 @@
     }
 
     private ValueNode wordValue(ValueNode value) {
-        if (value.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
-            return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        if (value.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
+            return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
         }
         return value;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
 import org.graalvm.compiler.java.GraphBuilderPhase;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
@@ -120,7 +121,7 @@
             for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
                 int index = param.index();
                 if (method.getParameterAnnotation(NonNullParameter.class, index) != null) {
-                    param.setStamp(param.stamp().join(StampFactory.objectNonNull()));
+                    param.setStamp(param.stamp(NodeView.DEFAULT).join(StampFactory.objectNonNull()));
                 }
             }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/PointerCastNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/PointerCastNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -59,7 +60,7 @@
     @Override
     public void generate(NodeLIRBuilderTool generator) {
         Value value = generator.operand(input);
-        assert value.getValueKind().equals(generator.getLIRGeneratorTool().getLIRKind(stamp())) : "PointerCastNode shouldn't change the LIRKind";
+        assert value.getValueKind().equals(generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT))) : "PointerCastNode shouldn't change the LIRKind";
 
         generator.setResult(this, value);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Thu Dec 07 11:54:55 2017 +0000
@@ -330,6 +330,7 @@
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ReturnNode;
@@ -1092,71 +1093,71 @@
     }
 
     protected ValueNode genIntegerAdd(ValueNode x, ValueNode y) {
-        return AddNode.create(x, y);
+        return AddNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerSub(ValueNode x, ValueNode y) {
-        return SubNode.create(x, y);
+        return SubNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerMul(ValueNode x, ValueNode y) {
-        return MulNode.create(x, y);
+        return MulNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatAdd(ValueNode x, ValueNode y) {
-        return AddNode.create(x, y);
+        return AddNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatSub(ValueNode x, ValueNode y) {
-        return SubNode.create(x, y);
+        return SubNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatMul(ValueNode x, ValueNode y) {
-        return MulNode.create(x, y);
+        return MulNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatDiv(ValueNode x, ValueNode y) {
-        return FloatDivNode.create(x, y);
+        return FloatDivNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatRem(ValueNode x, ValueNode y) {
-        return new RemNode(x, y);
+        return RemNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerDiv(ValueNode x, ValueNode y) {
-        return new SignedDivNode(x, y);
+        return SignedDivNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerRem(ValueNode x, ValueNode y) {
-        return new SignedRemNode(x, y);
+        return SignedRemNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genNegateOp(ValueNode x) {
-        return NegateNode.create(x);
+        return NegateNode.create(x, NodeView.DEFAULT);
     }
 
     protected ValueNode genLeftShift(ValueNode x, ValueNode y) {
-        return LeftShiftNode.create(x, y);
+        return LeftShiftNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genRightShift(ValueNode x, ValueNode y) {
-        return RightShiftNode.create(x, y);
+        return RightShiftNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genUnsignedRightShift(ValueNode x, ValueNode y) {
-        return new UnsignedRightShiftNode(x, y);
+        return UnsignedRightShiftNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genAnd(ValueNode x, ValueNode y) {
-        return AndNode.create(x, y);
+        return AndNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genOr(ValueNode x, ValueNode y) {
-        return OrNode.create(x, y);
+        return OrNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genXor(ValueNode x, ValueNode y) {
-        return XorNode.create(x, y);
+        return XorNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genNormalizeCompare(ValueNode x, ValueNode y, boolean isUnorderedLess) {
@@ -1164,19 +1165,19 @@
     }
 
     protected ValueNode genFloatConvert(FloatConvert op, ValueNode input) {
-        return FloatConvertNode.create(op, input);
+        return FloatConvertNode.create(op, input, NodeView.DEFAULT);
     }
 
     protected ValueNode genNarrow(ValueNode input, int bitCount) {
-        return NarrowNode.create(input, bitCount);
+        return NarrowNode.create(input, bitCount, NodeView.DEFAULT);
     }
 
     protected ValueNode genSignExtend(ValueNode input, int bitCount) {
-        return SignExtendNode.create(input, bitCount);
+        return SignExtendNode.create(input, bitCount, NodeView.DEFAULT);
     }
 
     protected ValueNode genZeroExtend(ValueNode input, int bitCount) {
-        return ZeroExtendNode.create(input, bitCount);
+        return ZeroExtendNode.create(input, bitCount, NodeView.DEFAULT);
     }
 
     protected void genGoto() {
@@ -1191,15 +1192,15 @@
     }
 
     protected LogicNode genObjectEquals(ValueNode x, ValueNode y) {
-        return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y);
+        return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, NodeView.DEFAULT);
     }
 
     protected LogicNode genIntegerEquals(ValueNode x, ValueNode y) {
-        return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y);
+        return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
     }
 
     protected LogicNode genIntegerLessThan(ValueNode x, ValueNode y) {
-        return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y);
+        return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genUnique(ValueNode x) {
@@ -1219,7 +1220,7 @@
 
         ValueNode exception = frameState.pop(JavaKind.Object);
         FixedGuardNode nullCheck = append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(exception)), NullCheckException, InvalidateReprofile, true));
-        ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp().join(objectNonNull()), nullCheck));
+        ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp(NodeView.DEFAULT).join(objectNonNull()), nullCheck));
         lastInstr.setNext(handleException(nonNullException, bci(), false));
     }
 
@@ -1244,7 +1245,7 @@
     }
 
     protected ValueNode genConditional(ValueNode x) {
-        return ConditionalNode.create((LogicNode) x);
+        return ConditionalNode.create((LogicNode) x, NodeView.DEFAULT);
     }
 
     protected NewInstanceNode createNewInstance(ResolvedJavaType type, boolean fillContents) {
@@ -1275,7 +1276,7 @@
     }
 
     protected ValueNode emitExplicitNullCheck(ValueNode receiver) {
-        if (StampTool.isPointerNonNull(receiver.stamp())) {
+        if (StampTool.isPointerNonNull(receiver.stamp(NodeView.DEFAULT))) {
             return receiver;
         }
         BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
@@ -1293,7 +1294,7 @@
     protected void emitExplicitBoundsCheck(ValueNode index, ValueNode length) {
         AbstractBeginNode trueSucc = graph.add(new BeginNode());
         BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index));
-        append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length)), trueSucc, exception, FAST_PATH_PROBABILITY));
+        append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length, NodeView.DEFAULT)), trueSucc, exception, FAST_PATH_PROBABILITY));
         lastInstr = trueSucc;
 
         exception.setStateAfter(createFrameState(bci(), exception));
@@ -1803,7 +1804,7 @@
             this.args = args;
             this.resultType = resultType;
             this.beforeStackSize = frameState.stackSize();
-            this.needsNullCheck = !targetMethod.isStatic() && args[0].getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(args[0].stamp());
+            this.needsNullCheck = !targetMethod.isStatic() && args[0].getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(args[0].stamp(NodeView.DEFAULT));
             this.nodeCount = graph.getNodeCount();
             this.mark = graph.getMark();
         }
@@ -1817,7 +1818,8 @@
                 int expectedStackSize = beforeStackSize + resultType.getSlotCount();
                 assert expectedStackSize == frameState.stackSize() : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, frameState.stackSize());
                 NodeIterable<Node> newNodes = graph.getNewNodes(mark);
-                assert !needsNullCheck || isPointerNonNull(args[0].stamp()) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"), args[0]);
+                assert !needsNullCheck || isPointerNonNull(args[0].stamp(NodeView.DEFAULT)) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"),
+                                args[0]);
                 for (Node n : newNodes) {
                     if (n instanceof StateSplit) {
                         StateSplit stateSplit = (StateSplit) n;
@@ -1891,7 +1893,7 @@
             LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
             LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
             ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
-            LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected));
+            LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected, NodeView.DEFAULT));
 
             JavaTypeProfile profile = null;
             if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
@@ -2394,7 +2396,7 @@
         if (kind != returnKind) {
             // sub-word integer
             assert returnKind.isNumericInteger() && returnKind.getStackKind() == JavaKind.Int;
-            IntegerStamp stamp = (IntegerStamp) value.stamp();
+            IntegerStamp stamp = (IntegerStamp) value.stamp(NodeView.DEFAULT);
 
             // the bytecode verifier doesn't check that the value is in the correct range
             if (stamp.lowerBound() < returnKind.getMinValue() || returnKind.getMaxValue() < stamp.upperBound()) {
@@ -2480,7 +2482,7 @@
         JsrScope scope = currentBlock.getJsrScope();
         int retAddress = scope.nextReturnAddress();
         ConstantNode returnBciNode = getJsrConstant(retAddress);
-        LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode);
+        LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
         guard = graph.addOrUniqueWithInputs(guard);
         append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
         if (!successor.getJsrScope().equals(scope.pop())) {
@@ -3184,7 +3186,7 @@
     private void genConditionalForIf(BciBlock trueBlock, LogicNode condition, int oldBci, int trueBlockInt, int falseBlockInt, boolean genReturn) {
         ConstantNode trueValue = graph.unique(ConstantNode.forInt(trueBlockInt));
         ConstantNode falseValue = graph.unique(ConstantNode.forInt(falseBlockInt));
-        ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue);
+        ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue, NodeView.DEFAULT);
         if (conditionalNode.graph() == null) {
             conditionalNode = graph.addOrUniqueWithInputs(conditionalNode);
         }
@@ -3716,7 +3718,7 @@
             }
         }
 
-        boolean nonNull = ((ObjectStamp) object.stamp()).nonNull();
+        boolean nonNull = ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
         if (castNode == null) {
             LogicNode condition = genUnique(createInstanceOfAllowNull(checkedType, object, null));
             if (condition.isTautology()) {
@@ -4174,7 +4176,8 @@
         ValueNode value = frameState.pop(JavaKind.Int);
 
         int nofCases = bs.numberOfCases();
-        double[] keyProbabilities = switchProbability(nofCases + 1, bci);
+        int nofCasesPlusDefault = nofCases + 1;
+        double[] keyProbabilities = switchProbability(nofCasesPlusDefault, bci);
 
         EconomicMap<Integer, SuccessorInfo> bciToBlockSuccessorIndex = EconomicMap.create(Equivalence.DEFAULT);
         for (int i = 0; i < currentBlock.getSuccessorCount(); i++) {
@@ -4184,11 +4187,11 @@
 
         ArrayList<BciBlock> actualSuccessors = new ArrayList<>();
         int[] keys = new int[nofCases];
-        int[] keySuccessors = new int[nofCases + 1];
+        int[] keySuccessors = new int[nofCasesPlusDefault];
         int deoptSuccessorIndex = -1;
         int nextSuccessorIndex = 0;
         boolean constantValue = value.isConstant();
-        for (int i = 0; i < nofCases + 1; i++) {
+        for (int i = 0; i < nofCasesPlusDefault; i++) {
             if (i < nofCases) {
                 keys[i] = bs.keyAt(i);
             }
@@ -4200,7 +4203,7 @@
                 }
                 keySuccessors[i] = deoptSuccessorIndex;
             } else {
-                int targetBci = i >= nofCases ? bs.defaultTarget() : bs.targetAt(i);
+                int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
                 SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
                 if (info.actualIndex < 0) {
                     info.actualIndex = nextSuccessorIndex++;
@@ -4209,6 +4212,48 @@
                 keySuccessors[i] = info.actualIndex;
             }
         }
+        /*
+         * When the profile indicates a case is never taken, the above code will cause the case to
+         * deopt should it be subsequently encountered. However, the case may share code with
+         * another case that is taken according to the profile.
+         *
+         * For example:
+         * // @formatter:off
+         * switch (opcode) {
+         *     case GOTO:
+         *     case GOTO_W: {
+         *         // emit goto code
+         *         break;
+         *     }
+         * }
+         * // @formatter:on
+         *
+         * The profile may indicate the GOTO_W case is never taken, and thus a deoptimization stub
+         * will be emitted. There might be optimization opportunity if additional branching based
+         * on opcode is within the case block. Specially, if there is only single case that
+         * reaches a target, we have better chance cutting out unused branches. Otherwise,
+         * it might be beneficial routing to the same code instead of deopting.
+         *
+         * The following code rewires deoptimization stub to existing resolved branch target if
+         * the target is connected by more than 1 cases.
+         */
+        if (deoptSuccessorIndex >= 0) {
+            int[] connectedCases = new int[nextSuccessorIndex];
+            for (int i = 0; i < nofCasesPlusDefault; i++) {
+                connectedCases[keySuccessors[i]]++;
+            }
+
+            for (int i = 0; i < nofCasesPlusDefault; i++) {
+                if (keySuccessors[i] == deoptSuccessorIndex) {
+                    int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
+                    SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
+                    int rewiredIndex = info.actualIndex;
+                    if (rewiredIndex >= 0 && connectedCases[rewiredIndex] > 1) {
+                        keySuccessors[i] = info.actualIndex;
+                    }
+                }
+            }
+        }
 
         genIntegerSwitch(value, actualSuccessors, keys, keyProbabilities, keySuccessors);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -55,6 +55,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -460,7 +461,7 @@
     }
 
     private ValuePhiNode createValuePhi(ValueNode currentValue, ValueNode otherValue, AbstractMergeNode block) {
-        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp().unrestricted(), block));
+        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp(NodeView.DEFAULT).unrestricted(), block));
         for (int i = 0; i < block.phiPredecessorCount(); i++) {
             phi.addInput(currentValue);
         }
@@ -558,7 +559,7 @@
         }
         assert !block.isPhiAtMerge(value) : "phi function for this block already created";
 
-        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp() : value.stamp().unrestricted(), block));
+        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp(NodeView.DEFAULT) : value.stamp(NodeView.DEFAULT).unrestricted(), block));
         phi.addInput(value);
         return phi;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/jdk/Unsafe_compareAndSwapNullCheck.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/jdk/Unsafe_compareAndSwapNullCheck.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,7 +23,6 @@
 package org.graalvm.compiler.jtt.jdk;
 
 import org.graalvm.compiler.jtt.JTTTest;
-import org.junit.Assume;
 import org.junit.Test;
 
 public class Unsafe_compareAndSwapNullCheck extends JTTTest {
@@ -48,8 +47,6 @@
 
     @Test
     public void run0() throws Throwable {
-        // GR-2921: Unsafe_compareAndSwapNullCheck test crashes on jdk9
-        Assume.assumeTrue(Java8OrEarlier);
         runTest(getInitialOptions(), EMPTY, false, true, "test", null, 1L, 2L);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Thu Dec 07 11:54:55 2017 +0000
@@ -299,16 +299,23 @@
 
         @Def({REG}) protected AllocatableValue result;
         @Use({COMPOSITE, UNINITIALIZED}) protected AMD64AddressValue address;
+        private final OperandSize size;
 
-        public LeaOp(AllocatableValue result, AMD64AddressValue address) {
+        public LeaOp(AllocatableValue result, AMD64AddressValue address, OperandSize size) {
             super(TYPE);
             this.result = result;
             this.address = address;
+            this.size = size;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            masm.leaq(asRegister(result, AMD64Kind.QWORD), address.toAddress());
+            if (size == OperandSize.QWORD) {
+                masm.leaq(asRegister(result, AMD64Kind.QWORD), address.toAddress());
+            } else {
+                assert size == OperandSize.DWORD;
+                masm.lead(asRegister(result, AMD64Kind.DWORD), address.toAddress());
+            }
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java	Thu Dec 07 11:54:55 2017 +0000
@@ -340,7 +340,7 @@
     private static boolean isPrintableAsciiString(byte[] array) {
         for (byte b : array) {
             char c = (char) b;
-            if (c != 0 && c < 0x20 && c > 0x7F) {
+            if (c != 0 && (c < 0x20 || c > 0x7F)) {
                 return false;
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -159,97 +159,101 @@
 
         intervalInLoop = new BitMap2D(allocator.operandSize(), allocator.numLoops());
 
-        // iterate all blocks
-        for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
-            try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
+        try {
+            // iterate all blocks
+            for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
+                try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
 
-                final BitSet liveGen = new BitSet(liveSize);
-                final BitSet liveKill = new BitSet(liveSize);
+                    final BitSet liveGen = new BitSet(liveSize);
+                    final BitSet liveKill = new BitSet(liveSize);
+
+                    ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
+                    int numInst = instructions.size();
 
-                ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
-                int numInst = instructions.size();
-
-                ValueConsumer useConsumer = (operand, mode, flags) -> {
-                    if (isVariable(operand)) {
-                        int operandNum = allocator.operandNumber(operand);
-                        if (!liveKill.get(operandNum)) {
-                            liveGen.set(operandNum);
-                            if (debug.isLogEnabled()) {
-                                debug.log("liveGen for operand %d(%s)", operandNum, operand);
+                    ValueConsumer useConsumer = (operand, mode, flags) -> {
+                        if (isVariable(operand)) {
+                            int operandNum = allocator.operandNumber(operand);
+                            if (!liveKill.get(operandNum)) {
+                                liveGen.set(operandNum);
+                                if (debug.isLogEnabled()) {
+                                    debug.log("liveGen for operand %d(%s)", operandNum, operand);
+                                }
+                            }
+                            if (block.getLoop() != null) {
+                                intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
                             }
                         }
-                        if (block.getLoop() != null) {
-                            intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
+
+                        if (allocator.detailedAsserts) {
+                            verifyInput(block, liveKill, operand);
                         }
-                    }
-
-                    if (allocator.detailedAsserts) {
-                        verifyInput(block, liveKill, operand);
-                    }
-                };
-                ValueConsumer stateConsumer = (operand, mode, flags) -> {
-                    if (LinearScan.isVariableOrRegister(operand)) {
-                        int operandNum = allocator.operandNumber(operand);
-                        if (!liveKill.get(operandNum)) {
-                            liveGen.set(operandNum);
-                            if (debug.isLogEnabled()) {
-                                debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
+                    };
+                    ValueConsumer stateConsumer = (operand, mode, flags) -> {
+                        if (LinearScan.isVariableOrRegister(operand)) {
+                            int operandNum = allocator.operandNumber(operand);
+                            if (!liveKill.get(operandNum)) {
+                                liveGen.set(operandNum);
+                                if (debug.isLogEnabled()) {
+                                    debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
+                                }
                             }
                         }
-                    }
-                };
-                ValueConsumer defConsumer = (operand, mode, flags) -> {
-                    if (isVariable(operand)) {
-                        int varNum = allocator.operandNumber(operand);
-                        liveKill.set(varNum);
-                        if (debug.isLogEnabled()) {
-                            debug.log("liveKill for operand %d(%s)", varNum, operand);
+                    };
+                    ValueConsumer defConsumer = (operand, mode, flags) -> {
+                        if (isVariable(operand)) {
+                            int varNum = allocator.operandNumber(operand);
+                            liveKill.set(varNum);
+                            if (debug.isLogEnabled()) {
+                                debug.log("liveKill for operand %d(%s)", varNum, operand);
+                            }
+                            if (block.getLoop() != null) {
+                                intervalInLoop.setBit(varNum, block.getLoop().getIndex());
+                            }
+                        }
+
+                        if (allocator.detailedAsserts) {
+                            /*
+                             * Fixed intervals are never live at block boundaries, so they need not
+                             * be processed in live sets. Process them only in debug mode so that
+                             * this can be checked
+                             */
+                            verifyTemp(liveKill, operand);
                         }
-                        if (block.getLoop() != null) {
-                            intervalInLoop.setBit(varNum, block.getLoop().getIndex());
+                    };
+
+                    // iterate all instructions of the block
+                    for (int j = 0; j < numInst; j++) {
+                        final LIRInstruction op = instructions.get(j);
+
+                        try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
+                            op.visitEachInput(useConsumer);
+                            op.visitEachAlive(useConsumer);
+                            /*
+                             * Add uses of live locals from interpreter's point of view for proper
+                             * debug information generation.
+                             */
+                            op.visitEachState(stateConsumer);
+                            op.visitEachTemp(defConsumer);
+                            op.visitEachOutput(defConsumer);
                         }
+                    } // end of instruction iteration
+
+                    BlockData blockSets = allocator.getBlockData(block);
+                    blockSets.liveGen = liveGen;
+                    blockSets.liveKill = liveKill;
+                    blockSets.liveIn = new BitSet(liveSize);
+                    blockSets.liveOut = new BitSet(liveSize);
+
+                    if (debug.isLogEnabled()) {
+                        debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
+                        debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
                     }
 
-                    if (allocator.detailedAsserts) {
-                        /*
-                         * Fixed intervals are never live at block boundaries, so they need not be
-                         * processed in live sets. Process them only in debug mode so that this can
-                         * be checked
-                         */
-                        verifyTemp(liveKill, operand);
-                    }
-                };
-
-                // iterate all instructions of the block
-                for (int j = 0; j < numInst; j++) {
-                    final LIRInstruction op = instructions.get(j);
-
-                    try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
-                        op.visitEachInput(useConsumer);
-                        op.visitEachAlive(useConsumer);
-                        /*
-                         * Add uses of live locals from interpreter's point of view for proper debug
-                         * information generation.
-                         */
-                        op.visitEachState(stateConsumer);
-                        op.visitEachTemp(defConsumer);
-                        op.visitEachOutput(defConsumer);
-                    }
-                } // end of instruction iteration
-
-                BlockData blockSets = allocator.getBlockData(block);
-                blockSets.liveGen = liveGen;
-                blockSets.liveKill = liveKill;
-                blockSets.liveIn = new BitSet(liveSize);
-                blockSets.liveOut = new BitSet(liveSize);
-
-                if (debug.isLogEnabled()) {
-                    debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
-                    debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
                 }
-
-            }
-        } // end of block iteration
+            } // end of block iteration
+        } catch (OutOfMemoryError oom) {
+            throw new PermanentBailoutException(oom, "Out-of-memory during live set allocation of size %d", liveSize);
+        }
     }
 
     private void verifyTemp(BitSet liveKill, Value operand) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/constopt/ConstantTree.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/constopt/ConstantTree.java	Thu Dec 07 11:54:55 2017 +0000
@@ -76,7 +76,7 @@
 
         public List<UseEntry> getUsages() {
             if (usages == null) {
-                Collections.emptyList();
+                return Collections.emptyList();
             }
             return usages;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/BasicInductionVariable.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/BasicInductionVariable.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -70,7 +71,7 @@
 
     @Override
     public Direction direction() {
-        Stamp stamp = rawStride.stamp();
+        Stamp stamp = rawStride.stamp(NodeView.DEFAULT);
         if (stamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) stamp;
             Direction dir = null;
@@ -140,27 +141,27 @@
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        Stamp fromStamp = phi.stamp();
+        Stamp fromStamp = phi.stamp(NodeView.DEFAULT);
         StructuredGraph graph = graph();
         ValueNode stride = strideNode();
         ValueNode initNode = this.initNode();
         if (!fromStamp.isCompatible(stamp)) {
-            stride = IntegerConvertNode.convert(stride, stamp, graph());
-            initNode = IntegerConvertNode.convert(initNode, stamp, graph());
+            stride = IntegerConvertNode.convert(stride, stamp, graph(), NodeView.DEFAULT);
+            initNode = IntegerConvertNode.convert(initNode, stamp, graph(), NodeView.DEFAULT);
         }
         ValueNode maxTripCount = loop.counted().maxTripCountNode(assumePositiveTripCount);
-        if (!maxTripCount.stamp().isCompatible(stamp)) {
-            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
+        if (!maxTripCount.stamp(NodeView.DEFAULT).isCompatible(stamp)) {
+            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph(), NodeView.DEFAULT);
         }
         return add(graph, mul(graph, stride, sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
     }
 
     @Override
     public ValueNode exitValueNode() {
-        Stamp stamp = phi.stamp();
+        Stamp stamp = phi.stamp(NodeView.DEFAULT);
         ValueNode maxTripCount = loop.counted().maxTripCountNode(false);
-        if (!maxTripCount.stamp().isCompatible(stamp)) {
-            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
+        if (!maxTripCount.stamp(NodeView.DEFAULT).isCompatible(stamp)) {
+            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph(), NodeView.DEFAULT);
         }
         return add(graph(), mul(graph(), strideNode(), maxTripCount), initNode());
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.GuardNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -69,7 +70,7 @@
 
     public ValueNode maxTripCountNode(boolean assumePositive) {
         StructuredGraph graph = iv.valueNode().graph();
-        Stamp stamp = iv.valueNode().stamp();
+        Stamp stamp = iv.valueNode().stamp(NodeView.DEFAULT);
         ValueNode range = sub(graph, end, iv.initNode());
 
         ValueNode oneDirection;
@@ -84,7 +85,7 @@
         }
         // round-away-from-zero divison: (range + stride -/+ 1) / stride
         ValueNode denominator = range;
-        if (!oneDirection.stamp().equals(iv.strideNode().stamp())) {
+        if (!oneDirection.stamp(NodeView.DEFAULT).equals(iv.strideNode().stamp(NodeView.DEFAULT))) {
             ValueNode subedRanged = sub(graph, range, oneDirection);
             denominator = add(graph, subedRanged, iv.strideNode());
         }
@@ -204,7 +205,7 @@
         if (overflowGuard != null) {
             return overflowGuard;
         }
-        IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp();
+        IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
         StructuredGraph graph = iv.valueNode().graph();
         CompareNode cond; // we use a negated guard with a < condition to achieve a >=
         ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
@@ -230,6 +231,6 @@
     }
 
     public IntegerStamp getStamp() {
-        return (IntegerStamp) iv.valueNode().stamp();
+        return (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedConvertedInductionVariable.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedConvertedInductionVariable.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,6 +23,7 @@
 package org.graalvm.compiler.loop;
 
 import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
 
@@ -49,12 +50,12 @@
 
     @Override
     public ValueNode initNode() {
-        return IntegerConvertNode.convert(base.initNode(), stamp, graph());
+        return IntegerConvertNode.convert(base.initNode(), stamp, graph(), NodeView.DEFAULT);
     }
 
     @Override
     public ValueNode strideNode() {
-        return IntegerConvertNode.convert(base.strideNode(), stamp, graph());
+        return IntegerConvertNode.convert(base.strideNode(), stamp, graph(), NodeView.DEFAULT);
     }
 
     @Override
@@ -84,7 +85,7 @@
 
     @Override
     public ValueNode exitValueNode() {
-        return IntegerConvertNode.convert(base.exitValueNode(), stamp, graph());
+        return IntegerConvertNode.convert(base.exitValueNode(), stamp, graph(), NodeView.DEFAULT);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedOffsetInductionVariable.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedOffsetInductionVariable.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
@@ -90,14 +91,14 @@
     @Override
     public ValueNode strideNode() {
         if (value instanceof SubNode && base.valueNode() == value.getY()) {
-            return graph().addOrUniqueWithInputs(NegateNode.create(base.strideNode()));
+            return graph().addOrUniqueWithInputs(NegateNode.create(base.strideNode(), NodeView.DEFAULT));
         }
         return base.strideNode();
     }
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp, graph()));
+        return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp, graph(), NodeView.DEFAULT));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedScaledInductionVariable.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedScaledInductionVariable.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
 import org.graalvm.compiler.nodes.calc.NegateNode;
@@ -45,7 +46,7 @@
 
     public DerivedScaledInductionVariable(LoopEx loop, InductionVariable base, NegateNode value) {
         super(loop, base);
-        this.scale = ConstantNode.forIntegerStamp(value.stamp(), -1, value.graph());
+        this.scale = ConstantNode.forIntegerStamp(value.stamp(NodeView.DEFAULT), -1, value.graph());
         this.value = value;
     }
 
@@ -60,7 +61,7 @@
 
     @Override
     public Direction direction() {
-        Stamp stamp = scale.stamp();
+        Stamp stamp = scale.stamp(NodeView.DEFAULT);
         if (stamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) stamp;
             if (integerStamp.isStrictlyPositive()) {
@@ -104,7 +105,7 @@
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
+        return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph(), NodeView.DEFAULT));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/InductionVariable.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/InductionVariable.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 
@@ -93,7 +94,7 @@
      * {@link CountedLoopInfo#isExactTripCount()} returns false for the containing loop.
      */
     public ValueNode extremumNode() {
-        return extremumNode(false, valueNode().stamp());
+        return extremumNode(false, valueNode().stamp(NodeView.DEFAULT));
     }
 
     public abstract ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -188,7 +189,7 @@
             if (!binary.isAssociative()) {
                 continue;
             }
-            ValueNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY());
+            ValueNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY(), NodeView.DEFAULT);
             if (result != binary) {
                 if (!result.isAlive()) {
                     assert !result.isDeleted();
@@ -259,8 +260,8 @@
                     if (!iv.isConstantStride() || Math.abs(iv.constantStride()) != 1) {
                         return false;
                     }
-                    IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp();
-                    IntegerStamp limitStamp = (IntegerStamp) limit.stamp();
+                    IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp(NodeView.DEFAULT);
+                    IntegerStamp limitStamp = (IntegerStamp) limit.stamp(NodeView.DEFAULT);
                     if (iv.direction() == Direction.Up) {
                         if (initStamp.upperBound() > limitStamp.lowerBound()) {
                             return false;
@@ -392,12 +393,12 @@
                 } else {
                     boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
                     if (!isValidConvert && op instanceof ZeroExtendNode) {
-                        IntegerStamp inputStamp = (IntegerStamp) ((ZeroExtendNode) op).getValue().stamp();
+                        IntegerStamp inputStamp = (IntegerStamp) ((ZeroExtendNode) op).getValue().stamp(NodeView.DEFAULT);
                         isValidConvert = inputStamp.isPositive();
                     }
 
                     if (isValidConvert) {
-                        iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(), op);
+                        iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
                     }
                 }
 
@@ -411,7 +412,7 @@
     }
 
     private static ValueNode addSub(LoopEx loop, ValueNode op, ValueNode base) {
-        if (op.stamp() instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
+        if (op.stamp(NodeView.DEFAULT) instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
             BinaryArithmeticNode<?> aritOp = (BinaryArithmeticNode<?>) op;
             if (aritOp.getX() == base && loop.isOutsideLoop(aritOp.getY())) {
                 return aritOp.getY();
@@ -434,7 +435,7 @@
         if (op instanceof LeftShiftNode) {
             LeftShiftNode shift = (LeftShiftNode) op;
             if (shift.getX() == base && shift.getY().isConstant()) {
-                return ConstantNode.forIntegerStamp(base.stamp(), 1 << shift.getY().asJavaConstant().asInt(), base.graph());
+                return ConstantNode.forIntegerStamp(base.stamp(NodeView.DEFAULT), 1 << shift.getY().asJavaConstant().asInt(), base.graph());
             }
         }
         return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -460,7 +461,7 @@
                 if (newVpn != null) {
                     PhiNode phi;
                     if (vpn instanceof ValueProxyNode) {
-                        phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(), merge));
+                        phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(NodeView.DEFAULT), merge));
                     } else if (vpn instanceof GuardProxyNode) {
                         phi = graph.addWithoutUnique(new GuardPhiNode(merge));
                     } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Thu Dec 07 11:54:55 2017 +0000
@@ -48,6 +48,7 @@
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.SafepointNode;
@@ -213,11 +214,11 @@
             }
             long originalStride = unrollFactor == 1 ? iv.constantStride() : iv.constantStride() / unrollFactor;
             if (iv.direction() == InductionVariable.Direction.Up) {
-                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(), unrollFactor * originalStride));
+                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(NodeView.DEFAULT), unrollFactor * originalStride));
                 ValueNode newLimit = graph.addWithoutUnique(new SubNode(compareBound, aboveVal));
                 compareNode.replaceFirstInput(compareBound, newLimit);
             } else if (iv.direction() == InductionVariable.Direction.Down) {
-                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(), unrollFactor * -originalStride));
+                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(NodeView.DEFAULT), unrollFactor * -originalStride));
                 ValueNode newLimit = graph.addWithoutUnique(new AddNode(compareBound, aboveVal));
                 compareNode.replaceFirstInput(compareBound, newLimit);
             }
@@ -391,7 +392,7 @@
     private static PhiNode patchPhi(StructuredGraph graph, PhiNode phi, AbstractMergeNode merge) {
         PhiNode ret;
         if (phi instanceof ValuePhiNode) {
-            ret = new ValuePhiNode(phi.stamp(), merge);
+            ret = new ValuePhiNode(phi.stamp(NodeView.DEFAULT), merge);
         } else if (phi instanceof GuardPhiNode) {
             ret = new GuardPhiNode(merge);
         } else if (phi instanceof MemoryPhiNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,9 +24,11 @@
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.nodes.FixedNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
+import org.graalvm.compiler.nodes.calc.FixedBinaryNode;
 import org.graalvm.compiler.nodes.calc.SignedDivNode;
 
 /**
@@ -34,11 +36,11 @@
  */
 public class MathUtil {
     private static boolean isConstantOne(ValueNode v1) {
-        return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
+        return v1.isConstant() && v1.stamp(NodeView.DEFAULT) instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
     }
 
     private static boolean isConstantZero(ValueNode v1) {
-        return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
+        return v1.isConstant() && v1.stamp(NodeView.DEFAULT) instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
     }
 
     public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
@@ -48,7 +50,7 @@
         if (isConstantZero(v2)) {
             return v1;
         }
-        return BinaryArithmeticNode.add(graph, v1, v2);
+        return BinaryArithmeticNode.add(graph, v1, v2, NodeView.DEFAULT);
     }
 
     public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
@@ -58,22 +60,24 @@
         if (isConstantOne(v2)) {
             return v1;
         }
-        return BinaryArithmeticNode.mul(graph, v1, v2);
+        return BinaryArithmeticNode.mul(graph, v1, v2, NodeView.DEFAULT);
     }
 
     public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
         if (isConstantZero(v2)) {
             return v1;
         }
-        return BinaryArithmeticNode.sub(graph, v1, v2);
+        return BinaryArithmeticNode.sub(graph, v1, v2, NodeView.DEFAULT);
     }
 
     public static ValueNode divBefore(StructuredGraph graph, FixedNode before, ValueNode dividend, ValueNode divisor) {
         if (isConstantOne(divisor)) {
             return dividend;
         }
-        SignedDivNode div = graph.add(new SignedDivNode(dividend, divisor));
-        graph.addBeforeFixed(before, div);
+        ValueNode div = graph.addOrUniqueWithInputs(SignedDivNode.create(dividend, divisor, NodeView.DEFAULT));
+        if (div instanceof FixedBinaryNode) {
+            graph.addBeforeFixed(before, (FixedBinaryNode) div);
+        }
         return div;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo.processor/src/org/graalvm/compiler/nodeinfo/processor/GraphNodeProcessor.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo.processor/src/org/graalvm/compiler/nodeinfo/processor/GraphNodeProcessor.java	Thu Dec 07 11:54:55 2017 +0000
@@ -103,7 +103,6 @@
     private void reportException(Kind kind, Element element, Throwable t) {
         StringWriter buf = new StringWriter();
         t.printStackTrace(new PrintWriter(buf));
-        buf.toString();
         message(kind, element, "Exception thrown during processing: %s", buf.toString());
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.test.GraphTest;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.options.OptionValues;
@@ -67,52 +68,52 @@
 
     @Test
     public void testBooleanConstant() {
-        assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testByteConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testShortConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testCharConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
-        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testIntConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
-        assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testLongConstant() {
-        assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
-        assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
-        assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
-        assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
-        assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
+        assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/NegateNodeCanonicalizationTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/NegateNodeCanonicalizationTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.options.OptionValues;
@@ -57,7 +58,7 @@
         for (byte i : a) {
             ConstantNode node = ConstantNode.forByte(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -67,7 +68,7 @@
         for (char i : a) {
             ConstantNode node = ConstantNode.forChar(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -77,7 +78,7 @@
         for (short i : a) {
             ConstantNode node = ConstantNode.forShort(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -87,7 +88,7 @@
         for (int i : a) {
             ConstantNode node = ConstantNode.forInt(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -97,7 +98,7 @@
         for (long i : a) {
             ConstantNode node = ConstantNode.forLong(i, graph);
             JavaConstant expected = JavaConstant.forLong(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -107,7 +108,7 @@
         for (float i : a) {
             ConstantNode node = ConstantNode.forFloat(i, graph);
             JavaConstant expected = JavaConstant.forFloat(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -117,7 +118,7 @@
         for (double i : a) {
             ConstantNode node = ConstantNode.forDouble(i, graph);
             JavaConstant expected = JavaConstant.forDouble(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampDoubleToLongTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampDoubleToLongTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -77,9 +79,9 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Long, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Long, param, NodeView.DEFAULT);
 
-        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Long.SIZE, resultStamp.getBits());
 
         for (long result : interestingLongs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampFloatToIntTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampFloatToIntTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -77,10 +79,10 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Int, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Int, param, NodeView.DEFAULT);
         reinterpret.inferStamp();
 
-        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Integer.SIZE, resultStamp.getBits());
 
         for (int result : interestingInts) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampIntToFloatTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampIntToFloatTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,10 +70,10 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Float, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Float, param, NodeView.DEFAULT);
         reinterpret.inferStamp();
 
-        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp();
+        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Float.SIZE, resultStamp.getBits());
 
         for (int input : interestingInts) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampLongToDoubleTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampLongToDoubleTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,10 +70,10 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Double, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Double, param, NodeView.DEFAULT);
         reinterpret.inferStamp();
 
-        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp();
+        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Double.SIZE, resultStamp.getBits());
 
         for (long input : interestingLongs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -68,7 +68,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return mkStamp(newStamp);
     }
 
@@ -124,7 +124,8 @@
             }
 
             ConstantNode constant = (ConstantNode) forValue;
-            return ConstantNode.forConstant(stamp(), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(), tool.getMetaAccess());
+            return ConstantNode.forConstant(stamp(NodeView.DEFAULT), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(),
+                            tool.getMetaAccess());
         } else if (forValue instanceof CompressionNode) {
             CompressionNode other = (CompressionNode) forValue;
             if (op != other.op && encoding.equals(other.encoding)) {
@@ -137,8 +138,8 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         boolean nonNull;
-        if (value.stamp() instanceof AbstractObjectStamp) {
-            nonNull = StampTool.isPointerNonNull(value.stamp());
+        if (value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp) {
+            nonNull = StampTool.isPointerNonNull(value.stamp(NodeView.DEFAULT));
         } else {
             // metaspace pointers are never null
             nonNull = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -134,7 +134,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         if (onlyUsedInVirtualState()) {
             gen.setResult(this, new ConstantValue(kind, value));
         } else {
@@ -525,7 +525,7 @@
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp().unrestricted().toString() + ")";
+            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp(NodeView.DEFAULT).unrestricted().toString() + ")";
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryProxyNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryProxyNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,7 +44,7 @@
     @Input ValueNode value;
 
     public EntryProxyNode(ValueNode value, EntryMarkerNode proxyPoint) {
-        super(TYPE, value.stamp().unrestricted());
+        super(TYPE, value.stamp(NodeView.DEFAULT).unrestricted());
         this.value = value;
         this.proxyPoint = proxyPoint;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -310,7 +310,7 @@
         @Input(InputType.Unchecked) Node proxyPoint;
 
         public ProxyPlaceholder(ValueNode value, MergeNode proxyPoint) {
-            super(TYPE, value.stamp());
+            super(TYPE, value.stamp(NodeView.DEFAULT));
             this.value = value;
             this.proxyPoint = proxyPoint;
         }
@@ -868,7 +868,7 @@
                 /* Now we have two different values, so we need to create a phi node. */
                 PhiNode phi;
                 if (proxy instanceof ValueProxyNode) {
-                    phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(), merge));
+                    phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(NodeView.DEFAULT), merge));
                 } else if (proxy instanceof GuardProxyNode) {
                     phi = graph.addWithoutUnique(new GuardPhiNode(merge));
                 } else {
@@ -1630,7 +1630,7 @@
         List<PhiNode> loopBeginPhis = new ArrayList<>(mergePhis.size());
         for (int i = 0; i < mergePhis.size(); i++) {
             PhiNode mergePhi = mergePhis.get(i);
-            PhiNode loopBeginPhi = graph.addWithoutUnique(new ValuePhiNode(mergePhi.stamp(), loopBegin));
+            PhiNode loopBeginPhi = graph.addWithoutUnique(new ValuePhiNode(mergePhi.stamp(NodeView.DEFAULT), loopBegin));
             mergePhi.replaceAtUsages(loopBeginPhi);
             /*
              * The first input of the new phi function is the original phi function, for the one
@@ -1793,7 +1793,7 @@
             assert irreducibleLoopHandler.header.phis().isEmpty();
 
             /* The new phi function for the loop variable. */
-            loopVariablePhi = graph.addWithoutUnique(new ValuePhiNode(explosionHeadValue.stamp().unrestricted(), irreducibleLoopHandler.header));
+            loopVariablePhi = graph.addWithoutUnique(new ValuePhiNode(explosionHeadValue.stamp(NodeView.DEFAULT).unrestricted(), irreducibleLoopHandler.header));
             for (int i = 0; i < irreducibleLoopHandler.header.phiPredecessorCount(); i++) {
                 loopVariablePhi.addInput(explosionHeadValue);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardedValueNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardedValueNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -53,7 +53,7 @@
     @Input ValueNode object;
 
     public GuardedValueNode(ValueNode object, GuardingNode guard) {
-        super(TYPE, object.stamp(), guard);
+        super(TYPE, object.stamp(NodeView.DEFAULT), guard);
         this.object = object;
     }
 
@@ -70,7 +70,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(object().stamp());
+        return updateStamp(object().stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -84,10 +84,10 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (getGuard() == null) {
-            if (stamp().equals(object().stamp())) {
+            if (stamp(NodeView.DEFAULT).equals(object().stamp(NodeView.DEFAULT))) {
                 return object();
             } else {
-                return PiNode.create(object(), stamp());
+                return PiNode.create(object(), stamp(NodeView.DEFAULT));
             }
         }
         return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -65,7 +65,6 @@
 import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.PrimitiveConstant;
@@ -238,7 +237,7 @@
             if (this.trueSuccessorProbability < probabilityB) {
                 // Reordering of those two if statements is beneficial from the point of view of
                 // their probabilities.
-                if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition())) {
+                if (prepareForSwap(tool, condition(), nextIf.condition())) {
                     // Reordering is allowed from (if1 => begin => if2) to (if2 => begin => if1).
                     assert intermediateBegin.next() == nextIf;
                     AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
@@ -267,19 +266,19 @@
         }
     }
 
-    private boolean isUnboxedFrom(MetaAccessProvider meta, ValueNode x, ValueNode src) {
+    private boolean isUnboxedFrom(MetaAccessProvider meta, NodeView view, ValueNode x, ValueNode src) {
         if (x == src) {
             return true;
         } else if (x instanceof UnboxNode) {
-            return isUnboxedFrom(meta, ((UnboxNode) x).getValue(), src);
+            return isUnboxedFrom(meta, view, ((UnboxNode) x).getValue(), src);
         } else if (x instanceof PiNode) {
             PiNode pi = (PiNode) x;
-            return isUnboxedFrom(meta, pi.getOriginalNode(), src);
+            return isUnboxedFrom(meta, view, pi.getOriginalNode(), src);
         } else if (x instanceof LoadFieldNode) {
             LoadFieldNode load = (LoadFieldNode) x;
             ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
-            if (load.getValue().stamp().javaType(meta).equals(integerType)) {
-                return isUnboxedFrom(meta, load.getValue(), src);
+            if (load.getValue().stamp(view).javaType(meta).equals(integerType)) {
+                return isUnboxedFrom(meta, view, load.getValue(), src);
             } else {
                 return false;
             }
@@ -321,7 +320,8 @@
         ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
 
         // At least one argument for reference equal must be a boxed primitive.
-        if (!x.stamp().javaType(meta).equals(integerType) && !y.stamp().javaType(meta).equals(integerType)) {
+        NodeView view = NodeView.from(tool);
+        if (!x.stamp(view).javaType(meta).equals(integerType) && !y.stamp(view).javaType(meta).equals(integerType)) {
             return false;
         }
 
@@ -366,7 +366,8 @@
                 continue;
             }
             IntegerEqualsNode equals = (IntegerEqualsNode) fixed.condition();
-            if ((isUnboxedFrom(meta, equals.getX(), x) && isUnboxedFrom(meta, equals.getY(), y)) || (isUnboxedFrom(meta, equals.getX(), y) && isUnboxedFrom(meta, equals.getY(), x))) {
+            if ((isUnboxedFrom(meta, view, equals.getX(), x) && isUnboxedFrom(meta, view, equals.getY(), y)) ||
+                            (isUnboxedFrom(meta, view, equals.getX(), y) && isUnboxedFrom(meta, view, equals.getY(), x))) {
                 unboxCheck = fixed;
             }
         }
@@ -406,7 +407,8 @@
             ValueNode falseValue = phi.valueAt(falseEnd);
             ValueNode trueValue = phi.valueAt(trueEnd);
 
-            ValueNode result = ConditionalNode.canonicalizeConditional(condition, trueValue, falseValue, phi.stamp());
+            NodeView view = NodeView.from(tool);
+            ValueNode result = ConditionalNode.canonicalizeConditional(condition, trueValue, falseValue, phi.stamp(view), view);
             if (result != null) {
                 /*
                  * canonicalizeConditional returns possibly new nodes so add them to the graph.
@@ -477,8 +479,9 @@
     private boolean checkForUnsignedCompare(SimplifierTool tool) {
         assert trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages();
         if (condition() instanceof IntegerLessThanNode) {
+            NodeView view = NodeView.from(tool);
             IntegerLessThanNode lessThan = (IntegerLessThanNode) condition();
-            Constant y = lessThan.getY().stamp().asConstant();
+            Constant y = lessThan.getY().stamp(view).asConstant();
             if (y instanceof PrimitiveConstant && ((PrimitiveConstant) y).asLong() == 0 && falseSuccessor().next() instanceof IfNode) {
                 IfNode ifNode2 = (IfNode) falseSuccessor().next();
                 if (ifNode2.condition() instanceof IntegerLessThanNode) {
@@ -490,7 +493,8 @@
                      * Convert x >= 0 && x < positive which is represented as !(x < 0) && x <
                      * <positive> into an unsigned compare.
                      */
-                    if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp() instanceof IntegerStamp && ((IntegerStamp) lessThan2.getY().stamp()).isPositive() &&
+                    if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp(view) instanceof IntegerStamp &&
+                                    ((IntegerStamp) lessThan2.getY().stamp(view)).isPositive() &&
                                     sameDestination(trueSuccessor(), ifNode2.falseSuccessor)) {
                         below = graph().unique(new IntegerBelowNode(lessThan2.getX(), lessThan2.getY()));
                         // swap direction
@@ -506,7 +510,7 @@
                          */
                         JavaConstant positive = lessThan2.getX().asJavaConstant();
                         if (positive != null && positive.asLong() > 0 && positive.asLong() < positive.getJavaKind().getMaxValue()) {
-                            ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(), positive.asLong() + 1, graph());
+                            ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(view), positive.asLong() + 1, graph());
                             below = graph().unique(new IntegerBelowNode(lessThan.getX(), newLimit));
                         }
                     }
@@ -574,7 +578,7 @@
         return false;
     }
 
-    private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b) {
+    private static boolean prepareForSwap(SimplifierTool tool, LogicNode a, LogicNode b) {
         DebugContext debug = a.getDebug();
         if (a instanceof InstanceOfNode) {
             InstanceOfNode instanceOfA = (InstanceOfNode) a;
@@ -625,13 +629,13 @@
                     }
                 } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
                     boolean canSwap = false;
-                    if ((compareA.getX() == compareB.getX() && valuesDistinct(constantReflection, compareA.getY(), compareB.getY()))) {
+                    if ((compareA.getX() == compareB.getX() && valuesDistinct(tool, compareA.getY(), compareB.getY()))) {
                         canSwap = true;
-                    } else if ((compareA.getX() == compareB.getY() && valuesDistinct(constantReflection, compareA.getY(), compareB.getX()))) {
+                    } else if ((compareA.getX() == compareB.getY() && valuesDistinct(tool, compareA.getY(), compareB.getX()))) {
                         canSwap = true;
-                    } else if ((compareA.getY() == compareB.getX() && valuesDistinct(constantReflection, compareA.getX(), compareB.getY()))) {
+                    } else if ((compareA.getY() == compareB.getX() && valuesDistinct(tool, compareA.getX(), compareB.getY()))) {
                         canSwap = true;
-                    } else if ((compareA.getY() == compareB.getY() && valuesDistinct(constantReflection, compareA.getX(), compareB.getX()))) {
+                    } else if ((compareA.getY() == compareB.getY() && valuesDistinct(tool, compareA.getX(), compareB.getX()))) {
                         canSwap = true;
                     }
 
@@ -646,16 +650,17 @@
         return false;
     }
 
-    private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
+    private static boolean valuesDistinct(SimplifierTool tool, ValueNode a, ValueNode b) {
         if (a.isConstant() && b.isConstant()) {
-            Boolean equal = constantReflection.constantEquals(a.asConstant(), b.asConstant());
+            Boolean equal = tool.getConstantReflection().constantEquals(a.asConstant(), b.asConstant());
             if (equal != null) {
                 return !equal.booleanValue();
             }
         }
 
-        Stamp stampA = a.stamp();
-        Stamp stampB = b.stamp();
+        NodeView view = NodeView.from(tool);
+        Stamp stampA = a.stamp(view);
+        Stamp stampB = b.stamp(view);
         return stampA.alwaysDistinct(stampB);
     }
 
@@ -691,7 +696,7 @@
                 } else if (distinct == 1) {
                     ValueNode trueValue = singlePhi.valueAt(trueEnd);
                     ValueNode falseValue = singlePhi.valueAt(falseEnd);
-                    ValueNode conditional = canonicalizeConditionalCascade(trueValue, falseValue);
+                    ValueNode conditional = canonicalizeConditionalCascade(tool, trueValue, falseValue);
                     if (conditional != null) {
                         singlePhi.setValueAt(trueEnd, conditional);
                         removeThroughFalseBranch(tool, merge);
@@ -710,7 +715,7 @@
                 if (trueValue == falseValue) {
                     value = trueValue;
                 } else {
-                    value = canonicalizeConditionalCascade(trueValue, falseValue);
+                    value = canonicalizeConditionalCascade(tool, trueValue, falseValue);
                     if (value == null) {
                         return false;
                     }
@@ -745,7 +750,7 @@
         }
     }
 
-    private ValueNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) {
+    private ValueNode canonicalizeConditionalCascade(SimplifierTool tool, ValueNode trueValue, ValueNode falseValue) {
         if (trueValue.getStackKind() != falseValue.getStackKind()) {
             return null;
         }
@@ -796,8 +801,9 @@
                 }
                 if (lessThan != null) {
                     assert equals != null;
+                    NodeView view = NodeView.from(tool);
                     if ((lessThan.getX() == equals.getX() && lessThan.getY() == equals.getY()) || (lessThan.getX() == equals.getY() && lessThan.getY() == equals.getX())) {
-                        return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp().getStackKind(), false));
+                        return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp(view).getStackKind(), false));
                     }
                 }
             }
@@ -1287,10 +1293,11 @@
                 GraphUtil.killCFG(end);
             } else {
                 // Need a new phi in case the frame state is used by more than the merge being
-                // removed
+                // removed.
+                NodeView view = NodeView.from(tool);
                 AbstractMergeNode newMerge = graph().add(new MergeNode());
                 PhiNode oldPhi = (PhiNode) oldMerge.usages().first();
-                PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(), newMerge));
+                PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(view), newMerge));
 
                 for (EndNode end : ends) {
                     newPhi.addInput(phiValues.get(end));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -342,7 +342,7 @@
         for (int i = 0; i < phi.valueCount(); i++) {
             ValueNode input = phi.valueAt(i);
             long increment = NO_INCREMENT;
-            if (input != null && input instanceof AddNode && input.stamp() instanceof IntegerStamp) {
+            if (input != null && input instanceof AddNode && input.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 AddNode add = (AddNode) input;
                 if (add.getX() == phi && add.getY().isConstant()) {
                     increment = add.getY().asJavaConstant().asLong();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/NodeView.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2017, 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.graalvm.compiler.nodes;
+
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+
+/**
+ * Interface that overrides properties of a node, such as the node's stamp.
+ *
+ * This interface allows richer canonicalizations when the current compilation context can provide a
+ * narrower stamp than the one stored in the node itself. One such example is performing
+ * canonicalization late in the compilation, when the nodes are already scheduled, and benefit from
+ * additional stamp information from conditional checks in branches.
+ *
+ * For example, in the following code, <code>offset + i</code> can be canonicalized once it is
+ * scheduled into the branch:
+ *
+ * <pre>
+ * public void update(int offset, int i) {
+ *     if (i == 0) {
+ *         array[offset + i];
+ *     }
+ * }
+ * </pre>
+ */
+public interface NodeView {
+
+    NodeView DEFAULT = new Default();
+
+    class Default implements NodeView {
+        @Override
+        public Stamp stamp(ValueNode node) {
+            return node.stamp;
+        }
+    }
+
+    /**
+     * Return a view-specific stamp of the node.
+     *
+     * This stamp must be more specific than the default stamp.
+     */
+    Stamp stamp(ValueNode node);
+
+    static NodeView from(CanonicalizerTool tool) {
+        if (tool instanceof NodeView) {
+            return (NodeView) tool;
+        }
+        return DEFAULT;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -152,7 +152,7 @@
 
     public void addInput(ValueNode x) {
         assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
-        assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
+        assert !(this instanceof ValuePhiNode) || x.stamp(NodeView.DEFAULT).isCompatible(stamp(NodeView.DEFAULT));
         values().add(x);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -76,7 +76,7 @@
         super(c, stamp, guard);
         this.object = object;
         this.piStamp = stamp;
-        assert piStamp.isCompatible(object.stamp()) : "Object stamp not compatible to piStamp";
+        assert piStamp.isCompatible(object.stamp(NodeView.DEFAULT)) : "Object stamp not compatible to piStamp";
         inferStamp();
     }
 
@@ -89,11 +89,12 @@
     }
 
     public PiNode(ValueNode object, ValueNode guard) {
-        this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), guard);
+        this(object, AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)), guard);
     }
 
     public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
-        this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), nonNull || StampTool.isPointerNonNull(object.stamp())));
+        this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
+                        nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))));
     }
 
     public static ValueNode create(ValueNode object, Stamp stamp) {
@@ -113,7 +114,7 @@
     }
 
     public static ValueNode create(ValueNode object, ValueNode guard) {
-        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
+        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value != null) {
             return value;
@@ -123,7 +124,7 @@
 
     @SuppressWarnings("unused")
     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
-        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
+        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value == null) {
             value = new PiNode(object, stamp, guard);
@@ -134,7 +135,8 @@
 
     @SuppressWarnings("unused")
     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
-        Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), nonNull || StampTool.isPointerNonNull(object.stamp()));
+        Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
+                        nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)));
         ValueNode value = canonical(object, stamp, null);
         if (value == null) {
             value = new PiNode(object, stamp);
@@ -165,7 +167,7 @@
     }
 
     private Stamp computeStamp() {
-        return piStamp.improveWith(object().stamp());
+        return piStamp.improveWith(object().stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -181,10 +183,10 @@
 
     public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard) {
         // Use most up to date stamp.
-        Stamp computedStamp = stamp.improveWith(object.stamp());
+        Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT));
 
         // The pi node does not give any additional information => skip it.
-        if (computedStamp.equals(object.stamp())) {
+        if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) {
             return object;
         }
 
@@ -192,14 +194,14 @@
             // Try to merge the pi node with a load node.
             if (object instanceof ReadNode) {
                 ReadNode readNode = (ReadNode) object;
-                readNode.setStamp(readNode.stamp().improveWith(stamp));
+                readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp));
                 return readNode;
             }
         } else {
             for (Node n : guard.asNode().usages()) {
                 if (n instanceof PiNode) {
                     PiNode otherPi = (PiNode) n;
-                    if (object == otherPi.object() && computedStamp.equals(otherPi.stamp())) {
+                    if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) {
                         /*
                          * Two PiNodes with the same guard and same result, so return the one with
                          * the more precise piStamp.
@@ -217,7 +219,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        Node value = canonical(object(), stamp(), getGuard());
+        Node value = canonical(object(), stamp(NodeView.DEFAULT), getGuard());
         if (value != null) {
             return value;
         }
@@ -232,7 +234,7 @@
     public void setOriginalNode(ValueNode newNode) {
         this.updateUsages(object, newNode);
         this.object = newNode;
-        assert piStamp.isCompatible(object.stamp()) : "New object stamp not compatible to piStamp";
+        assert piStamp.isCompatible(object.stamp(NodeView.DEFAULT)) : "New object stamp not compatible to piStamp";
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Thu Dec 07 11:54:55 2017 +0000
@@ -360,9 +360,9 @@
             ValueNode result = returnNode.result();
             if (result != null) {
                 if (returnStamp == null) {
-                    returnStamp = result.stamp();
+                    returnStamp = result.stamp(NodeView.DEFAULT);
                 } else {
-                    returnStamp = returnStamp.meet(result.stamp());
+                    returnStamp = returnStamp.meet(result.stamp(NodeView.DEFAULT));
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -56,8 +56,8 @@
         this.stamp = stamp;
     }
 
-    public final Stamp stamp() {
-        return stamp;
+    public final Stamp stamp(NodeView view) {
+        return view.stamp(this);
     }
 
     public final void setStamp(Stamp stamp) {
@@ -99,7 +99,7 @@
     }
 
     public final JavaKind getStackKind() {
-        return stamp().getStackKind();
+        return stamp(NodeView.DEFAULT).getStackKind();
     }
 
     /**
@@ -197,9 +197,9 @@
 
     private boolean checkReplaceAtUsagesInvariants(Node other) {
         assert other == null || other instanceof ValueNode;
-        if (this.hasUsages() && !this.stamp().isEmpty() && !(other instanceof PhiNode) && other != null) {
-            assert ((ValueNode) other).stamp().getClass() == stamp().getClass() : "stamp have to be of same class";
-            boolean morePrecise = ((ValueNode) other).stamp().join(stamp()).equals(((ValueNode) other).stamp());
+        if (this.hasUsages() && !this.stamp(NodeView.DEFAULT).isEmpty() && !(other instanceof PhiNode) && other != null) {
+            assert ((ValueNode) other).stamp(NodeView.DEFAULT).getClass() == stamp(NodeView.DEFAULT).getClass() : "stamp have to be of same class";
+            boolean morePrecise = ((ValueNode) other).stamp(NodeView.DEFAULT).join(stamp(NodeView.DEFAULT)).equals(((ValueNode) other).stamp(NodeView.DEFAULT));
             assert morePrecise : "stamp can only get more precise " + toString(Verbosity.All) + " " +
                             other.toString(Verbosity.All);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -105,11 +105,11 @@
         for (ValueNode input : values()) {
             assert input != null;
             if (s == null) {
-                s = input.stamp();
+                s = input.stamp(NodeView.DEFAULT);
             } else {
-                if (!s.isCompatible(input.stamp())) {
+                if (!s.isCompatible(input.stamp(NodeView.DEFAULT))) {
                     fail("Phi Input Stamps are not compatible. Phi:%s inputs:%s", this,
-                                    CollectionsUtil.mapAndJoin(values(), x -> x.toString() + ":" + x.stamp(), ", "));
+                                    CollectionsUtil.mapAndJoin(values(), x -> x.toString() + ":" + x.stamp(NodeView.DEFAULT), ", "));
                 }
             }
         }
@@ -118,7 +118,7 @@
 
     @Override
     protected String valueDescription() {
-        return stamp().unrestricted().toString();
+        return stamp(NodeView.DEFAULT).unrestricted().toString();
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -41,7 +41,7 @@
     private final boolean loopPhiProxy;
 
     public ValueProxyNode(ValueNode value, LoopExitNode loopExit) {
-        super(TYPE, value.stamp(), loopExit);
+        super(TYPE, value.stamp(NodeView.DEFAULT), loopExit);
         this.value = value;
         loopPhiProxy = loopExit.loopBegin().isPhiAtMerge(value);
     }
@@ -53,7 +53,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(value.stamp());
+        return updateStamp(value.stamp(NodeView.DEFAULT));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -46,6 +47,23 @@
         super(TYPE, ArithmeticOpTable::getAbs, x);
     }
 
+    public static ValueNode create(ValueNode value, NodeView view) {
+        ValueNode synonym = findSynonym(value, view);
+        if (synonym != null) {
+            return synonym;
+        }
+        return new NegateNode(value);
+    }
+
+    protected static ValueNode findSynonym(ValueNode forValue, NodeView view) {
+        ArithmeticOpTable.UnaryOp<Abs> absOp = ArithmeticOpTable.forStamp(forValue.stamp(view)).getAbs();
+        ValueNode synonym = UnaryArithmeticNode.findSynonym(forValue, absOp);
+        if (synonym != null) {
+            return synonym;
+        }
+        return null;
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode ret = super.canonical(tool, forValue);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -51,21 +52,21 @@
         super(c, ArithmeticOpTable::getAdd, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Add> op = ArithmeticOpTable.forStamp(x.stamp()).getAdd();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Add> op = ArithmeticOpTable.forStamp(x.stamp(view)).getAdd();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
         if (x.isConstant() && !y.isConstant()) {
-            return canonical(null, op, y, x);
+            return canonical(null, op, y, x, view);
         } else {
-            return canonical(null, op, x, y);
+            return canonical(null, op, x, y, view);
         }
     }
 
-    private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY, NodeView view) {
         AddNode self = addNode;
         boolean associative = op.isAssociative();
         if (associative) {
@@ -91,16 +92,16 @@
             }
             if (associative && self != null) {
                 // canonicalize expressions like "(a + 1) + 2"
-                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY);
+                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
                 if (reassociated != self) {
                     return reassociated;
                 }
             }
         }
         if (forX instanceof NegateNode) {
-            return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue());
+            return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue(), view);
         } else if (forY instanceof NegateNode) {
-            return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue());
+            return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue(), view);
         }
         if (self == null) {
             self = (AddNode) new AddNode(forX, forY).maybeCommuteInputs();
@@ -125,7 +126,8 @@
             return new AddNode(forY, forX);
         }
         BinaryOp<Add> op = getOp(forX, forY);
-        return canonical(this, op, forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, op, forX, forY, view);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -51,14 +52,14 @@
         super(TYPE, ArithmeticOpTable::getAnd, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<And> op = ArithmeticOpTable.forStamp(x.stamp()).getAnd();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<And> op = ArithmeticOpTable.forStamp(x.stamp(view)).getAnd();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
@@ -68,10 +69,11 @@
             return ret;
         }
 
-        return canonical(this, getOp(forX, forY), stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return forX;
         }
@@ -96,17 +98,17 @@
                         return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
                     }
                 }
-                IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+                IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
                 if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
                     // No bits are set which are outside the mask, so the mask will have no effect.
                     return forX;
                 }
             }
 
-            return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
         }
         if (forX instanceof NotNode && forY instanceof NotNode) {
-            return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue()));
+            return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
         }
         return self != null ? self : new AndNode(forX, forY).maybeCommuteInputs();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -41,6 +41,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ArithmeticOperation;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -60,13 +61,13 @@
     protected final SerializableBinaryFunction<OP> getOp;
 
     protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, SerializableBinaryFunction<OP> getOp, ValueNode x, ValueNode y) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp())).foldStamp(x.stamp(), y.stamp()), x, y);
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
         this.getOp = getOp;
     }
 
     protected final BinaryOp<OP> getOp(ValueNode forX, ValueNode forY) {
-        ArithmeticOpTable table = ArithmeticOpTable.forStamp(forX.stamp());
-        assert table.equals(ArithmeticOpTable.forStamp(forY.stamp()));
+        ArithmeticOpTable table = ArithmeticOpTable.forStamp(forX.stamp(NodeView.DEFAULT));
+        assert table.equals(ArithmeticOpTable.forStamp(forY.stamp(NodeView.DEFAULT)));
         return getOp.apply(table);
     }
 
@@ -81,14 +82,16 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode result = tryConstantFold(getOp(forX, forY), forX, forY, stamp());
+        NodeView view = NodeView.from(tool);
+        ValueNode result = tryConstantFold(getOp(forX, forY), forX, forY, stamp(view), view);
         if (result != null) {
             return result;
         }
         return this;
     }
 
-    public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp) {
+    @SuppressWarnings("unused")
+    public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
         if (forX.isConstant() && forY.isConstant()) {
             Constant ret = op.foldConstant(forX.asConstant(), forY.asConstant());
             if (ret != null) {
@@ -100,32 +103,32 @@
 
     @Override
     public Stamp foldStamp(Stamp stampX, Stamp stampY) {
-        assert stampX.isCompatible(x.stamp()) && stampY.isCompatible(y.stamp());
+        assert stampX.isCompatible(x.stamp(NodeView.DEFAULT)) && stampY.isCompatible(y.stamp(NodeView.DEFAULT));
         return getArithmeticOp().foldStamp(stampX, stampY);
     }
 
-    public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.addOrUniqueWithInputs(AddNode.create(v1, v2));
+    public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2, NodeView view) {
+        return graph.addOrUniqueWithInputs(AddNode.create(v1, v2, view));
     }
 
-    public static ValueNode add(ValueNode v1, ValueNode v2) {
-        return AddNode.create(v1, v2);
+    public static ValueNode add(ValueNode v1, ValueNode v2, NodeView view) {
+        return AddNode.create(v1, v2, view);
     }
 
-    public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.addOrUniqueWithInputs(MulNode.create(v1, v2));
+    public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2, NodeView view) {
+        return graph.addOrUniqueWithInputs(MulNode.create(v1, v2, view));
     }
 
-    public static ValueNode mul(ValueNode v1, ValueNode v2) {
-        return MulNode.create(v1, v2);
+    public static ValueNode mul(ValueNode v1, ValueNode v2, NodeView view) {
+        return MulNode.create(v1, v2, view);
     }
 
-    public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.addOrUniqueWithInputs(SubNode.create(v1, v2));
+    public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2, NodeView view) {
+        return graph.addOrUniqueWithInputs(SubNode.create(v1, v2, view));
     }
 
-    public static ValueNode sub(ValueNode v1, ValueNode v2) {
-        return SubNode.create(v1, v2);
+    public static ValueNode sub(ValueNode v1, ValueNode v2, NodeView view) {
+        return SubNode.create(v1, v2, view);
     }
 
     private enum ReassociateMatch {
@@ -193,7 +196,7 @@
      * @param forY
      * @param forX
      */
-    public static ValueNode reassociate(BinaryArithmeticNode<?> node, NodePredicate criterion, ValueNode forX, ValueNode forY) {
+    public static ValueNode reassociate(BinaryArithmeticNode<?> node, NodePredicate criterion, ValueNode forX, ValueNode forY, NodeView view) {
         assert node.getOp(forX, forY).isAssociative();
         ReassociateMatch match1 = findReassociate(node, criterion);
         if (match1 == null) {
@@ -239,21 +242,21 @@
         if (node instanceof AddNode || node instanceof SubNode) {
             ValueNode associated;
             if (invertM1) {
-                associated = BinaryArithmeticNode.sub(m2, m1);
+                associated = BinaryArithmeticNode.sub(m2, m1, view);
             } else if (invertM2) {
-                associated = BinaryArithmeticNode.sub(m1, m2);
+                associated = BinaryArithmeticNode.sub(m1, m2, view);
             } else {
-                associated = BinaryArithmeticNode.add(m1, m2);
+                associated = BinaryArithmeticNode.add(m1, m2, view);
             }
             if (invertA) {
-                return BinaryArithmeticNode.sub(associated, a);
+                return BinaryArithmeticNode.sub(associated, a, view);
             }
             if (aSub) {
-                return BinaryArithmeticNode.sub(a, associated);
+                return BinaryArithmeticNode.sub(a, associated, view);
             }
-            return BinaryArithmeticNode.add(a, associated);
+            return BinaryArithmeticNode.add(a, associated, view);
         } else if (node instanceof MulNode) {
-            return BinaryArithmeticNode.mul(a, AddNode.mul(m1, m2));
+            return BinaryArithmeticNode.mul(a, AddNode.mul(m1, m2, view), view);
         } else if (node instanceof AndNode) {
             return new AndNode(a, new AndNode(m1, m2));
         } else if (node instanceof OrNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -26,6 +26,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 /**
@@ -73,7 +74,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(foldStamp(getX().stamp(), getY().stamp()));
+        return updateStamp(foldStamp(getX().stamp(NodeView.DEFAULT), getY().stamp(NodeView.DEFAULT)));
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 
@@ -91,7 +92,8 @@
         return null;
     }
 
-    public static LogicNode tryConstantFoldPrimitive(Condition condition, ValueNode forX, ValueNode forY, boolean unorderedIsTrue) {
+    @SuppressWarnings("unused")
+    public static LogicNode tryConstantFoldPrimitive(Condition condition, ValueNode forX, ValueNode forY, boolean unorderedIsTrue, NodeView view) {
         if (forX.asConstant() instanceof PrimitiveConstant && forY.asConstant() instanceof PrimitiveConstant) {
             return LogicConstantNode.forBoolean(condition.foldCondition((PrimitiveConstant) forX.asConstant(), (PrimitiveConstant) forY.asConstant(), unorderedIsTrue));
         }
@@ -110,27 +112,27 @@
 
     public abstract static class CompareOp {
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
             LogicNode constantCondition = tryConstantFold(condition, forX, forY, constantReflection, unorderedIsTrue);
             if (constantCondition != null) {
                 return constantCondition;
             }
             LogicNode result;
             if (forX.isConstant()) {
-                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forX.asConstant(), forY, true, unorderedIsTrue)) != null) {
+                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forX.asConstant(), forY, true, unorderedIsTrue, view)) != null) {
                     return result;
                 }
             } else if (forY.isConstant()) {
-                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forY.asConstant(), forX, false, unorderedIsTrue)) != null) {
+                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forY.asConstant(), forX, false, unorderedIsTrue, view)) != null) {
                     return result;
                 }
             } else if (forX instanceof ConvertNode && forY instanceof ConvertNode) {
                 ConvertNode convertX = (ConvertNode) forX;
                 ConvertNode convertY = (ConvertNode) forY;
-                if (convertX.preservesOrder(condition) && convertY.preservesOrder(condition) && convertX.getValue().stamp().isCompatible(convertY.getValue().stamp())) {
+                if (convertX.preservesOrder(condition) && convertY.preservesOrder(condition) && convertX.getValue().stamp(view).isCompatible(convertY.getValue().stamp(view))) {
                     boolean supported = true;
-                    if (convertX.getValue().stamp() instanceof IntegerStamp) {
-                        IntegerStamp intStamp = (IntegerStamp) convertX.getValue().stamp();
+                    if (convertX.getValue().stamp(view) instanceof IntegerStamp) {
+                        IntegerStamp intStamp = (IntegerStamp) convertX.getValue().stamp(view);
                         supported = smallestCompareWidth != null && intStamp.getBits() >= smallestCompareWidth;
                     }
 
@@ -141,7 +143,7 @@
                             // of the value.
                             return null;
                         }
-                        return duplicateModified(convertX.getValue(), convertY.getValue(), unorderedIsTrue);
+                        return duplicateModified(convertX.getValue(), convertY.getValue(), unorderedIsTrue, view);
                     }
                 }
             }
@@ -149,11 +151,11 @@
         }
 
         protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) {
+                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue, NodeView view) {
             if (nonConstant instanceof ConditionalNode) {
                 return optimizeConditional(constant, (ConditionalNode) nonConstant, constantReflection, mirrored ? condition.mirror() : condition, unorderedIsTrue);
             } else if (nonConstant instanceof NormalizeCompareNode) {
-                return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored);
+                return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored, view);
             } else if (nonConstant instanceof ConvertNode) {
                 ConvertNode convert = (ConvertNode) nonConstant;
                 boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage());
@@ -164,18 +166,18 @@
                 }
 
                 boolean supported = true;
-                if (convert.getValue().stamp() instanceof IntegerStamp) {
-                    IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp();
+                if (convert.getValue().stamp(view) instanceof IntegerStamp) {
+                    IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp(view);
                     supported = smallestCompareWidth != null && intStamp.getBits() > smallestCompareWidth;
                 }
 
                 if (supported) {
-                    ConstantNode newConstant = canonicalConvertConstant(constantReflection, metaAccess, options, condition, convert, constant);
+                    ConstantNode newConstant = canonicalConvertConstant(constantReflection, metaAccess, options, condition, convert, constant, view);
                     if (newConstant != null) {
                         if (mirrored) {
-                            return duplicateModified(newConstant, convert.getValue(), unorderedIsTrue);
+                            return duplicateModified(newConstant, convert.getValue(), unorderedIsTrue, view);
                         } else {
-                            return duplicateModified(convert.getValue(), newConstant, unorderedIsTrue);
+                            return duplicateModified(convert.getValue(), newConstant, unorderedIsTrue, view);
                         }
                     }
                 }
@@ -185,7 +187,7 @@
         }
 
         private static ConstantNode canonicalConvertConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Condition condition,
-                        ConvertNode convert, Constant constant) {
+                        ConvertNode convert, Constant constant, NodeView view) {
             if (convert.preservesOrder(condition, constant, constantReflection)) {
                 Constant reverseConverted = convert.reverse(constant, constantReflection);
                 if (reverseConverted != null && convert.convert(reverseConverted, constantReflection).equals(constant)) {
@@ -193,7 +195,7 @@
                         // We always want uncompressed constants
                         return null;
                     }
-                    return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, metaAccess);
+                    return ConstantNode.forConstant(convert.getValue().stamp(view), reverseConverted, metaAccess);
                 }
             }
             return null;
@@ -201,7 +203,7 @@
 
         @SuppressWarnings("unused")
         protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) {
             throw new GraalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored);
         }
 
@@ -230,71 +232,71 @@
             return null;
         }
 
-        protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue);
+        protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue, NodeView view);
     }
 
-    public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
-        LogicNode result = createCompareNode(condition, x, y, constantReflection);
+    public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) {
+        LogicNode result = createCompareNode(condition, x, y, constantReflection, view);
         return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result);
     }
 
-    public static LogicNode createCompareNode(Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
+    public static LogicNode createCompareNode(Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) {
         assert x.getStackKind() == y.getStackKind();
         assert condition.isCanonical();
         assert !x.getStackKind().isNumericFloat();
 
         LogicNode comparison;
         if (condition == Condition.EQ) {
-            if (x.stamp() instanceof AbstractObjectStamp) {
-                comparison = ObjectEqualsNode.create(x, y, constantReflection);
-            } else if (x.stamp() instanceof AbstractPointerStamp) {
-                comparison = PointerEqualsNode.create(x, y);
+            if (x.stamp(view) instanceof AbstractObjectStamp) {
+                comparison = ObjectEqualsNode.create(x, y, constantReflection, view);
+            } else if (x.stamp(view) instanceof AbstractPointerStamp) {
+                comparison = PointerEqualsNode.create(x, y, view);
             } else {
                 assert x.getStackKind().isNumericInteger();
-                comparison = IntegerEqualsNode.create(x, y);
+                comparison = IntegerEqualsNode.create(x, y, view);
             }
         } else if (condition == Condition.LT) {
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerLessThanNode.create(x, y);
+            comparison = IntegerLessThanNode.create(x, y, view);
         } else {
             assert condition == Condition.BT;
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerBelowNode.create(x, y);
+            comparison = IntegerBelowNode.create(x, y, view);
         }
 
         return comparison;
     }
 
     public static LogicNode createCompareNode(StructuredGraph graph, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    Condition condition, ValueNode x, ValueNode y) {
-        LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y);
+                    Condition condition, ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y, view);
         return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result);
     }
 
     public static LogicNode createCompareNode(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    Condition condition, ValueNode x, ValueNode y) {
+                    Condition condition, ValueNode x, ValueNode y, NodeView view) {
         assert x.getStackKind() == y.getStackKind();
         assert condition.isCanonical();
         assert !x.getStackKind().isNumericFloat();
 
         LogicNode comparison;
         if (condition == Condition.EQ) {
-            if (x.stamp() instanceof AbstractObjectStamp) {
+            if (x.stamp(view) instanceof AbstractObjectStamp) {
                 assert smallestCompareWidth == null;
-                comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y);
-            } else if (x.stamp() instanceof AbstractPointerStamp) {
-                comparison = PointerEqualsNode.create(x, y);
+                comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, view);
+            } else if (x.stamp(view) instanceof AbstractPointerStamp) {
+                comparison = PointerEqualsNode.create(x, y, view);
             } else {
                 assert x.getStackKind().isNumericInteger();
-                comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y);
+                comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view);
             }
         } else if (condition == Condition.LT) {
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y);
+            comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view);
         } else {
             assert condition == Condition.BT;
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y);
+            comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view);
         }
 
         return comparison;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -55,8 +56,8 @@
 
     public static final NodeClass<ConditionalNode> TYPE = NodeClass.create(ConditionalNode.class);
     @Input(InputType.Condition) LogicNode condition;
-    @Input ValueNode trueValue;
-    @Input ValueNode falseValue;
+    @Input(InputType.Value) ValueNode trueValue;
+    @Input(InputType.Value) ValueNode falseValue;
 
     public LogicNode condition() {
         return condition;
@@ -67,23 +68,23 @@
     }
 
     public ConditionalNode(LogicNode condition, ValueNode trueValue, ValueNode falseValue) {
-        super(TYPE, trueValue.stamp().meet(falseValue.stamp()));
-        assert trueValue.stamp().isCompatible(falseValue.stamp());
+        super(TYPE, trueValue.stamp(NodeView.DEFAULT).meet(falseValue.stamp(NodeView.DEFAULT)));
+        assert trueValue.stamp(NodeView.DEFAULT).isCompatible(falseValue.stamp(NodeView.DEFAULT));
         this.condition = condition;
         this.trueValue = trueValue;
         this.falseValue = falseValue;
     }
 
-    public static ValueNode create(LogicNode condition) {
-        return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph()));
+    public static ValueNode create(LogicNode condition, NodeView view) {
+        return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph()), view);
     }
 
-    public static ValueNode create(LogicNode condition, ValueNode trueValue, ValueNode falseValue) {
-        ValueNode synonym = findSynonym(condition, trueValue, falseValue);
+    public static ValueNode create(LogicNode condition, ValueNode trueValue, ValueNode falseValue, NodeView view) {
+        ValueNode synonym = findSynonym(condition, trueValue, falseValue, view);
         if (synonym != null) {
             return synonym;
         }
-        ValueNode result = canonicalizeConditional(condition, trueValue, falseValue, trueValue.stamp().meet(falseValue.stamp()));
+        ValueNode result = canonicalizeConditional(condition, trueValue, falseValue, trueValue.stamp(view).meet(falseValue.stamp(view)), view);
         if (result != null) {
             return result;
         }
@@ -92,7 +93,7 @@
 
     @Override
     public boolean inferStamp() {
-        Stamp valueStamp = trueValue.stamp().meet(falseValue.stamp());
+        Stamp valueStamp = trueValue.stamp(NodeView.DEFAULT).meet(falseValue.stamp(NodeView.DEFAULT));
         if (condition instanceof IntegerLessThanNode) {
             IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
             if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
@@ -130,12 +131,13 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode synonym = findSynonym(condition, trueValue(), falseValue());
+        NodeView view = NodeView.from(tool);
+        ValueNode synonym = findSynonym(condition, trueValue(), falseValue(), view);
         if (synonym != null) {
             return synonym;
         }
 
-        ValueNode result = canonicalizeConditional(condition, trueValue(), falseValue(), stamp);
+        ValueNode result = canonicalizeConditional(condition, trueValue(), falseValue(), stamp, view);
         if (result != null) {
             return result;
         }
@@ -143,7 +145,7 @@
         return this;
     }
 
-    public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp) {
+    public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp, NodeView view) {
         if (trueValue == falseValue) {
             return trueValue;
         }
@@ -156,12 +158,12 @@
             }
         }
 
-        if (trueValue.stamp() instanceof IntegerStamp) {
+        if (trueValue.stamp(view) instanceof IntegerStamp) {
             // check if the conditional is redundant
             if (condition instanceof IntegerLessThanNode) {
                 IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
-                IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp();
-                IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp();
+                IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp(view);
+                IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp(view);
                 if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
                     // return "x" for "x < y ? x : y" in case that we know "x <= y"
                     if (trueValueStamp.upperBound() <= falseValueStamp.lowerBound()) {
@@ -182,25 +184,25 @@
                 long constFalseValue = falseValue.asJavaConstant().asLong();
                 if (condition instanceof IntegerEqualsNode) {
                     IntegerEqualsNode equals = (IntegerEqualsNode) condition;
-                    if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
-                        IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
+                    if (equals.getY().isConstant() && equals.getX().stamp(view) instanceof IntegerStamp) {
+                        IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp(view);
                         if (equalsXStamp.upMask() == 1) {
                             long equalsY = equals.getY().asJavaConstant().asLong();
                             if (equalsY == 0) {
                                 if (constTrueValue == 0 && constFalseValue == 1) {
                                     // return x when: x == 0 ? 0 : 1;
-                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp, view);
                                 } else if (constTrueValue == 1 && constFalseValue == 0) {
                                     // negate a boolean value via xor
-                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(view), 1), view), stamp, view);
                                 }
                             } else if (equalsY == 1) {
                                 if (constTrueValue == 1 && constFalseValue == 0) {
                                     // return x when: x == 1 ? 1 : 0;
-                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp, view);
                                 } else if (constTrueValue == 0 && constFalseValue == 1) {
                                     // negate a boolean value via xor
-                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(view), 1), view), stamp, view);
                                 }
                             }
                         }
@@ -211,10 +213,10 @@
                     // (value & 1) == 1 ? 1 : 0
                     IntegerTestNode integerTestNode = (IntegerTestNode) condition;
                     if (integerTestNode.getY().isConstant()) {
-                        assert integerTestNode.getX().stamp() instanceof IntegerStamp;
+                        assert integerTestNode.getX().stamp(view) instanceof IntegerStamp;
                         long testY = integerTestNode.getY().asJavaConstant().asLong();
                         if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
-                            return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
+                            return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY(), view), stamp, view);
                         }
                     }
                 }
@@ -231,7 +233,7 @@
                         if (trueValue instanceof AddNode) {
                             AddNode add = (AddNode) trueValue;
                             if (add.getX() == falseValue) {
-                                int bits = ((IntegerStamp) trueValue.stamp()).getBits();
+                                int bits = ((IntegerStamp) trueValue.stamp(NodeView.DEFAULT)).getBits();
                                 ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
                                 ValueNode and = new AndNode(shift, add.getY());
                                 return new AddNode(add.getX(), and);
@@ -245,10 +247,10 @@
         return null;
     }
 
-    private static ValueNode findSynonym(ValueNode condition, ValueNode trueValue, ValueNode falseValue) {
+    private static ValueNode findSynonym(ValueNode condition, ValueNode trueValue, ValueNode falseValue, NodeView view) {
         if (condition instanceof LogicNegationNode) {
             LogicNegationNode negated = (LogicNegationNode) condition;
-            return ConditionalNode.create(negated.getValue(), falseValue, trueValue);
+            return ConditionalNode.create(negated.getValue(), falseValue, trueValue, view);
         }
         if (condition instanceof LogicConstantNode) {
             LogicConstantNode c = (LogicConstantNode) condition;
@@ -267,6 +269,6 @@
     }
 
     public ConditionalNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) {
-        this(createCompareNode(graph, condition, x, y, null));
+        this(createCompareNode(graph, condition, x, y, null, NodeView.DEFAULT));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -65,8 +66,8 @@
         this.op = op;
     }
 
-    public static ValueNode create(FloatConvert op, ValueNode input) {
-        ValueNode synonym = findSynonym(input, ArithmeticOpTable.forStamp(input.stamp()).getFloatConvert(op));
+    public static ValueNode create(FloatConvert op, ValueNode input, NodeView view) {
+        ValueNode synonym = findSynonym(input, ArithmeticOpTable.forStamp(input.stamp(view)).getFloatConvert(op));
         if (synonym != null) {
             return synonym;
         }
@@ -84,7 +85,7 @@
 
     @Override
     public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) {
-        FloatConvertOp reverse = ArithmeticOpTable.forStamp(stamp()).getFloatConvert(op.reverse());
+        FloatConvertOp reverse = ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)).getFloatConvert(op.reverse());
         return reverse.foldConstant(c);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -53,10 +54,10 @@
         assert stamp instanceof FloatStamp;
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp(view)).getDiv();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
@@ -50,12 +51,12 @@
 
     public FloatEqualsNode(ValueNode x, ValueNode y) {
         super(TYPE, Condition.EQ, false, x, y);
-        assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp : x.stamp() + " " + y.stamp();
-        assert x.stamp().isCompatible(y.stamp());
+        assert x.stamp(NodeView.DEFAULT) instanceof FloatStamp && y.stamp(NodeView.DEFAULT) instanceof FloatStamp : x.stamp(NodeView.DEFAULT) + " " + y.stamp(NodeView.DEFAULT);
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false, view);
         if (result != null) {
             return result;
         } else {
@@ -64,18 +65,18 @@
     }
 
     public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y);
+                    ValueNode x, ValueNode y, NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public boolean isIdentityComparison() {
-        FloatStamp xStamp = (FloatStamp) x.stamp();
-        FloatStamp yStamp = (FloatStamp) y.stamp();
+        FloatStamp xStamp = (FloatStamp) x.stamp(NodeView.DEFAULT);
+        FloatStamp yStamp = (FloatStamp) y.stamp(NodeView.DEFAULT);
         /*
          * If both stamps have at most one 0.0 and it's the same 0.0 then this is an identity
          * comparison. FloatStamp isn't careful about tracking the presence of -0.0 so assume that
@@ -87,7 +88,8 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, unorderedIsTrue, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, unorderedIsTrue, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -98,13 +100,13 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
             if (result != null) {
                 return result;
             }
-            Stamp xStampGeneric = forX.stamp();
-            Stamp yStampGeneric = forY.stamp();
+            Stamp xStampGeneric = forX.stamp(view);
+            Stamp yStampGeneric = forY.stamp(view);
             if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) {
                 FloatStamp xStamp = (FloatStamp) xStampGeneric;
                 FloatStamp yStamp = (FloatStamp) yStampGeneric;
@@ -118,10 +120,10 @@
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof FloatStamp && newY.stamp(view) instanceof FloatStamp) {
                 return new FloatEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(view) instanceof IntegerStamp && newY.stamp(view) instanceof IntegerStamp) {
                 return new IntegerEqualsNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
@@ -49,12 +50,12 @@
 
     public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
         super(TYPE, Condition.LT, unorderedIsTrue, x, y);
-        assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp;
-        assert x.stamp().isCompatible(y.stamp());
+        assert x.stamp(NodeView.DEFAULT) instanceof FloatStamp && y.stamp(NodeView.DEFAULT) instanceof FloatStamp;
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
-        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.LT, x, y, unorderedIsTrue);
+    public static LogicNode create(ValueNode x, ValueNode y, boolean unorderedIsTrue, NodeView view) {
+        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.LT, x, y, unorderedIsTrue, view);
         if (result != null) {
             return result;
         }
@@ -62,17 +63,18 @@
     }
 
     public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    ValueNode x, ValueNode y, boolean unorderedIsTrue) {
-        LogicNode result = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.LT, unorderedIsTrue, x, y);
+                    ValueNode x, ValueNode y, boolean unorderedIsTrue, NodeView view) {
+        LogicNode result = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.LT, unorderedIsTrue, x, y, view);
         if (result != null) {
             return result;
         }
-        return create(x, y, unorderedIsTrue);
+        return create(x, y, unorderedIsTrue, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.LT, unorderedIsTrue, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.LT, unorderedIsTrue, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -83,8 +85,8 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
             if (result != null) {
                 return result;
             }
@@ -95,10 +97,10 @@
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(NodeView.DEFAULT) instanceof FloatStamp && newY.stamp(NodeView.DEFAULT) instanceof FloatStamp) {
                 return new FloatLessThanNode(newX, newY, unorderedIsTrue);
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(NodeView.DEFAULT) instanceof IntegerStamp && newY.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 return new IntegerLessThanNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -45,25 +46,27 @@
 
     public IntegerBelowNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y, OP);
-        assert x.stamp() instanceof IntegerStamp;
-        assert y.stamp() instanceof IntegerStamp;
+        assert x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
+        assert y.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        return OP.create(x, y);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        return OP.create(x, y, view);
     }
 
-    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y);
+    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y,
+                    NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -72,8 +75,8 @@
 
     public static class BelowOp extends LowerOp {
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            assert newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp;
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            assert newX.stamp(NodeView.DEFAULT) instanceof IntegerStamp && newY.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
             return new IntegerBelowNode(newX, newY);
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ArithmeticOperation;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -61,12 +62,12 @@
 
     protected IntegerConvertNode(NodeClass<? extends IntegerConvertNode<OP, REV>> c, SerializableIntegerConvertFunction<OP> getOp, SerializableIntegerConvertFunction<REV> getReverseOp, int inputBits,
                     int resultBits, ValueNode input) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(input.stamp())).foldStamp(inputBits, resultBits, input.stamp()), input);
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(input.stamp(NodeView.DEFAULT))).foldStamp(inputBits, resultBits, input.stamp(NodeView.DEFAULT)), input);
         this.getOp = getOp;
         this.getReverseOp = getReverseOp;
         this.inputBits = inputBits;
         this.resultBits = resultBits;
-        assert ((PrimitiveStamp) input.stamp()).getBits() == inputBits;
+        assert ((PrimitiveStamp) input.stamp(NodeView.DEFAULT)).getBits() == inputBits;
     }
 
     public int getInputBits() {
@@ -78,7 +79,7 @@
     }
 
     protected final IntegerConvertOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp()));
+        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
     }
 
     @Override
@@ -93,19 +94,19 @@
 
     @Override
     public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) {
-        IntegerConvertOp<REV> reverse = getReverseOp.apply(ArithmeticOpTable.forStamp(stamp()));
+        IntegerConvertOp<REV> reverse = getReverseOp.apply(ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)));
         return reverse.foldConstant(getResultBits(), getInputBits(), c);
     }
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return getArithmeticOp().foldStamp(inputBits, resultBits, newStamp);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        ValueNode synonym = findSynonym(getOp(forValue), forValue, inputBits, resultBits, stamp());
+        ValueNode synonym = findSynonym(getOp(forValue), forValue, inputBits, resultBits, stamp(NodeView.DEFAULT));
         if (synonym != null) {
             return synonym;
         }
@@ -121,12 +122,12 @@
         return null;
     }
 
-    public static ValueNode convert(ValueNode input, Stamp stamp) {
-        return convert(input, stamp, false);
+    public static ValueNode convert(ValueNode input, Stamp stamp, NodeView view) {
+        return convert(input, stamp, false, view);
     }
 
-    public static ValueNode convert(ValueNode input, Stamp stamp, StructuredGraph graph) {
-        ValueNode convert = convert(input, stamp, false);
+    public static ValueNode convert(ValueNode input, Stamp stamp, StructuredGraph graph, NodeView view) {
+        ValueNode convert = convert(input, stamp, false, view);
         if (!convert.isAlive()) {
             assert !convert.isDeleted();
             convert = graph.addOrUniqueWithInputs(convert);
@@ -134,12 +135,12 @@
         return convert;
     }
 
-    public static ValueNode convertUnsigned(ValueNode input, Stamp stamp) {
-        return convert(input, stamp, true);
+    public static ValueNode convertUnsigned(ValueNode input, Stamp stamp, NodeView view) {
+        return convert(input, stamp, true, view);
     }
 
-    public static ValueNode convert(ValueNode input, Stamp stamp, boolean zeroExtend) {
-        IntegerStamp fromStamp = (IntegerStamp) input.stamp();
+    public static ValueNode convert(ValueNode input, Stamp stamp, boolean zeroExtend, NodeView view) {
+        IntegerStamp fromStamp = (IntegerStamp) input.stamp(view);
         IntegerStamp toStamp = (IntegerStamp) stamp;
 
         ValueNode result;
@@ -149,13 +150,13 @@
             result = new NarrowNode(input, fromStamp.getBits(), toStamp.getBits());
         } else if (zeroExtend) {
             // toStamp.getBits() > fromStamp.getBits()
-            result = ZeroExtendNode.create(input, toStamp.getBits());
+            result = ZeroExtendNode.create(input, toStamp.getBits(), view);
         } else {
             // toStamp.getBits() > fromStamp.getBits()
-            result = SignExtendNode.create(input, toStamp.getBits());
+            result = SignExtendNode.create(input, toStamp.getBits(), view);
         }
 
-        IntegerStamp resultStamp = (IntegerStamp) result.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) result.stamp(view);
         assert toStamp.getBits() == resultStamp.getBits();
         return result;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -59,7 +60,7 @@
 
         // Assigning canDeopt during constructor, because it must never change during lifetime of
         // the node.
-        this.canDeopt = ((IntegerStamp) getY().stamp()).contains(0);
+        this.canDeopt = ((IntegerStamp) getY().stamp(NodeView.DEFAULT)).contains(0);
     }
 
     public final Op getOp() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 
@@ -59,8 +60,8 @@
         assert !y.getStackKind().isNumericFloat() && y.getStackKind() != JavaKind.Object;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false, view);
         if (result != null) {
             return result;
         }
@@ -84,17 +85,19 @@
         return new IntegerEqualsNode(x, y).maybeCommuteInputs();
     }
 
-    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y);
+    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y,
+                    NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -104,7 +107,7 @@
     public static class IntegerEqualsOp extends CompareOp {
         @Override
         protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) {
             PrimitiveConstant primitive = (PrimitiveConstant) constant;
             ValueNode a = normalizeNode.getX();
             ValueNode b = normalizeNode.getY();
@@ -112,21 +115,21 @@
 
             if (cst == 0) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 } else {
-                    return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 }
             } else if (cst == 1) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatLessThanNode.create(b, a, !normalizeNode.isUnorderedLess);
+                    return FloatLessThanNode.create(b, a, !normalizeNode.isUnorderedLess, view);
                 } else {
-                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a);
+                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, view);
                 }
             } else if (cst == -1) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatLessThanNode.create(a, b, normalizeNode.isUnorderedLess);
+                    return FloatLessThanNode.create(a, b, normalizeNode.isUnorderedLess, view);
                 } else {
-                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 }
             } else {
                 return LogicConstantNode.contradiction();
@@ -134,12 +137,12 @@
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof FloatStamp && newY.stamp(view) instanceof FloatStamp) {
                 return new FloatEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(view) instanceof IntegerStamp && newY.stamp(view) instanceof IntegerStamp) {
                 return new IntegerEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) {
+            } else if (newX.stamp(view) instanceof AbstractPointerStamp && newY.stamp(view) instanceof AbstractPointerStamp) {
                 return new IntegerEqualsNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
@@ -147,10 +150,10 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
             if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
                 return LogicConstantNode.tautology();
-            } else if (forX.stamp().alwaysDistinct(forY.stamp())) {
+            } else if (forX.stamp(view).alwaysDistinct(forY.stamp(view))) {
                 return LogicConstantNode.contradiction();
             }
 
@@ -174,19 +177,19 @@
                 }
                 if (v1 != null) {
                     assert v2 != null;
-                    return create(v1, v2);
+                    return create(v1, v2, view);
                 }
             }
 
-            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
         }
 
         @Override
         protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) {
+                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue, NodeView view) {
             if (constant instanceof PrimitiveConstant) {
                 PrimitiveConstant primitiveConstant = (PrimitiveConstant) constant;
-                IntegerStamp nonConstantStamp = ((IntegerStamp) nonConstant.stamp());
+                IntegerStamp nonConstantStamp = ((IntegerStamp) nonConstant.stamp(view));
                 if ((primitiveConstant.asLong() == 1 && nonConstantStamp.upperBound() == 1 && nonConstantStamp.lowerBound() == 0) ||
                                 (primitiveConstant.asLong() == -1 && nonConstantStamp.upperBound() == 0 && nonConstantStamp.lowerBound() == -1)) {
                     // nonConstant can only be 0 or 1 (respective -1), test against 0 instead of 1
@@ -194,15 +197,16 @@
                     // execution
                     // on specific platforms.
                     return LogicNegationNode.create(
-                                    IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, nonConstant, ConstantNode.forIntegerKind(nonConstant.getStackKind(), 0)));
+                                    IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, nonConstant, ConstantNode.forIntegerKind(nonConstant.getStackKind(), 0),
+                                                    view));
                 } else if (primitiveConstant.asLong() == 0) {
                     if (nonConstant instanceof AndNode) {
                         AndNode andNode = (AndNode) nonConstant;
                         return new IntegerTestNode(andNode.getX(), andNode.getY());
                     } else if (nonConstant instanceof SubNode) {
                         SubNode subNode = (SubNode) nonConstant;
-                        return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, subNode.getX(), subNode.getY());
-                    } else if (nonConstant instanceof ShiftNode && nonConstant.stamp() instanceof IntegerStamp) {
+                        return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, subNode.getX(), subNode.getY(), view);
+                    } else if (nonConstant instanceof ShiftNode && nonConstant.stamp(view) instanceof IntegerStamp) {
                         if (nonConstant instanceof LeftShiftNode) {
                             LeftShiftNode shift = (LeftShiftNode) nonConstant;
                             if (shift.getY().isConstant()) {
@@ -217,7 +221,7 @@
                             }
                         } else if (nonConstant instanceof RightShiftNode) {
                             RightShiftNode shift = (RightShiftNode) nonConstant;
-                            if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp()).isPositive()) {
+                            if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp(view)).isPositive()) {
                                 int mask = shift.getShiftAmountMask();
                                 int amount = shift.getY().asJavaConstant().asInt() & mask;
                                 if (shift.getX().getStackKind() == JavaKind.Int) {
@@ -258,16 +262,16 @@
                     }
                 }
 
-                if (nonConstant instanceof XorNode && nonConstant.stamp() instanceof IntegerStamp) {
+                if (nonConstant instanceof XorNode && nonConstant.stamp(view) instanceof IntegerStamp) {
                     XorNode xorNode = (XorNode) nonConstant;
-                    if (xorNode.getY().isJavaConstant() && xorNode.getY().asJavaConstant().asLong() == 1 && ((IntegerStamp) xorNode.getX().stamp()).upMask() == 1) {
+                    if (xorNode.getY().isJavaConstant() && xorNode.getY().asJavaConstant().asLong() == 1 && ((IntegerStamp) xorNode.getX().stamp(view)).upMask() == 1) {
                         // x ^ 1 == 0 is the same as x == 1 if x in [0, 1]
                         // x ^ 1 == 1 is the same as x == 0 if x in [0, 1]
-                        return new IntegerEqualsNode(xorNode.getX(), ConstantNode.forIntegerStamp(xorNode.getX().stamp(), primitiveConstant.asLong() ^ 1));
+                        return new IntegerEqualsNode(xorNode.getX(), ConstantNode.forIntegerStamp(xorNode.getX().stamp(view), primitiveConstant.asLong() ^ 1));
                     }
                 }
             }
-            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue);
+            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue, view);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -60,22 +61,23 @@
         assert !y.getStackKind().isNumericFloat() && y.getStackKind() != JavaKind.Object;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        return OP.create(x, y);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        return OP.create(x, y, view);
     }
 
     public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y);
+                    ValueNode x, ValueNode y, NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -98,11 +100,11 @@
 
     public static class LessThanOp extends LowerOp {
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof FloatStamp && newY.stamp(view) instanceof FloatStamp) {
                 return new FloatLessThanNode(newX, newY, unorderedIsTrue); // TODO: Is the last arg
                                                                            // supposed to be true?
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(view) instanceof IntegerStamp && newY.stamp(view) instanceof IntegerStamp) {
                 return new IntegerLessThanNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
@@ -110,7 +112,7 @@
 
         @Override
         protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) {
             PrimitiveConstant primitive = (PrimitiveConstant) constant;
             /* @formatter:off
              * a NC b < c  (not mirrored)
@@ -138,18 +140,18 @@
 
             if (cst == 0) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, mirrored ^ normalizeNode.isUnorderedLess);
+                    return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, mirrored ^ normalizeNode.isUnorderedLess, view);
                 } else {
-                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 }
             } else if (cst == 1) {
                 // a <= b <=> !(a > b)
                 LogicNode compare;
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
                     // since we negate, we have to reverse the unordered result
-                    compare = FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, mirrored == normalizeNode.isUnorderedLess);
+                    compare = FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, mirrored == normalizeNode.isUnorderedLess, view);
                 } else {
-                    compare = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a);
+                    compare = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, view);
                 }
                 return LogicNegationNode.create(compare);
             } else if (cst <= -1) {
@@ -161,13 +163,13 @@
         }
 
         @Override
-        protected LogicNode findSynonym(ValueNode forX, ValueNode forY) {
-            LogicNode result = super.findSynonym(forX, forY);
+        protected LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.findSynonym(forX, forY, view);
             if (result != null) {
                 return result;
             }
-            if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
-                if (IntegerStamp.sameSign((IntegerStamp) forX.stamp(), (IntegerStamp) forY.stamp())) {
+            if (forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) {
+                if (IntegerStamp.sameSign((IntegerStamp) forX.stamp(view), (IntegerStamp) forY.stamp(view))) {
                     return new IntegerBelowNode(forX, forY);
                 }
             }
@@ -188,8 +190,8 @@
                 }
                 if (xx != null) {
                     assert yy != null;
-                    IntegerStamp xStamp = (IntegerStamp) sub.getX().stamp();
-                    IntegerStamp yStamp = (IntegerStamp) sub.getY().stamp();
+                    IntegerStamp xStamp = (IntegerStamp) sub.getX().stamp(view);
+                    IntegerStamp yStamp = (IntegerStamp) sub.getY().stamp(view);
                     long minValue = CodeUtil.minValue(xStamp.getBits());
                     long maxValue = CodeUtil.maxValue(xStamp.getBits());
 
@@ -203,10 +205,10 @@
                 }
             }
 
-            if (forX.stamp() instanceof IntegerStamp) {
-                assert forY.stamp() instanceof IntegerStamp;
-                int bits = ((IntegerStamp) forX.stamp()).getBits();
-                assert ((IntegerStamp) forY.stamp()).getBits() == bits;
+            if (forX.stamp(view) instanceof IntegerStamp) {
+                assert forY.stamp(view) instanceof IntegerStamp;
+                int bits = ((IntegerStamp) forX.stamp(view)).getBits();
+                assert ((IntegerStamp) forY.stamp(view)).getBits() == bits;
                 long min = OP.minValue(bits);
                 long xResidue = 0;
                 ValueNode left = null;
@@ -240,12 +242,12 @@
                             if (left == null) {
                                 left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
                             } else if (xResidue != 0) {
-                                left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+                                left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue), view);
                             }
                             if (right == null) {
                                 right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
                             } else if (yResidue != 0) {
-                                right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
+                                right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue), view);
                             }
                             return new IntegerBelowNode(left, right);
                         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 
@@ -76,12 +77,12 @@
             IntegerStamp xStamp = (IntegerStamp) xStampGeneric;
             AddNode addNode = (AddNode) forY;
             IntegerStamp aStamp = null;
-            if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
+            if (addNode.getX() == forX && addNode.getY().stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 // x < x + a
-                aStamp = (IntegerStamp) addNode.getY().stamp();
-            } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
+                aStamp = (IntegerStamp) addNode.getY().stamp(NodeView.DEFAULT);
+            } else if (addNode.getY() == forX && addNode.getX().stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 // x < a + x
-                aStamp = (IntegerStamp) addNode.getX().stamp();
+                aStamp = (IntegerStamp) addNode.getX().stamp(NodeView.DEFAULT);
             }
             if (aStamp != null) {
                 IntegerStamp result = getOp().getSucceedingStampForXLowerXPlusA(mirror, strict, aStamp);
@@ -117,12 +118,12 @@
     public abstract static class LowerOp extends CompareOp {
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
             if (result != null) {
                 return result;
             }
-            LogicNode synonym = findSynonym(forX, forY);
+            LogicNode synonym = findSynonym(forX, forY, view);
             if (synonym != null) {
                 return synonym;
             }
@@ -159,12 +160,12 @@
 
         protected abstract IntegerLowerThanNode createNode(ValueNode x, ValueNode y);
 
-        public LogicNode create(ValueNode x, ValueNode y) {
-            LogicNode result = CompareNode.tryConstantFoldPrimitive(getCondition(), x, y, false);
+        public LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+            LogicNode result = CompareNode.tryConstantFoldPrimitive(getCondition(), x, y, false, view);
             if (result != null) {
                 return result;
             } else {
-                result = findSynonym(x, y);
+                result = findSynonym(x, y, view);
                 if (result != null) {
                     return result;
                 }
@@ -172,47 +173,47 @@
             }
         }
 
-        protected LogicNode findSynonym(ValueNode forX, ValueNode forY) {
+        protected LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) {
             if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
                 return LogicConstantNode.contradiction();
             }
-            TriState fold = tryFold(forX.stamp(), forY.stamp());
+            TriState fold = tryFold(forX.stamp(view), forY.stamp(view));
             if (fold.isTrue()) {
                 return LogicConstantNode.tautology();
             } else if (fold.isFalse()) {
                 return LogicConstantNode.contradiction();
             }
-            if (forY.stamp() instanceof IntegerStamp) {
-                IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+            if (forY.stamp(view) instanceof IntegerStamp) {
+                IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
                 int bits = yStamp.getBits();
                 if (forX.isJavaConstant() && !forY.isConstant()) {
                     // bring the constant on the right
                     long xValue = forX.asJavaConstant().asLong();
                     if (xValue != maxValue(bits)) {
                         // c < x <=> !(c >= x) <=> !(x <= c) <=> !(x < c + 1)
-                        return LogicNegationNode.create(create(forY, ConstantNode.forIntegerStamp(yStamp, xValue + 1)));
+                        return LogicNegationNode.create(create(forY, ConstantNode.forIntegerStamp(yStamp, xValue + 1), view));
                     }
                 }
                 if (forY.isJavaConstant()) {
                     long yValue = forY.asJavaConstant().asLong();
                     if (yValue == maxValue(bits)) {
                         // x < MAX <=> x != MAX
-                        return LogicNegationNode.create(IntegerEqualsNode.create(forX, forY));
+                        return LogicNegationNode.create(IntegerEqualsNode.create(forX, forY, view));
                     }
                     if (yValue == minValue(bits) + 1) {
                         // x < MIN + 1 <=> x <= MIN <=> x == MIN
-                        return IntegerEqualsNode.create(forX, ConstantNode.forIntegerStamp(yStamp, minValue(bits)));
+                        return IntegerEqualsNode.create(forX, ConstantNode.forIntegerStamp(yStamp, minValue(bits)), view);
                     }
                 } else if (forY instanceof AddNode) {
                     AddNode addNode = (AddNode) forY;
-                    LogicNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true);
+                    LogicNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true, view);
                     if (canonical != null) {
                         return canonical;
                     }
                 }
                 if (forX instanceof AddNode) {
                     AddNode addNode = (AddNode) forX;
-                    LogicNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false);
+                    LogicNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false, view);
                     if (canonical != null) {
                         return canonical;
                     }
@@ -221,32 +222,32 @@
             return null;
         }
 
-        private LogicNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean mirrored, boolean strict) {
+        private LogicNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean mirrored, boolean strict, NodeView view) {
             // x < x + a
             IntegerStamp succeedingXStamp;
             boolean exact;
-            if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
-                IntegerStamp aStamp = (IntegerStamp) addNode.getY().stamp();
+            if (addNode.getX() == forX && addNode.getY().stamp(view) instanceof IntegerStamp) {
+                IntegerStamp aStamp = (IntegerStamp) addNode.getY().stamp(view);
                 succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
                 exact = aStamp.lowerBound() == aStamp.upperBound();
-            } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
-                IntegerStamp aStamp = (IntegerStamp) addNode.getX().stamp();
+            } else if (addNode.getY() == forX && addNode.getX().stamp(view) instanceof IntegerStamp) {
+                IntegerStamp aStamp = (IntegerStamp) addNode.getX().stamp(view);
                 succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
                 exact = aStamp.lowerBound() == aStamp.upperBound();
             } else {
                 return null;
             }
-            if (succeedingXStamp.join(forX.stamp()).isEmpty()) {
+            if (succeedingXStamp.join(forX.stamp(view)).isEmpty()) {
                 return LogicConstantNode.contradiction();
             } else if (exact && !succeedingXStamp.isEmpty()) {
                 int bits = succeedingXStamp.getBits();
                 if (compare(lowerBound(succeedingXStamp), minValue(bits)) > 0) {
                     assert upperBound(succeedingXStamp) == maxValue(bits);
                     // x must be in [L..MAX] <=> x >= L <=> !(x < L)
-                    return LogicNegationNode.create(create(forX, ConstantNode.forIntegerStamp(succeedingXStamp, lowerBound(succeedingXStamp))));
+                    return LogicNegationNode.create(create(forX, ConstantNode.forIntegerStamp(succeedingXStamp, lowerBound(succeedingXStamp)), view));
                 } else if (compare(upperBound(succeedingXStamp), maxValue(bits)) < 0) {
                     // x must be in [MIN..H] <=> x <= H <=> !(H < x)
-                    return LogicNegationNode.create(create(ConstantNode.forIntegerStamp(succeedingXStamp, upperBound(succeedingXStamp)), forX));
+                    return LogicNegationNode.create(create(ConstantNode.forIntegerStamp(succeedingXStamp, upperBound(succeedingXStamp)), forX, view));
                 }
             }
             return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.TriState;
@@ -52,12 +53,13 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         if (forX.isConstant() && forY.isConstant()) {
             return LogicConstantNode.forBoolean((forX.asJavaConstant().asLong() & forY.asJavaConstant().asLong()) == 0);
         }
-        if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
-            IntegerStamp xStamp = (IntegerStamp) forX.stamp();
-            IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+        if (forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) {
+            IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
+            IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
             if ((xStamp.upMask() & yStamp.upMask()) == 0) {
                 return LogicConstantNode.tautology();
             } else if ((xStamp.downMask() & yStamp.downMask()) != 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -77,7 +78,7 @@
     @Override
     public boolean verify() {
         assertTrue(getValue() != null, "is null input must not be null");
-        assertTrue(getValue().stamp() instanceof AbstractPointerStamp, "input must be a pointer not %s", getValue().stamp());
+        assertTrue(getValue().stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp, "input must be a pointer not %s", getValue().stamp(NodeView.DEFAULT));
         return super.verify();
     }
 
@@ -113,7 +114,7 @@
     @Override
     public void virtualize(VirtualizerTool tool) {
         ValueNode alias = tool.getAlias(getValue());
-        TriState fold = tryFold(alias.stamp());
+        TriState fold = tryFold(alias.stamp(NodeView.DEFAULT));
         if (fold != TriState.UNKNOWN) {
             tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph()));
         }
@@ -122,7 +123,7 @@
     @Override
     public Stamp getSucceedingStampForValue(boolean negated) {
         // Ignore any more precise input stamp since canonicalization will skip through PiNodes
-        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp().unrestricted();
+        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp(NodeView.DEFAULT).unrestricted();
         return negated ? pointerStamp.asNonNull() : pointerStamp.asAlwaysNull();
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -45,10 +46,10 @@
         super(TYPE, ArithmeticOpTable::getShl, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        ArithmeticOpTable.ShiftOp<Shl> op = ArithmeticOpTable.forStamp(x.stamp()).getShl();
-        Stamp stamp = op.foldStamp(x.stamp(), (IntegerStamp) y.stamp());
-        ValueNode value = ShiftNode.canonical(op, stamp, x, y);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        ArithmeticOpTable.ShiftOp<Shl> op = ArithmeticOpTable.forStamp(x.stamp(view)).getShl();
+        Stamp stamp = op.foldStamp(x.stamp(view), (IntegerStamp) y.stamp(view));
+        ValueNode value = ShiftNode.canonical(op, stamp, x, y, view);
         if (value != null) {
             return value;
         }
@@ -63,7 +64,7 @@
             return ret;
         }
 
-        return canonical(this, getArithmeticOp(), stamp(), forX, forY);
+        return canonical(this, getArithmeticOp(), stamp(NodeView.DEFAULT), forX, forY);
     }
 
     private static ValueNode canonical(LeftShiftNode leftShiftNode, ArithmeticOpTable.ShiftOp<Shl> op, Stamp stamp, ValueNode forX, ValueNode forY) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -56,14 +57,14 @@
         super(c, ArithmeticOpTable::getMul, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Mul> op = ArithmeticOpTable.forStamp(x.stamp()).getMul();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Mul> op = ArithmeticOpTable.forStamp(x.stamp(view)).getMul();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
@@ -83,10 +84,11 @@
             return new MulNode(forY, forX);
         }
         BinaryOp<Mul> op = getOp(forX, forY);
-        return canonical(this, op, stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, op, stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(MulNode self, BinaryOp<Mul> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(MulNode self, BinaryOp<Mul> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (forY.isConstant()) {
             Constant c = forY.asConstant();
             if (op.isNeutral(c)) {
@@ -95,57 +97,64 @@
 
             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
                 long i = ((PrimitiveConstant) c).asLong();
-
-                if (i == 0) {
-                    return ConstantNode.forIntegerStamp(stamp, 0);
-                } else if (i == 1) {
-                    return forX;
-                } else if (i == -1) {
-                    return NegateNode.create(forX);
-                } else if (i > 0) {
-                    if (CodeUtil.isPowerOf2(i)) {
-                        return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
-                    } else if (CodeUtil.isPowerOf2(i - 1)) {
-                        return AddNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i - 1))), forX);
-                    } else if (CodeUtil.isPowerOf2(i + 1)) {
-                        return SubNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))), forX);
-                    } else {
-                        int bitCount = Long.bitCount(i);
-                        long highestBitValue = Long.highestOneBit(i);
-                        if (bitCount == 2) {
-                            // e.g., 0b1000_0010
-                            long lowerBitValue = i - highestBitValue;
-                            assert highestBitValue > 0 && lowerBitValue > 0;
-                            ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(highestBitValue)));
-                            ValueNode right = lowerBitValue == 1 ? forX : new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(lowerBitValue)));
-                            return AddNode.create(left, right);
-                        } else {
-                            // e.g., 0b1111_1101
-                            int shiftToRoundUpToPowerOf2 = CodeUtil.log2(highestBitValue) + 1;
-                            long subValue = (1 << shiftToRoundUpToPowerOf2) - i;
-                            if (CodeUtil.isPowerOf2(subValue) && shiftToRoundUpToPowerOf2 < ((IntegerStamp) stamp).getBits()) {
-                                assert CodeUtil.log2(subValue) >= 1;
-                                ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(shiftToRoundUpToPowerOf2));
-                                ValueNode right = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(subValue)));
-                                return SubNode.create(left, right);
-                            }
-                        }
-                    }
-                } else if (i < 0) {
-                    if (CodeUtil.isPowerOf2(-i)) {
-                        return NegateNode.create(LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(-i))));
-                    }
+                ValueNode result = canonical(stamp, forX, i, view);
+                if (result != null) {
+                    return result;
                 }
             }
 
             if (op.isAssociative()) {
                 // canonicalize expressions like "(a * 1) * 2"
-                return reassociate(self != null ? self : (MulNode) new MulNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+                return reassociate(self != null ? self : (MulNode) new MulNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
             }
         }
         return self != null ? self : new MulNode(forX, forY).maybeCommuteInputs();
     }
 
+    public static ValueNode canonical(Stamp stamp, ValueNode forX, long i, NodeView view) {
+        if (i == 0) {
+            return ConstantNode.forIntegerStamp(stamp, 0);
+        } else if (i == 1) {
+            return forX;
+        } else if (i == -1) {
+            return NegateNode.create(forX, view);
+        } else if (i > 0) {
+            if (CodeUtil.isPowerOf2(i)) {
+                return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
+            } else if (CodeUtil.isPowerOf2(i - 1)) {
+                return AddNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i - 1))), forX, view);
+            } else if (CodeUtil.isPowerOf2(i + 1)) {
+                return SubNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))), forX, view);
+            } else {
+                int bitCount = Long.bitCount(i);
+                long highestBitValue = Long.highestOneBit(i);
+                if (bitCount == 2) {
+                    // e.g., 0b1000_0010
+                    long lowerBitValue = i - highestBitValue;
+                    assert highestBitValue > 0 && lowerBitValue > 0;
+                    ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(highestBitValue)));
+                    ValueNode right = lowerBitValue == 1 ? forX : new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(lowerBitValue)));
+                    return AddNode.create(left, right, view);
+                } else {
+                    // e.g., 0b1111_1101
+                    int shiftToRoundUpToPowerOf2 = CodeUtil.log2(highestBitValue) + 1;
+                    long subValue = (1 << shiftToRoundUpToPowerOf2) - i;
+                    if (CodeUtil.isPowerOf2(subValue) && shiftToRoundUpToPowerOf2 < ((IntegerStamp) stamp).getBits()) {
+                        assert CodeUtil.log2(subValue) >= 1;
+                        ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(shiftToRoundUpToPowerOf2));
+                        ValueNode right = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(subValue)));
+                        return SubNode.create(left, right, view);
+                    }
+                }
+            }
+        } else if (i < 0) {
+            if (CodeUtil.isPowerOf2(-i)) {
+                return NegateNode.create(LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(-i)), view), view);
+            }
+        }
+        return null;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
         Value op1 = nodeValueMap.operand(getX());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -48,21 +49,21 @@
     public static final NodeClass<NarrowNode> TYPE = NodeClass.create(NarrowNode.class);
 
     public NarrowNode(ValueNode input, int resultBits) {
-        this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
-        assert 0 < resultBits && resultBits <= PrimitiveStamp.getBits(input.stamp());
+        this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
+        assert 0 < resultBits && resultBits <= PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT));
     }
 
     public NarrowNode(ValueNode input, int inputBits, int resultBits) {
         super(TYPE, ArithmeticOpTable::getNarrow, ArithmeticOpTable::getSignExtend, inputBits, resultBits, input);
     }
 
-    public static ValueNode create(ValueNode input, int resultBits) {
-        return create(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
+    public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
+        return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
     }
 
-    public static ValueNode create(ValueNode input, int inputBits, int resultBits) {
-        IntegerConvertOp<Narrow> signExtend = ArithmeticOpTable.forStamp(input.stamp()).getNarrow();
-        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp()));
+    public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
+        IntegerConvertOp<Narrow> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getNarrow();
+        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
         if (synonym != null) {
             return synonym;
         } else {
@@ -77,6 +78,7 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
@@ -108,7 +110,7 @@
                 if (other instanceof SignExtendNode) {
                     // sxxx -(sign-extend)-> ssssssss sssssxxx -(narrow)-> sssssxxx
                     // ==> sxxx -(sign-extend)-> sssssxxx
-                    return SignExtendNode.create(other.getValue(), other.getInputBits(), getResultBits());
+                    return SignExtendNode.create(other.getValue(), other.getInputBits(), getResultBits(), view);
                 } else if (other instanceof ZeroExtendNode) {
                     // xxxx -(zero-extend)-> 00000000 00000xxx -(narrow)-> 0000xxxx
                     // ==> xxxx -(zero-extend)-> 0000xxxx
@@ -117,13 +119,13 @@
             }
         } else if (forValue instanceof AndNode) {
             AndNode andNode = (AndNode) forValue;
-            IntegerStamp yStamp = (IntegerStamp) andNode.getY().stamp();
-            IntegerStamp xStamp = (IntegerStamp) andNode.getX().stamp();
+            IntegerStamp yStamp = (IntegerStamp) andNode.getY().stamp(view);
+            IntegerStamp xStamp = (IntegerStamp) andNode.getX().stamp(view);
             long relevantMask = CodeUtil.mask(this.getResultBits());
             if ((relevantMask & yStamp.downMask()) == relevantMask) {
-                return create(andNode.getX(), this.getResultBits());
+                return create(andNode.getX(), this.getResultBits(), view);
             } else if ((relevantMask & xStamp.downMask()) == relevantMask) {
-                return create(andNode.getY(), this.getResultBits());
+                return create(andNode.getY(), this.getResultBits(), view);
             }
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.spi.StampInverter;
@@ -49,8 +50,8 @@
         super(TYPE, ArithmeticOpTable::getNeg, value);
     }
 
-    public static ValueNode create(ValueNode value) {
-        ValueNode synonym = findSynonym(value);
+    public static ValueNode create(ValueNode value, NodeView view) {
+        ValueNode synonym = findSynonym(value, view);
         if (synonym != null) {
             return synonym;
         }
@@ -66,8 +67,8 @@
         return this;
     }
 
-    protected static ValueNode findSynonym(ValueNode forValue) {
-        ArithmeticOpTable.UnaryOp<Neg> negOp = ArithmeticOpTable.forStamp(forValue.stamp()).getNeg();
+    protected static ValueNode findSynonym(ValueNode forValue, NodeView view) {
+        ArithmeticOpTable.UnaryOp<Neg> negOp = ArithmeticOpTable.forStamp(forValue.stamp(view)).getNeg();
         ValueNode synonym = UnaryArithmeticNode.findSynonym(forValue, negOp);
         if (synonym != null) {
             return synonym;
@@ -75,9 +76,9 @@
         if (forValue instanceof NegateNode) {
             return ((NegateNode) forValue).getValue();
         }
-        if (forValue instanceof SubNode && !(forValue.stamp() instanceof FloatStamp)) {
+        if (forValue instanceof SubNode && !(forValue.stamp(view) instanceof FloatStamp)) {
             SubNode sub = (SubNode) forValue;
-            return SubNode.create(sub.getY(), sub.getX());
+            return SubNode.create(sub.getY(), sub.getX(), view);
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
@@ -86,7 +87,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode result = tryConstantFold(x, y, isUnorderedLess, stamp().getStackKind(), tool.getConstantReflection());
+        NodeView view = NodeView.from(tool);
+        ValueNode result = tryConstantFold(x, y, isUnorderedLess, stamp(view).getStackKind(), tool.getConstantReflection());
         if (result != null) {
             return result;
         }
@@ -100,7 +102,7 @@
 
     @Override
     public Stamp foldStamp(Stamp stampX, Stamp stampY) {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 
     public boolean isUnorderedLess() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -45,20 +45,31 @@
 
     public static final NodeClass<NotNode> TYPE = NodeClass.create(NotNode.class);
 
-    public NotNode(ValueNode x) {
+    protected NotNode(ValueNode x) {
         super(TYPE, ArithmeticOpTable::getNot, x);
     }
 
+    public static ValueNode create(ValueNode x) {
+        return canonicalize(null, x);
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
         }
-        if (forValue instanceof NotNode) {
-            return ((NotNode) forValue).getValue();
+        return canonicalize(this, forValue);
+    }
+
+    private static ValueNode canonicalize(NotNode node, ValueNode x) {
+        if (x instanceof NotNode) {
+            return ((NotNode) x).getValue();
         }
-        return this;
+        if (node != null) {
+            return node;
+        }
+        return new NotNode(x);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.GetClassNode;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
@@ -58,16 +59,16 @@
 
     public ObjectEqualsNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        assert x.stamp() instanceof AbstractObjectStamp;
-        assert y.stamp() instanceof AbstractObjectStamp;
+        assert x.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
+        assert y.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
+    public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) {
         LogicNode result = CompareNode.tryConstantFold(Condition.EQ, x, y, constantReflection, false);
         if (result != null) {
             return result;
         } else {
-            result = findSynonym(x, y);
+            result = findSynonym(x, y, view);
             if (result != null) {
                 return result;
             }
@@ -75,17 +76,18 @@
         }
     }
 
-    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, ValueNode x, ValueNode y) {
-        LogicNode result = OP.canonical(constantReflection, metaAccess, options, null, Condition.EQ, false, x, y);
+    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = OP.canonical(constantReflection, metaAccess, options, null, Condition.EQ, false, x, y, view);
         if (result != null) {
             return result;
         }
-        return create(x, y, constantReflection);
+        return create(x, y, constantReflection, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -96,25 +98,25 @@
 
         @Override
         protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) {
+                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue, NodeView view) {
             ResolvedJavaType type = constantReflection.asJavaType(constant);
             if (type != null && nonConstant instanceof GetClassNode) {
                 GetClassNode getClassNode = (GetClassNode) nonConstant;
                 ValueNode object = getClassNode.getObject();
-                assert ((ObjectStamp) object.stamp()).nonNull();
+                assert ((ObjectStamp) object.stamp(view)).nonNull();
                 if (!type.isPrimitive() && (type.isConcrete() || type.isArray())) {
                     return InstanceOfNode.create(TypeReference.createExactTrusted(type), object);
                 }
                 return LogicConstantNode.forBoolean(false);
             }
-            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue);
+            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue, view);
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof ObjectStamp && newY.stamp() instanceof ObjectStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof ObjectStamp && newY.stamp(view) instanceof ObjectStamp) {
                 return new ObjectEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) {
+            } else if (newX.stamp(view) instanceof AbstractPointerStamp && newY.stamp(view) instanceof AbstractPointerStamp) {
                 return new PointerEqualsNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -50,27 +51,28 @@
         super(TYPE, ArithmeticOpTable::getOr, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp()).getOr();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(view)).getOr();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, getOp(forX, forY), stamp(), forX, forY);
+        return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return forX;
         }
@@ -90,10 +92,10 @@
                     return ConstantNode.forIntegerStamp(stamp, mask);
                 }
             }
-            return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
         }
         if (forX instanceof NotNode && forY instanceof NotNode) {
-            return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue()));
+            return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
         }
         return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
 import org.graalvm.compiler.nodes.extended.LoadMethodNode;
@@ -56,8 +57,8 @@
         this(TYPE, x, y);
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        LogicNode result = findSynonym(x, y);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = findSynonym(x, y, view);
         if (result != null) {
             return result;
         }
@@ -66,13 +67,14 @@
 
     protected PointerEqualsNode(NodeClass<? extends PointerEqualsNode> c, ValueNode x, ValueNode y) {
         super(c, Condition.EQ, false, x, y);
-        assert x.stamp() instanceof AbstractPointerStamp;
-        assert y.stamp() instanceof AbstractPointerStamp;
+        assert x.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
+        assert y.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -111,31 +113,31 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = findSynonym(forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = findSynonym(forX, forY, view);
             if (result != null) {
                 return result;
             }
             if (isAlwaysFailingVirtualDispatchTest(condition, forX, forY)) {
                 return LogicConstantNode.contradiction();
             }
-            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
             return new PointerEqualsNode(newX, newY);
         }
     }
 
-    public static LogicNode findSynonym(ValueNode forX, ValueNode forY) {
+    public static LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return LogicConstantNode.tautology();
-        } else if (forX.stamp().alwaysDistinct(forY.stamp())) {
+        } else if (forX.stamp(view).alwaysDistinct(forY.stamp(view))) {
             return LogicConstantNode.contradiction();
-        } else if (((AbstractPointerStamp) forX.stamp()).alwaysNull()) {
+        } else if (((AbstractPointerStamp) forX.stamp(view)).alwaysNull()) {
             return IsNullNode.create(forY);
-        } else if (((AbstractPointerStamp) forY.stamp()).alwaysNull()) {
+        } else if (((AbstractPointerStamp) forY.stamp(view)).alwaysNull()) {
             return IsNullNode.create(forX);
         } else {
             return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -56,16 +57,24 @@
 
     public static final NodeClass<ReinterpretNode> TYPE = NodeClass.create(ReinterpretNode.class);
 
-    public ReinterpretNode(JavaKind to, ValueNode value) {
+    protected ReinterpretNode(JavaKind to, ValueNode value) {
         this(StampFactory.forKind(to), value);
     }
 
-    public ReinterpretNode(Stamp to, ValueNode value) {
-        super(TYPE, getReinterpretStamp(to, value.stamp()), value);
+    protected ReinterpretNode(Stamp to, ValueNode value) {
+        super(TYPE, getReinterpretStamp(to, value.stamp(NodeView.DEFAULT)), value);
         assert to instanceof ArithmeticStamp;
     }
 
-    private SerializableConstant evalConst(SerializableConstant c) {
+    public static ValueNode create(JavaKind to, ValueNode value, NodeView view) {
+        return create(StampFactory.forKind(to), value, view);
+    }
+
+    public static ValueNode create(Stamp to, ValueNode value, NodeView view) {
+        return canonical(null, to, value, view);
+    }
+
+    private static SerializableConstant evalConst(Stamp stamp, SerializableConstant c) {
         /*
          * We don't care about byte order here. Either would produce the correct result.
          */
@@ -73,7 +82,7 @@
         c.serialize(buffer);
 
         buffer.rewind();
-        SerializableConstant ret = ((ArithmeticStamp) stamp()).deserialize(buffer);
+        SerializableConstant ret = ((ArithmeticStamp) stamp).deserialize(buffer);
 
         assert !buffer.hasRemaining();
         return ret;
@@ -81,17 +90,22 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
+        return canonical(this, this.stamp(view), forValue, view);
+    }
+
+    public static ValueNode canonical(ReinterpretNode node, Stamp forStamp, ValueNode forValue, NodeView view) {
         if (forValue.isConstant()) {
-            return ConstantNode.forConstant(stamp(), evalConst((SerializableConstant) forValue.asConstant()), null);
+            return ConstantNode.forConstant(forStamp, evalConst(forStamp, (SerializableConstant) forValue.asConstant()), null);
         }
-        if (stamp().isCompatible(forValue.stamp())) {
+        if (forStamp.isCompatible(forValue.stamp(view))) {
             return forValue;
         }
         if (forValue instanceof ReinterpretNode) {
             ReinterpretNode reinterpret = (ReinterpretNode) forValue;
-            return new ReinterpretNode(stamp(), reinterpret.getValue());
+            return new ReinterpretNode(forStamp, reinterpret.getValue());
         }
-        return this;
+        return node != null ? node : new ReinterpretNode(forStamp, forValue);
     }
 
     /**
@@ -269,12 +283,12 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(getReinterpretStamp(stamp(), getValue().stamp()));
+        return updateStamp(getReinterpretStamp(stamp(NodeView.DEFAULT), getValue().stamp(NodeView.DEFAULT)));
     }
 
     @Override
     public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) {
-        LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         builder.setResult(this, gen.emitReinterpret(kind, builder.operand(getValue())));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,10 +25,14 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Rem;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -39,7 +43,7 @@
 
     public static final NodeClass<RemNode> TYPE = NodeClass.create(RemNode.class);
 
-    public RemNode(ValueNode x, ValueNode y) {
+    protected RemNode(ValueNode x, ValueNode y) {
         this(TYPE, x, y);
     }
 
@@ -47,6 +51,16 @@
         super(c, ArithmeticOpTable::getRem, x, y);
     }
 
+    public static ValueNode create(ValueNode forX, ValueNode forY, NodeView view) {
+        BinaryOp<Rem> op = ArithmeticOpTable.forStamp(forX.stamp(view)).getRem();
+        Stamp stamp = op.foldStamp(forX.stamp(view), forY.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, forX, forY, stamp, view);
+        if (tryConstantFold != null) {
+            return tryConstantFold;
+        }
+        return new RemNode(forX, forY);
+    }
+
     @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -45,30 +46,31 @@
         super(TYPE, ArithmeticOpTable::getShr, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        ArithmeticOpTable.ShiftOp<Shr> op = ArithmeticOpTable.forStamp(x.stamp()).getShr();
-        Stamp stamp = op.foldStamp(x.stamp(), (IntegerStamp) y.stamp());
-        ValueNode value = ShiftNode.canonical(op, stamp, x, y);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        ArithmeticOpTable.ShiftOp<Shr> op = ArithmeticOpTable.forStamp(x.stamp(view)).getShr();
+        Stamp stamp = op.foldStamp(x.stamp(view), (IntegerStamp) y.stamp(view));
+        ValueNode value = ShiftNode.canonical(op, stamp, x, y, view);
         if (value != null) {
             return value;
         }
 
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, getArithmeticOp(), stamp(), forX, forY);
+        return canonical(this, getArithmeticOp(), stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(RightShiftNode rightShiftNode, ArithmeticOpTable.ShiftOp<Shr> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(RightShiftNode rightShiftNode, ArithmeticOpTable.ShiftOp<Shr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         RightShiftNode self = rightShiftNode;
-        if (forX.stamp() instanceof IntegerStamp && ((IntegerStamp) forX.stamp()).isPositive()) {
+        if (forX.stamp(view) instanceof IntegerStamp && ((IntegerStamp) forX.stamp(view)).isPositive()) {
             return new UnsignedRightShiftNode(forX, forY);
         }
 
@@ -87,8 +89,8 @@
                     if (other instanceof RightShiftNode) {
                         int total = amount + otherAmount;
                         if (total != (total & mask)) {
-                            assert other.getX().stamp() instanceof IntegerStamp;
-                            IntegerStamp istamp = (IntegerStamp) other.getX().stamp();
+                            assert other.getX().stamp(view) instanceof IntegerStamp;
+                            IntegerStamp istamp = (IntegerStamp) other.getX().stamp(view);
 
                             if (istamp.isPositive()) {
                                 return ConstantNode.forIntegerKind(stamp.getStackKind(), 0);
@@ -131,7 +133,7 @@
              * are all equal to the sign bit of the input. That's equivalent to the condition that
              * the input is in the signed range of the narrow type.
              */
-            IntegerStamp inputStamp = (IntegerStamp) getX().stamp();
+            IntegerStamp inputStamp = (IntegerStamp) getX().stamp(NodeView.DEFAULT);
             return CodeUtil.minValue(resultBits) <= inputStamp.lowerBound() && inputStamp.upperBound() <= CodeUtil.maxValue(resultBits);
         } else {
             return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ArithmeticOperation;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 
@@ -64,13 +65,13 @@
      * @param s the second input value
      */
     protected ShiftNode(NodeClass<? extends ShiftNode<OP>> c, SerializableShiftFunction<OP> getOp, ValueNode x, ValueNode s) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp())).foldStamp(x.stamp(), (IntegerStamp) s.stamp()), x, s);
-        assert ((IntegerStamp) s.stamp()).getBits() == 32;
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), (IntegerStamp) s.stamp(NodeView.DEFAULT)), x, s);
+        assert ((IntegerStamp) s.stamp(NodeView.DEFAULT)).getBits() == 32;
         this.getOp = getOp;
     }
 
     protected final ShiftOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp()));
+        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
     }
 
     @Override
@@ -85,14 +86,16 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode valueNode = canonical(getOp(forX), stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode valueNode = canonical(getOp(forX), stamp(NodeView.DEFAULT), forX, forY, view);
         if (valueNode != null) {
             return valueNode;
         }
         return this;
     }
 
-    public static <OP> ValueNode canonical(ShiftOp<OP> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    @SuppressWarnings("unused")
+    public static <OP> ValueNode canonical(ShiftOp<OP> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (forX.isConstant() && forY.isConstant()) {
             JavaConstant amount = forY.asJavaConstant();
             assert amount.getJavaKind() == JavaKind.Int;
@@ -102,7 +105,7 @@
     }
 
     public int getShiftAmountMask() {
-        return getArithmeticOp().getShiftAmountMask(stamp());
+        return getArithmeticOp().getShiftAmountMask(stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -117,7 +120,7 @@
          * amount. We can narrow only if (y & wideMask) == (y & narrowMask) for all possible values
          * of y.
          */
-        IntegerStamp yStamp = (IntegerStamp) getY().stamp();
+        IntegerStamp yStamp = (IntegerStamp) getY().stamp(NodeView.DEFAULT);
         return (yStamp.upMask() & (wideMask & ~narrowMask)) == 0;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -46,25 +47,25 @@
     public static final NodeClass<SignExtendNode> TYPE = NodeClass.create(SignExtendNode.class);
 
     public SignExtendNode(ValueNode input, int resultBits) {
-        this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
-        assert 0 < PrimitiveStamp.getBits(input.stamp()) && PrimitiveStamp.getBits(input.stamp()) <= resultBits;
+        this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
+        assert 0 < PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) && PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) <= resultBits;
     }
 
     public SignExtendNode(ValueNode input, int inputBits, int resultBits) {
         super(TYPE, ArithmeticOpTable::getSignExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
     }
 
-    public static ValueNode create(ValueNode input, int resultBits) {
-        return create(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
+    public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
+        return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
     }
 
-    public static ValueNode create(ValueNode input, int inputBits, int resultBits) {
-        IntegerConvertOp<SignExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp()).getSignExtend();
-        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp()));
+    public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
+        IntegerConvertOp<SignExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getSignExtend();
+        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
         if (synonym != null) {
             return synonym;
         }
-        return canonical(null, input, inputBits, resultBits);
+        return canonical(null, input, inputBits, resultBits, view);
     }
 
     @Override
@@ -74,35 +75,36 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, forValue, getInputBits(), getResultBits());
+        return canonical(this, forValue, getInputBits(), getResultBits(), view);
     }
 
-    private static ValueNode canonical(SignExtendNode self, ValueNode forValue, int inputBits, int resultBits) {
+    private static ValueNode canonical(SignExtendNode self, ValueNode forValue, int inputBits, int resultBits, NodeView view) {
         if (forValue instanceof SignExtendNode) {
             // sxxx -(sign-extend)-> ssss sxxx -(sign-extend)-> ssssssss sssssxxx
             // ==> sxxx -(sign-extend)-> ssssssss sssssxxx
             SignExtendNode other = (SignExtendNode) forValue;
-            return SignExtendNode.create(other.getValue(), other.getInputBits(), resultBits);
+            return SignExtendNode.create(other.getValue(), other.getInputBits(), resultBits, view);
         } else if (forValue instanceof ZeroExtendNode) {
             ZeroExtendNode other = (ZeroExtendNode) forValue;
             if (other.getResultBits() > other.getInputBits()) {
                 // sxxx -(zero-extend)-> 0000 sxxx -(sign-extend)-> 00000000 0000sxxx
                 // ==> sxxx -(zero-extend)-> 00000000 0000sxxx
-                return ZeroExtendNode.create(other.getValue(), other.getInputBits(), resultBits);
+                return ZeroExtendNode.create(other.getValue(), other.getInputBits(), resultBits, view);
             }
         }
 
-        if (forValue.stamp() instanceof IntegerStamp) {
-            IntegerStamp inputStamp = (IntegerStamp) forValue.stamp();
+        if (forValue.stamp(view) instanceof IntegerStamp) {
+            IntegerStamp inputStamp = (IntegerStamp) forValue.stamp(view);
             if ((inputStamp.upMask() & (1L << (inputBits - 1))) == 0L) {
                 // 0xxx -(sign-extend)-> 0000 0xxx
                 // ==> 0xxx -(zero-extend)-> 0000 0xxx
-                return ZeroExtendNode.create(forValue, inputBits, resultBits);
+                return ZeroExtendNode.create(forValue, inputBits, resultBits, view);
             }
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,10 +24,12 @@
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -39,31 +41,42 @@
 
     public static final NodeClass<SignedDivNode> TYPE = NodeClass.create(SignedDivNode.class);
 
-    public SignedDivNode(ValueNode x, ValueNode y) {
+    protected SignedDivNode(ValueNode x, ValueNode y) {
         this(TYPE, x, y);
     }
 
     protected SignedDivNode(NodeClass<? extends SignedDivNode> c, ValueNode x, ValueNode y) {
-        super(c, IntegerStamp.OPS.getDiv().foldStamp(x.stamp(), y.stamp()), Op.DIV, Type.SIGNED, x, y);
+        super(c, IntegerStamp.OPS.getDiv().foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), Op.DIV, Type.SIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        return canonical(null, x, y, view);
     }
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(IntegerStamp.OPS.getDiv().foldStamp(getX().stamp(), getY().stamp()));
+        return updateStamp(IntegerStamp.OPS.getDiv().foldStamp(getX().stamp(NodeView.DEFAULT), getY().stamp(NodeView.DEFAULT)));
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, view);
+    }
+
+    public static ValueNode canonical(SignedDivNode self, ValueNode forX, ValueNode forY, NodeView view) {
+        Stamp predictedStamp = IntegerStamp.OPS.getDiv().foldStamp(forX.stamp(NodeView.DEFAULT), forY.stamp(NodeView.DEFAULT));
+        Stamp stamp = self != null ? self.stamp(view) : predictedStamp;
         if (forX.isConstant() && forY.isConstant()) {
-            @SuppressWarnings("hiding")
             long y = forY.asJavaConstant().asLong();
             if (y == 0) {
-                return this; // this will trap, can not canonicalize
+                return self != null ? self : new SignedDivNode(forX, forY); // this will trap, can
+                                                                            // not canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y);
+            return ConstantNode.forIntegerStamp(stamp, forX.asJavaConstant().asLong() / y);
         } else if (forY.isConstant()) {
             long c = forY.asJavaConstant().asLong();
-            ValueNode v = canonical(forX, c);
+            ValueNode v = canonical(forX, c, view);
             if (v != null) {
                 return v;
             }
@@ -74,47 +87,47 @@
             SubNode integerSubNode = (SubNode) forX;
             if (integerSubNode.getY() instanceof SignedRemNode) {
                 SignedRemNode integerRemNode = (SignedRemNode) integerSubNode.getY();
-                if (integerSubNode.stamp().isCompatible(this.stamp()) && integerRemNode.stamp().isCompatible(this.stamp()) && integerSubNode.getX() == integerRemNode.getX() &&
+                if (integerSubNode.stamp(view).isCompatible(stamp) && integerRemNode.stamp(view).isCompatible(stamp) && integerSubNode.getX() == integerRemNode.getX() &&
                                 forY == integerRemNode.getY()) {
                     SignedDivNode sd = new SignedDivNode(integerSubNode.getX(), forY);
-                    sd.stateBefore = this.stateBefore;
+                    sd.stateBefore = self != null ? self.stateBefore : null;
                     return sd;
                 }
             }
         }
 
-        if (next() instanceof SignedDivNode) {
-            NodeClass<?> nodeClass = getNodeClass();
-            if (next().getClass() == this.getClass() && nodeClass.equalInputs(this, next()) && valueEquals(next())) {
-                return next();
+        if (self != null && self.next() instanceof SignedDivNode) {
+            NodeClass<?> nodeClass = self.getNodeClass();
+            if (self.next().getClass() == self.getClass() && nodeClass.equalInputs(self, self.next()) && self.valueEquals(self.next())) {
+                return self.next();
             }
         }
 
-        return this;
+        return self != null ? self : new SignedDivNode(forX, forY);
     }
 
-    public static ValueNode canonical(ValueNode forX, long c) {
+    public static ValueNode canonical(ValueNode forX, long c, NodeView view) {
         if (c == 1) {
             return forX;
         }
         if (c == -1) {
-            return NegateNode.create(forX);
+            return NegateNode.create(forX, view);
         }
         long abs = Math.abs(c);
-        if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
+        if (CodeUtil.isPowerOf2(abs) && forX.stamp(view) instanceof IntegerStamp) {
             ValueNode dividend = forX;
-            IntegerStamp stampX = (IntegerStamp) forX.stamp();
+            IntegerStamp stampX = (IntegerStamp) forX.stamp(view);
             int log2 = CodeUtil.log2(abs);
             // no rounding if dividend is positive or if its low bits are always 0
             if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
-                int bits = PrimitiveStamp.getBits(forX.stamp());
+                int bits = PrimitiveStamp.getBits(forX.stamp(view));
                 RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
                 UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
-                dividend = BinaryArithmeticNode.add(dividend, round);
+                dividend = BinaryArithmeticNode.add(dividend, round, view);
             }
             RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
             if (c < 0) {
-                return NegateNode.create(shift);
+                return NegateNode.create(shift, view);
             }
             return shift;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,10 +23,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -38,52 +40,63 @@
 
     public static final NodeClass<SignedRemNode> TYPE = NodeClass.create(SignedRemNode.class);
 
-    public SignedRemNode(ValueNode x, ValueNode y) {
+    protected SignedRemNode(ValueNode x, ValueNode y) {
         this(TYPE, x, y);
     }
 
     protected SignedRemNode(NodeClass<? extends SignedRemNode> c, ValueNode x, ValueNode y) {
-        super(c, IntegerStamp.OPS.getRem().foldStamp(x.stamp(), y.stamp()), Op.REM, Type.SIGNED, x, y);
+        super(c, IntegerStamp.OPS.getRem().foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), Op.REM, Type.SIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        Stamp stamp = IntegerStamp.OPS.getRem().foldStamp(x.stamp(view), y.stamp(view));
+        return canonical(null, x, y, stamp, view);
     }
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(IntegerStamp.OPS.getRem().foldStamp(getX().stamp(), getY().stamp()));
+        return updateStamp(IntegerStamp.OPS.getRem().foldStamp(getX().stamp(NodeView.DEFAULT), getY().stamp(NodeView.DEFAULT)));
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, stamp(view), view);
+    }
+
+    private static ValueNode canonical(SignedRemNode self, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
         if (forX.isConstant() && forY.isConstant()) {
-            @SuppressWarnings("hiding")
             long y = forY.asJavaConstant().asLong();
             if (y == 0) {
-                return this; // this will trap, can not canonicalize
+                return self != null ? self : new SignedRemNode(forX, forY); // this will trap, can
+                                                                            // not canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() % y);
-        } else if (forY.isConstant() && forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
+            return ConstantNode.forIntegerStamp(stamp, forX.asJavaConstant().asLong() % y);
+        } else if (forY.isConstant() && forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) {
             long constY = forY.asJavaConstant().asLong();
-            IntegerStamp xStamp = (IntegerStamp) forX.stamp();
-            IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+            IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
+            IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
             if (constY < 0 && constY != CodeUtil.minValue(yStamp.getBits())) {
-                return new SignedRemNode(forX, ConstantNode.forIntegerStamp(yStamp, -constY)).canonical(tool);
+                Stamp newStamp = IntegerStamp.OPS.getRem().foldStamp(forX.stamp(view), forY.stamp(view));
+                return canonical(null, forX, ConstantNode.forIntegerStamp(yStamp, -constY), newStamp, view);
             }
 
             if (constY == 1) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp, 0);
             } else if (CodeUtil.isPowerOf2(constY)) {
                 if (xStamp.isPositive()) {
                     // x & (y - 1)
-                    return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1));
+                    return new AndNode(forX, ConstantNode.forIntegerStamp(stamp, constY - 1));
                 } else if (xStamp.isNegative()) {
                     // -((-x) & (y - 1))
-                    return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+                    return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp, constY - 1)));
                 } else {
                     // x - ((x / y) << log2(y))
-                    return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY), ConstantNode.forInt(CodeUtil.log2(constY))));
+                    return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY, view), ConstantNode.forInt(CodeUtil.log2(constY)), view), view);
                 }
             }
         }
-        return this;
+        return self != null ? self : new SignedRemNode(forX, forY);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,8 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -42,10 +44,18 @@
 
     public static final NodeClass<SqrtNode> TYPE = NodeClass.create(SqrtNode.class);
 
-    public SqrtNode(ValueNode x) {
+    protected SqrtNode(ValueNode x) {
         super(TYPE, ArithmeticOpTable::getSqrt, x);
     }
 
+    public static ValueNode create(ValueNode x, NodeView view) {
+        if (x.isConstant()) {
+            ArithmeticOpTable.UnaryOp<Sqrt> op = ArithmeticOpTable.forStamp(x.stamp(view)).getSqrt();
+            return ConstantNode.forPrimitive(op.foldStamp(x.stamp(view)), op.foldConstant(x.asConstant()));
+        }
+        return new SqrtNode(x);
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
         nodeValueMap.setResult(this, gen.emitMathSqrt(nodeValueMap.operand(getValue())));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -53,20 +54,20 @@
         super(c, ArithmeticOpTable::getSub, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Sub> op = ArithmeticOpTable.forStamp(x.stamp()).getSub();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Sub> op = ArithmeticOpTable.forStamp(x.stamp(view)).getSub();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
-    private static ValueNode canonical(SubNode subNode, BinaryOp<Sub> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(SubNode subNode, BinaryOp<Sub> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         SubNode self = subNode;
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            Constant zero = op.getZero(forX.stamp());
+            Constant zero = op.getZero(forX.stamp(view));
             if (zero != null) {
                 return ConstantNode.forPrimitive(stamp, zero);
             }
@@ -87,18 +88,18 @@
                 SubNode x = (SubNode) forX;
                 if (x.getX() == forY) {
                     // (a - b) - a
-                    return NegateNode.create(x.getY());
+                    return NegateNode.create(x.getY(), view);
                 }
             }
             if (forY instanceof AddNode) {
                 AddNode y = (AddNode) forY;
                 if (y.getX() == forX) {
                     // a - (a + b)
-                    return NegateNode.create(y.getY());
+                    return NegateNode.create(y.getY(), view);
                 }
                 if (y.getY() == forX) {
                     // b - (a + b)
-                    return NegateNode.create(y.getX());
+                    return NegateNode.create(y.getX(), view);
                 }
             } else if (forY instanceof SubNode) {
                 SubNode y = (SubNode) forY;
@@ -114,7 +115,7 @@
                 return forX;
             }
             if (associative && self != null) {
-                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY);
+                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
                 if (reassociated != self) {
                     return reassociated;
                 }
@@ -124,7 +125,7 @@
                 if (i < 0 || ((IntegerStamp) StampFactory.forKind(forY.getStackKind())).contains(-i)) {
                     // Adding a negative is more friendly to the backend since adds are
                     // commutative, so prefer add when it fits.
-                    return BinaryArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp, -i));
+                    return BinaryArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp, -i), view);
                 }
             }
         } else if (forX.isConstant()) {
@@ -135,30 +136,28 @@
                  * have to test for the neutral element of +, because we are doing this
                  * transformation: 0 - x == (-x) + 0 == -x.
                  */
-                return NegateNode.create(forY);
+                return NegateNode.create(forY, view);
             }
             if (associative && self != null) {
-                return reassociate(self, ValueNode.isConstantPredicate(), forX, forY);
+                return reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
             }
         }
         if (forY instanceof NegateNode) {
-            return BinaryArithmeticNode.add(forX, ((NegateNode) forY).getValue());
+            return BinaryArithmeticNode.add(forX, ((NegateNode) forY).getValue(), view);
         }
-        if (self == null) {
-            self = new SubNode(forX, forY);
-        }
-        return self;
+        return self != null ? self : new SubNode(forX, forY);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
         BinaryOp<Sub> op = getOp(forX, forY);
-        return canonical(this, op, stamp, forX, forY);
+        return canonical(this, op, stamp, forX, forY, view);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ArithmeticOperation;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 
@@ -47,12 +48,12 @@
     protected final SerializableUnaryFunction<OP> getOp;
 
     protected UnaryArithmeticNode(NodeClass<? extends UnaryArithmeticNode<OP>> c, SerializableUnaryFunction<OP> getOp, ValueNode value) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(value.stamp())).foldStamp(value.stamp()), value);
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(value.stamp(NodeView.DEFAULT))).foldStamp(value.stamp(NodeView.DEFAULT)), value);
         this.getOp = getOp;
     }
 
     protected final UnaryOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp()));
+        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
     }
 
     @Override
@@ -62,7 +63,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return getOp(getValue()).foldStamp(newStamp);
     }
 
@@ -77,7 +78,7 @@
 
     protected static <OP> ValueNode findSynonym(ValueNode forValue, UnaryOp<OP> op) {
         if (forValue.isConstant()) {
-            return ConstantNode.forPrimitive(op.foldStamp(forValue.stamp()), op.foldConstant(forValue.asConstant()));
+            return ConstantNode.forPrimitive(op.foldStamp(forValue.stamp(NodeView.DEFAULT)), op.foldConstant(forValue.asConstant()));
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 /**
@@ -63,7 +64,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(foldStamp(value.stamp()));
+        return updateStamp(foldStamp(value.stamp(NodeView.DEFAULT)));
     }
 
     /**
@@ -74,6 +75,6 @@
      * @param newStamp
      */
     public Stamp foldStamp(Stamp newStamp) {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -52,7 +53,8 @@
         this.firstHalf = firstHalf;
     }
 
-    public static ValueNode create(ValueNode value, boolean firstHalf) {
+    @SuppressWarnings("unused")
+    public static ValueNode create(ValueNode value, boolean firstHalf, NodeView view) {
         if (value.isConstant() && value.asConstant().isDefaultForKind()) {
             return ConstantNode.defaultForKind(JavaKind.Int);
         }
@@ -84,7 +86,7 @@
         if ((byteOrder == ByteOrder.BIG_ENDIAN) == firstHalf) {
             result = graph().unique(new UnsignedRightShiftNode(result, ConstantNode.forInt(32, graph())));
         }
-        result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph());
+        result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph(), NodeView.DEFAULT);
         replaceAtUsagesAndDelete(result);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedDivNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedDivNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,10 +23,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -43,18 +45,30 @@
     }
 
     protected UnsignedDivNode(NodeClass<? extends UnsignedDivNode> c, ValueNode x, ValueNode y) {
-        super(c, x.stamp().unrestricted(), Op.DIV, Type.UNSIGNED, x, y);
+        super(c, x.stamp(NodeView.DEFAULT).unrestricted(), Op.DIV, Type.UNSIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        Stamp stamp = x.stamp(view).unrestricted();
+        return canonical(null, x, y, stamp, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        int bits = ((IntegerStamp) stamp()).getBits();
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, stamp(view), view);
+    }
+
+    @SuppressWarnings("unused")
+    private static ValueNode canonical(UnsignedDivNode self, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
+        int bits = ((IntegerStamp) stamp).getBits();
         if (forX.isConstant() && forY.isConstant()) {
             long yConst = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (yConst == 0) {
-                return this; // this will trap, cannot canonicalize
+                return self != null ? self : new UnsignedDivNode(forX, forY); // this will trap,
+                                                                              // cannot canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), Long.divideUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
+            return ConstantNode.forIntegerStamp(stamp, Long.divideUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
         } else if (forY.isConstant()) {
             long c = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (c == 1) {
@@ -64,7 +78,7 @@
                 return new UnsignedRightShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(c)));
             }
         }
-        return this;
+        return self != null ? self : new UnsignedDivNode(forX, forY);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRemNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRemNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,10 +23,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -43,27 +45,39 @@
     }
 
     protected UnsignedRemNode(NodeClass<? extends UnsignedRemNode> c, ValueNode x, ValueNode y) {
-        super(c, x.stamp().unrestricted(), Op.REM, Type.UNSIGNED, x, y);
+        super(c, x.stamp(NodeView.DEFAULT).unrestricted(), Op.REM, Type.UNSIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        Stamp stamp = x.stamp(view).unrestricted();
+        return canonical(null, x, y, stamp, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        int bits = ((IntegerStamp) stamp()).getBits();
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, stamp(view), view);
+    }
+
+    @SuppressWarnings("unused")
+    public static ValueNode canonical(UnsignedRemNode self, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
+        int bits = ((IntegerStamp) stamp).getBits();
         if (forX.isConstant() && forY.isConstant()) {
             long yConst = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (yConst == 0) {
-                return this; // this will trap, cannot canonicalize
+                return self != null ? self : new UnsignedRemNode(forX, forY); // this will trap,
+                                                                              // cannot canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), Long.remainderUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
+            return ConstantNode.forIntegerStamp(stamp, Long.remainderUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
         } else if (forY.isConstant()) {
             long c = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (c == 1) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp, 0);
             } else if (CodeUtil.isPowerOf2(c)) {
-                return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), c - 1));
+                return new AndNode(forX, ConstantNode.forIntegerStamp(stamp, c - 1));
             }
         }
-        return this;
+        return self != null ? self : new UnsignedRemNode(forX, forY);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,11 +25,13 @@
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.UShr;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -44,17 +46,34 @@
         super(TYPE, ArithmeticOpTable::getUShr, x, y);
     }
 
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        ArithmeticOpTable.ShiftOp<UShr> op = ArithmeticOpTable.forStamp(x.stamp(view)).getUShr();
+        Stamp stamp = op.foldStamp(x.stamp(view), (IntegerStamp) y.stamp(view));
+        ValueNode value = ShiftNode.canonical(op, stamp, x, y, view);
+        if (value != null) {
+            return value;
+        }
+
+        return canonical(null, op, stamp, x, y, view);
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
+        return canonical(this, this.getArithmeticOp(), this.stamp(view), forX, forY, view);
+    }
+
+    @SuppressWarnings("unused")
+    private static ValueNode canonical(UnsignedRightShiftNode node, ArithmeticOpTable.ShiftOp<UShr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (forY.isConstant()) {
             int amount = forY.asJavaConstant().asInt();
             int originalAmout = amount;
-            int mask = getShiftAmountMask();
+            int mask = op.getShiftAmountMask(stamp);
             amount &= mask;
             if (amount == 0) {
                 return forX;
@@ -66,14 +85,14 @@
                     if (other instanceof UnsignedRightShiftNode) {
                         int total = amount + otherAmount;
                         if (total != (total & mask)) {
-                            return ConstantNode.forIntegerKind(getStackKind(), 0);
+                            return ConstantNode.forIntegerKind(stamp.getStackKind(), 0);
                         }
                         return new UnsignedRightShiftNode(other.getX(), ConstantNode.forInt(total));
                     } else if (other instanceof LeftShiftNode && otherAmount == amount) {
-                        if (getStackKind() == JavaKind.Long) {
+                        if (stamp.getStackKind() == JavaKind.Long) {
                             return new AndNode(other.getX(), ConstantNode.forLong(-1L >>> amount));
                         } else {
-                            assert getStackKind() == JavaKind.Int;
+                            assert stamp.getStackKind() == JavaKind.Int;
                             return new AndNode(other.getX(), ConstantNode.forInt(-1 >>> amount));
                         }
                     }
@@ -83,7 +102,11 @@
                 return new UnsignedRightShiftNode(forX, ConstantNode.forInt(amount));
             }
         }
-        return this;
+
+        if (node != null) {
+            return node;
+        }
+        return new UnsignedRightShiftNode(forX, forY);
     }
 
     @Override
@@ -98,7 +121,7 @@
              * For unsigned right shifts, the narrow can be done before the shift if the cut off
              * bits are all zero.
              */
-            IntegerStamp inputStamp = (IntegerStamp) getX().stamp();
+            IntegerStamp inputStamp = (IntegerStamp) getX().stamp(NodeView.DEFAULT);
             return (inputStamp.upMask() & ~(resultBits - 1)) == 0;
         } else {
             return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -48,17 +49,17 @@
 
     public XorNode(ValueNode x, ValueNode y) {
         super(TYPE, ArithmeticOpTable::getXor, x, y);
-        assert x.stamp().isCompatible(y.stamp());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Xor> op = ArithmeticOpTable.forStamp(x.stamp()).getXor();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Xor> op = ArithmeticOpTable.forStamp(x.stamp(view)).getXor();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
@@ -68,12 +69,13 @@
             return ret;
         }
 
-        return canonical(this, getOp(forX, forY), stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, getOp(forX, forY), stamp(NodeView.DEFAULT), forX, forY, view);
     }
 
-    private static ValueNode canonical(XorNode self, BinaryOp<Xor> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(XorNode self, BinaryOp<Xor> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forPrimitive(stamp, op.getZero(forX.stamp()));
+            return ConstantNode.forPrimitive(stamp, op.getZero(forX.stamp(view)));
         }
         if (forX.isConstant() && !forY.isConstant()) {
             return new XorNode(forY, forX);
@@ -91,7 +93,7 @@
                     return new NotNode(forX);
                 }
             }
-            return reassociate(self != null ? self : (XorNode) new XorNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(self != null ? self : (XorNode) new XorNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
         }
         return self != null ? self : new XorNode(forX, forY).maybeCommuteInputs();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -50,25 +51,25 @@
     public static final NodeClass<ZeroExtendNode> TYPE = NodeClass.create(ZeroExtendNode.class);
 
     public ZeroExtendNode(ValueNode input, int resultBits) {
-        this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
-        assert 0 < PrimitiveStamp.getBits(input.stamp()) && PrimitiveStamp.getBits(input.stamp()) <= resultBits;
+        this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
+        assert 0 < PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) && PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) <= resultBits;
     }
 
     public ZeroExtendNode(ValueNode input, int inputBits, int resultBits) {
         super(TYPE, ArithmeticOpTable::getZeroExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
     }
 
-    public static ValueNode create(ValueNode input, int resultBits) {
-        return create(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
+    public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
+        return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
     }
 
-    public static ValueNode create(ValueNode input, int inputBits, int resultBits) {
-        IntegerConvertOp<ZeroExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp()).getZeroExtend();
-        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp()));
+    public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
+        IntegerConvertOp<ZeroExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getZeroExtend();
+        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
         if (synonym != null) {
             return synonym;
         }
-        return canonical(null, input, inputBits, resultBits);
+        return canonical(null, input, inputBits, resultBits, view);
     }
 
     @Override
@@ -91,15 +92,16 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, forValue, getInputBits(), getResultBits());
+        return canonical(this, forValue, getInputBits(), getResultBits(), view);
     }
 
-    private static ValueNode canonical(ZeroExtendNode zeroExtendNode, ValueNode forValue, int inputBits, int resultBits) {
+    private static ValueNode canonical(ZeroExtendNode zeroExtendNode, ValueNode forValue, int inputBits, int resultBits, NodeView view) {
         ZeroExtendNode self = zeroExtendNode;
         if (forValue instanceof ZeroExtendNode) {
             // xxxx -(zero-extend)-> 0000 xxxx -(zero-extend)-> 00000000 0000xxxx
@@ -109,20 +111,20 @@
         }
         if (forValue instanceof NarrowNode) {
             NarrowNode narrow = (NarrowNode) forValue;
-            Stamp inputStamp = narrow.getValue().stamp();
+            Stamp inputStamp = narrow.getValue().stamp(view);
             if (inputStamp instanceof IntegerStamp) {
                 IntegerStamp istamp = (IntegerStamp) inputStamp;
-                long mask = CodeUtil.mask(PrimitiveStamp.getBits(narrow.stamp()));
+                long mask = CodeUtil.mask(PrimitiveStamp.getBits(narrow.stamp(view)));
 
                 if ((istamp.upMask() & ~mask) == 0) {
                     // The original value cannot change because of the narrow and zero extend.
 
                     if (istamp.getBits() < resultBits) {
                         // Need to keep the zero extend, skip the narrow.
-                        return create(narrow.getValue(), resultBits);
+                        return create(narrow.getValue(), resultBits, view);
                     } else if (istamp.getBits() > resultBits) {
                         // Need to keep the narrow, skip the zero extend.
-                        return NarrowNode.create(narrow.getValue(), resultBits);
+                        return NarrowNode.create(narrow.getValue(), resultBits, view);
                     } else {
                         assert istamp.getBits() == resultBits;
                         // Just return the original value.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/BlackholeNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/BlackholeNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,6 +44,10 @@
         this.value = value;
     }
 
+    public ValueNode getValue() {
+        return value;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         gen.getLIRGeneratorTool().emitBlackhole(gen.operand(value));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/OpaqueNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/OpaqueNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -39,7 +40,7 @@
     @Input protected ValueNode value;
 
     public OpaqueNode(ValueNode value) {
-        super(TYPE, value.stamp().unrestricted());
+        super(TYPE, value.stamp(NodeView.DEFAULT).unrestricted());
         this.value = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -90,7 +91,7 @@
     }
 
     protected VirtualBoxingNode createVirtualBoxingNode() {
-        return new VirtualBoxingNode(StampTool.typeOrNull(stamp()), boxingKind);
+        return new VirtualBoxingNode(StampTool.typeOrNull(stamp(NodeView.DEFAULT)), boxingKind);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
@@ -67,7 +68,7 @@
     @Input ValueNode condition;
 
     public BranchProbabilityNode(ValueNode probability, ValueNode condition) {
-        super(TYPE, condition.stamp());
+        super(TYPE, condition.stamp(NodeView.DEFAULT));
         this.probability = probability;
         this.condition = condition;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -46,7 +47,7 @@
     }
 
     protected FixedValueAnchorNode(NodeClass<? extends FixedValueAnchorNode> c, ValueNode object) {
-        super(c, object.stamp());
+        super(c, object.stamp(NodeView.DEFAULT));
         this.object = object;
     }
 
@@ -63,7 +64,7 @@
     @Override
     public boolean inferStamp() {
         if (predefinedStamp == null) {
-            return updateStamp(object.stamp());
+            return updateStamp(object.stamp(NodeView.DEFAULT));
         } else {
             return false;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GetClassNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GetClassNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -60,7 +61,7 @@
     public GetClassNode(Stamp stamp, ValueNode object) {
         super(TYPE, stamp);
         this.object = object;
-        assert ((ObjectStamp) object.stamp()).nonNull();
+        assert ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
     }
 
     @Override
@@ -68,9 +69,9 @@
         tool.getLowerer().lower(this, tool);
     }
 
-    public static ValueNode tryFold(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ValueNode object) {
-        if (metaAccess != null && object != null && object.stamp() instanceof ObjectStamp) {
-            ObjectStamp objectStamp = (ObjectStamp) object.stamp();
+    public static ValueNode tryFold(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, NodeView view, ValueNode object) {
+        if (metaAccess != null && object != null && object.stamp(view) instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) object.stamp(view);
             if (objectStamp.isExactType()) {
                 return ConstantNode.forConstant(constantReflection.asJavaClass(objectStamp.type()), metaAccess);
             }
@@ -80,7 +81,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode folded = tryFold(tool.getMetaAccess(), tool.getConstantReflection(), getObject());
+        NodeView view = NodeView.from(tool);
+        ValueNode folded = tryFold(tool.getMetaAccess(), tool.getConstantReflection(), view, getObject());
         return folded == null ? this : folded;
     }
 
@@ -90,7 +92,7 @@
         if (alias instanceof VirtualObjectNode) {
             VirtualObjectNode virtual = (VirtualObjectNode) alias;
             Constant javaClass = tool.getConstantReflectionProvider().asJavaClass(virtual.type());
-            tool.replaceWithValue(ConstantNode.forConstant(stamp(), javaClass, tool.getMetaAccessProvider(), graph()));
+            tool.replaceWithValue(ConstantNode.forConstant(stamp(NodeView.DEFAULT), javaClass, tool.getMetaAccessProvider(), graph()));
         }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -43,6 +43,7 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
@@ -70,7 +71,7 @@
         assert keySuccessors.length == keys.length + 1;
         assert keySuccessors.length == keyProbabilities.length;
         this.keys = keys;
-        assert value.stamp() instanceof PrimitiveStamp && value.stamp().getStackKind().isNumericInteger();
+        assert value.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && value.stamp(NodeView.DEFAULT).getStackKind().isNumericInteger();
         assert assertSorted();
     }
 
@@ -135,6 +136,7 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
+        NodeView view = NodeView.from(tool);
         if (blockSuccessorCount() == 1) {
             tool.addToWorkList(defaultSuccessor());
             graph().removeSplitPropagate(this, defaultSuccessor());
@@ -142,7 +144,7 @@
             killOtherSuccessors(tool, successorIndexAtKey(value().asJavaConstant().asInt()));
         } else if (tryOptimizeEnumSwitch(tool)) {
             return;
-        } else if (tryRemoveUnreachableKeys(tool, value().stamp())) {
+        } else if (tryRemoveUnreachableKeys(tool, value().stamp(view))) {
             return;
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -61,8 +62,8 @@
     }
 
     private static Stamp hubStamp(StampProvider stampProvider, ValueNode value) {
-        assert value.stamp() instanceof ObjectStamp;
-        return stampProvider.createHubStamp(((ObjectStamp) value.stamp()));
+        assert value.stamp(NodeView.DEFAULT) instanceof ObjectStamp;
+        return stampProvider.createHubStamp(((ObjectStamp) value.stamp(NodeView.DEFAULT)));
     }
 
     public static ValueNode create(ValueNode value, StampProvider stampProvider, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
@@ -91,9 +92,10 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (!GeneratePIC.getValue(tool.getOptions())) {
+            NodeView view = NodeView.from(tool);
             MetaAccessProvider metaAccess = tool.getMetaAccess();
             ValueNode curValue = getValue();
-            ValueNode newNode = findSynonym(curValue, stamp(), metaAccess, tool.getConstantReflection());
+            ValueNode newNode = findSynonym(curValue, stamp(view), metaAccess, tool.getConstantReflection());
             if (newNode != null) {
                 return newNode;
             }
@@ -117,7 +119,7 @@
             ValueNode alias = tool.getAlias(getValue());
             TypeReference type = StampTool.typeReferenceOrNull(alias);
             if (type != null && type.isExact()) {
-                tool.replaceWithValue(ConstantNode.forConstant(stamp(), tool.getConstantReflectionProvider().asObjectHub(type.getType()), tool.getMetaAccessProvider(), graph()));
+                tool.replaceWithValue(ConstantNode.forConstant(stamp(NodeView.DEFAULT), tool.getConstantReflectionProvider().asObjectHub(type.getType()), tool.getMetaAccessProvider(), graph()));
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -96,8 +97,9 @@
                 Assumptions assumptions = graph().getAssumptions();
                 AssumptionResult<ResolvedJavaMethod> resolvedMethod = type.getType().findUniqueConcreteMethod(method);
                 if (resolvedMethod != null && resolvedMethod.canRecordTo(assumptions) && !type.getType().isInterface() && method.getDeclaringClass().isAssignableFrom(type.getType())) {
+                    NodeView view = NodeView.from(tool);
                     resolvedMethod.recordTo(assumptions);
-                    return ConstantNode.forConstant(stamp(), resolvedMethod.getResult().getEncoding(), tool.getMetaAccess());
+                    return ConstantNode.forConstant(stamp(view), resolvedMethod.getResult().getEncoding(), tool.getMetaAccess());
                 }
             }
         }
@@ -123,9 +125,9 @@
              * This really represent a misuse of LoadMethod since we're loading from a class which
              * isn't known to implement the original method but for now at least fold it away.
              */
-            return ConstantNode.forConstant(stamp(), JavaConstant.NULL_POINTER, null);
+            return ConstantNode.forConstant(stamp(NodeView.DEFAULT), JavaConstant.NULL_POINTER, null);
         } else {
-            return ConstantNode.forConstant(stamp(), newMethod.getEncoding(), tool.getMetaAccess());
+            return ConstantNode.forConstant(stamp(NodeView.DEFAULT), newMethod.getEncoding(), tool.getMetaAccess());
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ReinterpretNode;
 import org.graalvm.compiler.nodes.java.LoadFieldNode;
@@ -103,14 +104,14 @@
                     JavaKind entryKind = virtual.entryKind(entryIndex);
                     if (entry.getStackKind() == getStackKind() || entryKind == accessKind()) {
 
-                        if (!(entry.stamp().isCompatible(stamp()))) {
-                            if (entry.stamp() instanceof PrimitiveStamp && stamp instanceof PrimitiveStamp) {
+                        if (!(entry.stamp(NodeView.DEFAULT).isCompatible(stamp(NodeView.DEFAULT)))) {
+                            if (entry.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && stamp instanceof PrimitiveStamp) {
                                 PrimitiveStamp p1 = (PrimitiveStamp) stamp;
-                                PrimitiveStamp p2 = (PrimitiveStamp) entry.stamp();
+                                PrimitiveStamp p2 = (PrimitiveStamp) entry.stamp(NodeView.DEFAULT);
                                 int width1 = p1.getBits();
                                 int width2 = p2.getBits();
                                 if (width1 == width2) {
-                                    Node replacement = new ReinterpretNode(p2, entry);
+                                    Node replacement = ReinterpretNode.create(p2, entry, NodeView.DEFAULT);
                                     tool.replaceWith((ValueNode) replacement);
                                     return;
                                 } else {
@@ -141,11 +142,12 @@
                     if (arrayConstant != null) {
                         int stableDimension = objectConstant.getStableDimension();
                         if (stableDimension > 0) {
+                            NodeView view = NodeView.from(tool);
                             long constantOffset = offset().asJavaConstant().asLong();
-                            Constant constant = stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), arrayConstant, constantOffset);
+                            Constant constant = stamp(view).readConstant(tool.getConstantReflection().getMemoryAccessProvider(), arrayConstant, constantOffset);
                             boolean isDefaultStable = objectConstant.isDefaultStable();
                             if (constant != null && (isDefaultStable || !constant.isDefaultForKind())) {
-                                return ConstantNode.forConstant(stamp(), constant, stableDimension - 1, isDefaultStable, tool.getMetaAccess());
+                                return ConstantNode.forConstant(stamp(view), constant, stableDimension - 1, isDefaultStable, tool.getMetaAccess());
                             }
                         }
                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -46,6 +46,7 @@
 import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ControlSplitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.Constant;
@@ -79,7 +80,8 @@
      */
     protected SwitchNode(NodeClass<? extends SwitchNode> c, ValueNode value, AbstractBeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
         super(c, StampFactory.forVoid());
-        assert value.stamp().getStackKind().isNumericInteger() || value.stamp() instanceof AbstractPointerStamp : value.stamp() + " key not supported by SwitchNode";
+        assert value.stamp(NodeView.DEFAULT).getStackKind().isNumericInteger() || value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp : value.stamp(NodeView.DEFAULT) +
+                        " key not supported by SwitchNode";
         assert keySuccessors.length == keyProbabilities.length;
         this.successors = new NodeSuccessorList<>(this, successors);
         this.value = value;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -118,7 +119,7 @@
     }
 
     default ValueNode addNonNullCast(ValueNode value) {
-        AbstractPointerStamp valueStamp = (AbstractPointerStamp) value.stamp();
+        AbstractPointerStamp valueStamp = (AbstractPointerStamp) value.stamp(NodeView.DEFAULT);
         if (valueStamp.nonNull()) {
             return value;
         } else {
@@ -277,7 +278,7 @@
     default ValueNode nullCheckedValue(ValueNode value, DeoptimizationAction action) {
         if (!StampTool.isPointerNonNull(value)) {
             LogicNode condition = getGraph().unique(IsNullNode.create(value));
-            ObjectStamp receiverStamp = (ObjectStamp) value.stamp();
+            ObjectStamp receiverStamp = (ObjectStamp) value.stamp(NodeView.DEFAULT);
             Stamp stamp = receiverStamp.join(objectNonNull());
             FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, NullCheckException, action, true));
             ValueNode nonNullReceiver = getGraph().addOrUniqueWithInputs(PiNode.create(value, stamp, fixedGuard));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.FixedAccessNode;
@@ -88,6 +89,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return expectedValue.stamp().meet(newValue.stamp()).unrestricted();
+        return expectedValue.stamp(NodeView.DEFAULT).meet(newValue.stamp(NodeView.DEFAULT)).unrestricted();
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -59,7 +60,7 @@
     protected DynamicNewInstanceNode(NodeClass<? extends DynamicNewInstanceNode> c, ValueNode clazz, boolean fillContents, FrameState stateBefore) {
         super(c, StampFactory.objectNonNull(), fillContents, stateBefore);
         this.clazz = clazz;
-        assert ((ObjectStamp) clazz.stamp()).nonNull();
+        assert ((ObjectStamp) clazz.stamp(NodeView.DEFAULT)).nonNull();
     }
 
     public ValueNode getInstanceType() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodes.BeginStateSplitNode;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.KillingBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -79,7 +80,7 @@
              */
             LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getLocationIdentity();
             AbstractBeginNode entry = graph().add(KillingBeginNode.create(locationsKilledByInvoke));
-            LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp()));
+            LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp(NodeView.DEFAULT)));
 
             loadException.setStateAfter(stateAfter());
             replaceAtUsages(InputType.Value, loadException);
@@ -93,7 +94,7 @@
     @Override
     public boolean verify() {
         assertTrue(stateAfter() != null, "an exception handler needs a frame state");
-        assertTrue(stateAfter().stackSize() == 1 && stateAfter().stackAt(0).stamp().getStackKind() == JavaKind.Object,
+        assertTrue(stateAfter().stackSize() == 1 && stateAfter().stackAt(0).stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object,
                         "an exception handler's frame state must have only the exception on the stack");
         return super.verify();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IsNullNode;
@@ -92,7 +93,7 @@
     }
 
     public static LogicNode createHelper(ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
-        LogicNode synonym = findSynonym(checkedStamp, object);
+        LogicNode synonym = findSynonym(checkedStamp, object, NodeView.DEFAULT);
         if (synonym != null) {
             return synonym;
         } else {
@@ -107,7 +108,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        LogicNode synonym = findSynonym(checkedStamp, forValue);
+        NodeView view = NodeView.from(tool);
+        LogicNode synonym = findSynonym(checkedStamp, forValue, view);
         if (synonym != null) {
             return synonym;
         } else {
@@ -115,8 +117,8 @@
         }
     }
 
-    public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object) {
-        ObjectStamp inputStamp = (ObjectStamp) object.stamp();
+    public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object, NodeView view) {
+        ObjectStamp inputStamp = (ObjectStamp) object.stamp(view);
         ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
 
         if (joinedStamp.isEmpty()) {
@@ -158,7 +160,7 @@
     @Override
     public void virtualize(VirtualizerTool tool) {
         ValueNode alias = tool.getAlias(getValue());
-        TriState fold = tryFold(alias.stamp());
+        TriState fold = tryFold(alias.stamp(NodeView.DEFAULT));
         if (fold != TriState.UNKNOWN) {
             tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph()));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -98,7 +99,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) {
-        if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp()))) {
+        NodeView view = NodeView.from(tool);
+        if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp(view)))) {
             return null;
         }
         return canonical(this, StampPair.create(stamp, uncheckedStamp), forObject, field, tool.getConstantFieldProvider(),
@@ -178,10 +180,10 @@
             int fieldIndex = ((VirtualInstanceNode) alias).fieldIndex(field());
             if (fieldIndex != -1) {
                 ValueNode entry = tool.getEntry((VirtualObjectNode) alias, fieldIndex);
-                if (stamp.isCompatible(entry.stamp())) {
+                if (stamp.isCompatible(entry.stamp(NodeView.DEFAULT))) {
                     tool.replaceWith(entry);
                 } else {
-                    assert stamp().getStackKind() == JavaKind.Int && (entry.stamp().getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
+                    assert stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Int && (entry.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
                                     entry.getStackKind() == JavaKind.Illegal) : "Can only allow different stack kind two slot marker writes on one stot fields.";
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
@@ -92,7 +93,7 @@
 
     private static JavaKind determinePreciseArrayElementType(ValueNode array, JavaKind kind) {
         if (kind == JavaKind.Byte) {
-            ResolvedJavaType javaType = ((ObjectStamp) array.stamp()).type();
+            ResolvedJavaType javaType = ((ObjectStamp) array.stamp(NodeView.DEFAULT)).type();
             if (javaType != null && javaType.isArray() && javaType.getComponentType() != null && javaType.getComponentType().getJavaKind() == JavaKind.Boolean) {
                 return JavaKind.Boolean;
             }
@@ -114,10 +115,10 @@
             int idx = indexValue.isConstant() ? indexValue.asJavaConstant().asInt() : -1;
             if (idx >= 0 && idx < virtual.entryCount()) {
                 ValueNode entry = tool.getEntry(virtual, idx);
-                if (stamp.isCompatible(entry.stamp())) {
+                if (stamp.isCompatible(entry.stamp(NodeView.DEFAULT))) {
                     tool.replaceWith(entry);
                 } else {
-                    assert stamp().getStackKind() == JavaKind.Int && (entry.stamp().getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
+                    assert stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Int && (entry.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
                                     entry.getStackKind() == JavaKind.Illegal) : "Can only allow different stack kind two slot marker writes on one stot fields.";
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -58,11 +59,11 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        assert getNewValue().stamp().isCompatible(getExpectedValue().stamp());
+        assert getNewValue().stamp(NodeView.DEFAULT).isCompatible(getExpectedValue().stamp(NodeView.DEFAULT));
         assert !this.canDeoptimize();
         LIRGeneratorTool tool = gen.getLIRGeneratorTool();
 
-        LIRKind resultKind = tool.getLIRKind(stamp());
+        LIRKind resultKind = tool.getLIRKind(stamp(NodeView.DEFAULT));
         Value trueResult = tool.emitConstant(resultKind, JavaConstant.TRUE);
         Value falseResult = tool.emitConstant(resultKind, JavaConstant.FALSE);
         Value result = tool.emitLogicCompareAndSwap(gen.operand(getAddress()), gen.operand(getExpectedValue()), gen.operand(getNewValue()), trueResult, falseResult);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.FixedAccessNode;
@@ -55,7 +56,7 @@
     @OptionalInput(State) FrameState stateAfter;
 
     public LoweredAtomicReadAndWriteNode(AddressNode address, LocationIdentity location, ValueNode newValue, BarrierType barrierType) {
-        super(TYPE, address, location, newValue.stamp().unrestricted(), barrierType);
+        super(TYPE, address, location, newValue.stamp(NodeView.DEFAULT).unrestricted(), barrierType);
         this.newValue = newValue;
     }
 
@@ -93,6 +94,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -132,7 +133,7 @@
             return targetMethod;
         }
 
-        return devirtualizeCall(invokeKind, targetMethod, contextType, receiver.graph().getAssumptions(), receiver.stamp());
+        return devirtualizeCall(invokeKind, targetMethod, contextType, receiver.graph().getAssumptions(), receiver.stamp(NodeView.DEFAULT));
     }
 
     public static ResolvedJavaMethod devirtualizeCall(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ResolvedJavaType contextType, Assumptions assumptions, Stamp receiverStamp) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.spi.VirtualizableAllocation;
@@ -119,7 +120,8 @@
     @Override
     public void simplify(SimplifierTool tool) {
         if (hasNoUsages()) {
-            Stamp lengthStamp = length().stamp();
+            NodeView view = NodeView.from(tool);
+            Stamp lengthStamp = length().stamp(view);
             if (lengthStamp instanceof IntegerStamp) {
                 IntegerStamp lengthIntegerStamp = (IntegerStamp) lengthStamp;
                 if (lengthIntegerStamp.isPositive()) {
@@ -130,7 +132,7 @@
             // Should be areFrameStatesAtSideEffects but currently SVM will complain about
             // RuntimeConstraint
             if (graph().getGuardsStage().allowsFloatingGuards()) {
-                LogicNode lengthNegativeCondition = CompareNode.createCompareNode(graph(), Condition.LT, length(), ConstantNode.forInt(0, graph()), tool.getConstantReflection());
+                LogicNode lengthNegativeCondition = CompareNode.createCompareNode(graph(), Condition.LT, length(), ConstantNode.forInt(0, graph()), tool.getConstantReflection(), view);
                 // we do not have a non-deopting path for that at the moment so action=None.
                 FixedGuardNode guard = graph().add(new FixedGuardNode(lengthNegativeCondition, DeoptimizationReason.RuntimeConstraint, DeoptimizationAction.None, true));
                 graph().replaceFixedWithFixed(this, guard);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.IterableNodeType;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.MonitorEnter;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
@@ -56,7 +57,7 @@
 
     public RawMonitorEnterNode(ValueNode object, ValueNode hub, MonitorIdNode monitorId) {
         super(TYPE, object, monitorId);
-        assert ((ObjectStamp) object.stamp()).nonNull();
+        assert ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
         this.hub = hub;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.AbstractStateSplit;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -87,7 +88,7 @@
      * that must be registered with the runtime upon object initialization.
      */
     public static boolean mayHaveFinalizer(ValueNode object, Assumptions assumptions) {
-        ObjectStamp objectStamp = (ObjectStamp) object.stamp();
+        ObjectStamp objectStamp = (ObjectStamp) object.stamp(NodeView.DEFAULT);
         if (objectStamp.isExactType()) {
             return objectStamp.type().hasFinalizer();
         } else if (objectStamp.type() != null) {
@@ -102,7 +103,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        if (!(forValue.stamp() instanceof ObjectStamp)) {
+        NodeView view = NodeView.from(tool);
+        if (!(forValue.stamp(view) instanceof ObjectStamp)) {
             return this;
         }
         if (!mayHaveFinalizer(forValue, graph().getAssumptions())) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
 import org.graalvm.compiler.nodes.extended.SwitchNode;
@@ -64,7 +65,7 @@
         assert successors.length <= keys.length + 1;
         assert keySuccessors.length == keyProbabilities.length;
         this.keys = keys;
-        assert value.stamp() instanceof AbstractPointerStamp;
+        assert value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
         assert assertKeys();
 
         hubs = new Constant[keys.length];
@@ -123,6 +124,7 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
+        NodeView view = NodeView.from(tool);
         if (value() instanceof ConstantNode) {
             Constant constant = value().asConstant();
 
@@ -139,8 +141,8 @@
             }
             killOtherSuccessors(tool, survivingEdge);
         }
-        if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp() instanceof ObjectStamp) {
-            ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp();
+        if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp(view) instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(view);
             if (objectStamp.type() != null) {
                 int validKeys = 0;
                 for (int i = 0; i < keyCount(); i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
@@ -57,7 +58,7 @@
 
     public UnsafeCompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, JavaKind valueKind, LocationIdentity locationIdentity) {
         super(TYPE, StampFactory.forKind(JavaKind.Boolean.getStackKind()));
-        assert expected.stamp().isCompatible(newValue.stamp());
+        assert expected.stamp(NodeView.DEFAULT).isCompatible(newValue.stamp(NodeView.DEFAULT));
         this.object = object;
         this.offset = offset;
         this.expected = expected;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -46,12 +47,12 @@
     }
 
     public ValueCompareAndSwapNode(AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location, BarrierType barrierType) {
-        super(TYPE, address, location, expectedValue, newValue, barrierType, expectedValue.stamp().meet(newValue.stamp()).unrestricted());
+        super(TYPE, address, location, expectedValue, newValue, barrierType, expectedValue.stamp(NodeView.DEFAULT).meet(newValue.stamp(NodeView.DEFAULT)).unrestricted());
     }
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        assert getNewValue().stamp().isCompatible(getExpectedValue().stamp());
+        assert getNewValue().stamp(NodeView.DEFAULT).isCompatible(getExpectedValue().stamp(NodeView.DEFAULT));
         LIRGeneratorTool tool = gen.getLIRGeneratorTool();
         assert !this.canDeoptimize();
         gen.setResult(this, tool.emitValueCompareAndSwap(gen.operand(getAddress()), gen.operand(getExpectedValue()), gen.operand(getNewValue())));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,8 @@
 
     AddressNode getAddress();
 
+    void setAddress(AddressNode address);
+
     LocationIdentity getLocationIdentity();
 
     boolean canNullCheck();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -54,6 +54,7 @@
         return address;
     }
 
+    @Override
     public void setAddress(AddressNode address) {
         updateUsages(this.address, address);
         this.address = address;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -59,6 +59,12 @@
     }
 
     @Override
+    public void setAddress(AddressNode address) {
+        updateUsages(this.address, address);
+        this.address = address;
+    }
+
+    @Override
     public LocationIdentity getLocationIdentity() {
         return location;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNodeUtil;
 import org.graalvm.compiler.nodes.ValuePhiNode;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
@@ -65,8 +66,8 @@
         this.lastLocationAccess = lastLocationAccess;
 
         // The input to floating reads must be always non-null or have at least a guard.
-        assert guard != null || !(address.getBase().stamp() instanceof ObjectStamp) || address.getBase() instanceof ValuePhiNode ||
-                        ((ObjectStamp) address.getBase().stamp()).nonNull() : address.getBase();
+        assert guard != null || !(address.getBase().stamp(NodeView.DEFAULT) instanceof ObjectStamp) || address.getBase() instanceof ValuePhiNode ||
+                        ((ObjectStamp) address.getBase().stamp(NodeView.DEFAULT)).nonNull() : address.getBase();
     }
 
     @Override
@@ -82,7 +83,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitLoad(readKind, gen.operand(address), null));
     }
 
@@ -106,7 +107,7 @@
     @Override
     public FixedAccessNode asFixedNode() {
         try (DebugCloseable position = withNodeSourcePosition()) {
-            ReadNode result = graph().add(new ReadNode(getAddress(), getLocationIdentity(), stamp(), getBarrierType()));
+            ReadNode result = graph().add(new ReadNode(getAddress(), getLocationIdentity(), stamp(NodeView.DEFAULT), getBarrierType()));
             result.setGuard(getGuard());
             return result;
         }
@@ -121,6 +122,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.CanonicalizableLocation;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
@@ -94,7 +95,7 @@
     @Override
     public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) {
         try (DebugCloseable position = withNodeSourcePosition()) {
-            return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(), getGuard(), getBarrierType()));
+            return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(NodeView.DEFAULT), getGuard(), getBarrierType()));
         }
     }
 
@@ -104,6 +105,7 @@
     }
 
     public static ValueNode canonicalizeRead(ValueNode read, AddressNode address, LocationIdentity locationIdentity, CanonicalizerTool tool) {
+        NodeView view = NodeView.from(tool);
         MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (tool.canonicalizeReads() && address instanceof OffsetAddressNode) {
             OffsetAddressNode objAddress = (OffsetAddressNode) address;
@@ -112,10 +114,10 @@
                 long displacement = objAddress.getOffset().asJavaConstant().asLong();
                 int stableDimension = ((ConstantNode) object).getStableDimension();
                 if (locationIdentity.isImmutable() || stableDimension > 0) {
-                    Constant constant = read.stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement);
+                    Constant constant = read.stamp(view).readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement);
                     boolean isDefaultStable = locationIdentity.isImmutable() || ((ConstantNode) object).isDefaultStable();
                     if (constant != null && (isDefaultStable || !constant.isDefaultForKind())) {
-                        return ConstantNode.forConstant(read.stamp(), constant, Math.max(stableDimension - 1, 0), isDefaultStable, metaAccess);
+                        return ConstantNode.forConstant(read.stamp(view), constant, Math.max(stableDimension - 1, 0), isDefaultStable, metaAccess);
                     }
                 }
             }
@@ -128,7 +130,7 @@
             if (locationIdentity instanceof CanonicalizableLocation) {
                 CanonicalizableLocation canonicalize = (CanonicalizableLocation) locationIdentity;
                 ValueNode result = canonicalize.canonicalizeRead(read, address, object, tool);
-                assert result != null && result.stamp().isCompatible(read.stamp());
+                assert result != null && result.stamp(view).isCompatible(read.stamp(view));
                 return result;
             }
 
@@ -148,6 +150,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -52,7 +53,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp());
+        LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp(NodeView.DEFAULT));
         gen.getLIRGeneratorTool().getArithmetic().emitStore(writeKind, gen.operand(address), gen.operand(value()), gen.state(this));
     }
 
@@ -63,7 +64,7 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return value().stamp();
+        return value().stamp(NodeView.DEFAULT);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
@@ -31,6 +32,8 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
@@ -54,8 +57,12 @@
         this.base = base;
         this.offset = offset;
 
-        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64) &&
-                        offset != null && IntegerStamp.getBits(offset.stamp()) == 64 : "both values must have 64 bits";
+        assert base != null && (base.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp(NodeView.DEFAULT)) == 64) &&
+                        offset != null && IntegerStamp.getBits(offset.stamp(NodeView.DEFAULT)) == 64 : "both values must have 64 bits";
+    }
+
+    public static OffsetAddressNode create(ValueNode base) {
+        return new OffsetAddressNode(base, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(base.stamp(NodeView.DEFAULT)), 0));
     }
 
     @Override
@@ -66,7 +73,7 @@
     public void setBase(ValueNode base) {
         updateUsages(this.base, base);
         this.base = base;
-        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64);
+        assert base != null && (base.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp(NodeView.DEFAULT)) == 64);
     }
 
     public ValueNode getOffset() {
@@ -76,18 +83,16 @@
     public void setOffset(ValueNode offset) {
         updateUsages(this.offset, offset);
         this.offset = offset;
-        assert offset != null && IntegerStamp.getBits(offset.stamp()) == 64;
+        assert offset != null && IntegerStamp.getBits(offset.stamp(NodeView.DEFAULT)) == 64;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (base instanceof RawAddressNode) {
-            // The RawAddressNode is redundant, just directly use its input as base.
-            return new OffsetAddressNode(((RawAddressNode) base).getAddress(), offset);
-        } else if (base instanceof OffsetAddressNode) {
+        if (base instanceof OffsetAddressNode) {
+            NodeView view = NodeView.from(tool);
             // Rewrite (&base[offset1])[offset2] to base[offset1 + offset2].
             OffsetAddressNode b = (OffsetAddressNode) base;
-            return new OffsetAddressNode(b.getBase(), BinaryArithmeticNode.add(b.getOffset(), this.getOffset()));
+            return new OffsetAddressNode(b.getBase(), BinaryArithmeticNode.add(b.getOffset(), this.getOffset(), view));
         } else if (base instanceof AddNode) {
             AddNode add = (AddNode) base;
             if (add.getY().isConstant()) {
@@ -102,7 +107,7 @@
 
     @Override
     public long getMaxConstantDisplacement() {
-        Stamp curStamp = offset.stamp();
+        Stamp curStamp = offset.stamp(NodeView.DEFAULT);
         if (curStamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) curStamp;
             if (integerStamp.lowerBound() >= 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/RawAddressNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, 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.graalvm.compiler.nodes.memory.address;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-
-/**
- * Convert a word-sized integer to a raw address.
- */
-@NodeInfo(allowedUsageTypes = InputType.Association)
-public class RawAddressNode extends AddressNode {
-    public static final NodeClass<RawAddressNode> TYPE = NodeClass.create(RawAddressNode.class);
-
-    @Input ValueNode address;
-
-    public RawAddressNode(ValueNode address) {
-        super(TYPE);
-        this.address = address;
-    }
-
-    public ValueNode getAddress() {
-        return address;
-    }
-
-    public void setAddress(ValueNode address) {
-        updateUsages(this.address, address);
-        this.address = address;
-    }
-
-    @Override
-    public ValueNode getBase() {
-        return address;
-    }
-
-    @Override
-    public long getMaxConstantDisplacement() {
-        return 0;
-    }
-
-    @Override
-    public ValueNode getIndex() {
-        return null;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/StampTool.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/StampTool.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -61,9 +62,9 @@
             ValueNode nextValue = iterator.next();
             if (nextValue != selfValue) {
                 if (stamp == null) {
-                    stamp = nextValue.stamp();
+                    stamp = nextValue.stamp(NodeView.DEFAULT);
                 } else {
-                    stamp = stamp.meet(nextValue.stamp());
+                    stamp = stamp.meet(nextValue.stamp(NodeView.DEFAULT));
                 }
             }
         }
@@ -132,7 +133,7 @@
      * @return true if this node represents a legal object value which is known to be always null
      */
     public static boolean isPointerAlwaysNull(ValueNode node) {
-        return isPointerAlwaysNull(node.stamp());
+        return isPointerAlwaysNull(node.stamp(NodeView.DEFAULT));
     }
 
     /**
@@ -158,7 +159,7 @@
      * @return true if this node represents a legal object value which is known to never be null
      */
     public static boolean isPointerNonNull(ValueNode node) {
-        return isPointerNonNull(node.stamp());
+        return isPointerNonNull(node.stamp(NodeView.DEFAULT));
     }
 
     /**
@@ -184,11 +185,11 @@
      * @return the Java type this value has if it is a legal Object type, null otherwise
      */
     public static TypeReference typeReferenceOrNull(ValueNode node) {
-        return typeReferenceOrNull(node.stamp());
+        return typeReferenceOrNull(node.stamp(NodeView.DEFAULT));
     }
 
     public static ResolvedJavaType typeOrNull(ValueNode node) {
-        return typeOrNull(node.stamp());
+        return typeOrNull(node.stamp(NodeView.DEFAULT));
     }
 
     public static ResolvedJavaType typeOrNull(Stamp stamp) {
@@ -210,7 +211,7 @@
     }
 
     public static ResolvedJavaType typeOrNull(ValueNode node, MetaAccessProvider metaAccess) {
-        return typeOrNull(node.stamp(), metaAccess);
+        return typeOrNull(node.stamp(NodeView.DEFAULT), metaAccess);
     }
 
     /**
@@ -242,7 +243,7 @@
      * @return true if this node represents a legal object value whose Java type is known exactly
      */
     public static boolean isExactType(ValueNode node) {
-        return isExactType(node.stamp());
+        return isExactType(node.stamp(NodeView.DEFAULT));
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Thu Dec 07 11:54:55 2017 +0000
@@ -55,6 +55,7 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -652,7 +653,7 @@
         ValueNode n = node;
         while (n instanceof PiNode) {
             PiNode piNode = (PiNode) n;
-            ObjectStamp originalStamp = (ObjectStamp) piNode.getOriginalNode().stamp();
+            ObjectStamp originalStamp = (ObjectStamp) piNode.getOriginalNode().stamp(NodeView.DEFAULT);
             if (originalStamp.nonNull()) {
                 n = piNode.getOriginalNode();
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -111,7 +112,7 @@
     public void lower(LoweringTool tool) {
         for (int i = 0; i < virtualObjects.size(); i++) {
             if (ensureVirtual.get(i)) {
-                EnsureVirtualizedNode.ensureVirtualFailure(this, virtualObjects.get(i).stamp());
+                EnsureVirtualizedNode.ensureVirtualFailure(this, virtualObjects.get(i).stamp(NodeView.DEFAULT));
             }
         }
         tool.getLowerer().lower(this, tool);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/EnsureVirtualizedNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/EnsureVirtualizedNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.StoreFieldNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -76,7 +77,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        ensureVirtualFailure(this, object.stamp());
+        ensureVirtualFailure(this, object.stamp(NodeView.DEFAULT));
     }
 
     public static void ensureVirtualFailure(Node location, Stamp stamp) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,10 +23,10 @@
  */
 package org.graalvm.compiler.phases.common;
 
-import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PrefetchAllocateNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -36,10 +36,11 @@
 import org.graalvm.compiler.nodes.memory.ReadNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.Phase;
 
+import jdk.vm.ci.meta.JavaKind;
+
 /**
  * Created by adinn on 09/05/17.
  */
@@ -66,22 +67,22 @@
             AddressNode lowered;
             if (node instanceof ReadNode) {
                 ReadNode readNode = (ReadNode) node;
-                Stamp stamp = readNode.stamp();
+                Stamp stamp = readNode.stamp(NodeView.DEFAULT);
                 address = readNode.getAddress();
                 lowered = lowering.lower(readNode, stamp, address);
             } else if (node instanceof JavaReadNode) {
                 JavaReadNode javaReadNode = (JavaReadNode) node;
-                Stamp stamp = javaReadNode.stamp();
+                Stamp stamp = javaReadNode.stamp(NodeView.DEFAULT);
                 address = javaReadNode.getAddress();
                 lowered = lowering.lower(javaReadNode, stamp, address);
             } else if (node instanceof FloatingReadNode) {
                 FloatingReadNode floatingReadNode = (FloatingReadNode) node;
-                Stamp stamp = floatingReadNode.stamp();
+                Stamp stamp = floatingReadNode.stamp(NodeView.DEFAULT);
                 address = floatingReadNode.getAddress();
                 lowered = lowering.lower(floatingReadNode, stamp, address);
             } else if (node instanceof AbstractWriteNode) {
                 AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node;
-                Stamp stamp = abstractWriteNode.value().stamp();
+                Stamp stamp = abstractWriteNode.value().stamp(NodeView.DEFAULT);
                 address = abstractWriteNode.getAddress();
                 lowered = lowering.lower(abstractWriteNode, stamp, address);
             } else if (node instanceof PrefetchAllocateNode) {
@@ -108,7 +109,7 @@
         // now replace any remaining unlowered address nodes
         for (Node node : graph.getNodes()) {
             AddressNode lowered;
-            if (node instanceof RawAddressNode || node instanceof OffsetAddressNode) {
+            if (node instanceof OffsetAddressNode) {
                 AddressNode address = (AddressNode) node;
                 lowered = lowering.lower(address);
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -27,16 +27,12 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.Phase;
 
 public class AddressLoweringPhase extends Phase {
 
     public abstract static class AddressLowering {
-
-        public abstract AddressNode lower(ValueNode address);
-
         public abstract AddressNode lower(ValueNode base, ValueNode offset);
     }
 
@@ -51,10 +47,7 @@
     protected void run(StructuredGraph graph) {
         for (Node node : graph.getNodes()) {
             AddressNode lowered;
-            if (node instanceof RawAddressNode) {
-                RawAddressNode address = (RawAddressNode) node;
-                lowered = lowering.lower(address.getAddress());
-            } else if (node instanceof OffsetAddressNode) {
+            if (node instanceof OffsetAddressNode) {
                 OffsetAddressNode address = (OffsetAddressNode) node;
                 lowered = lowering.lower(address.getBase(), address.getOffset());
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,6 +23,7 @@
 package org.graalvm.compiler.phases.common;
 
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
@@ -44,6 +45,7 @@
 import org.graalvm.compiler.nodes.ControlSinkNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StartNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -153,6 +155,10 @@
         new Instance(context, workingSet, newNodesMark).apply(graph, dumpGraph);
     }
 
+    public NodeView getNodeView() {
+        return NodeView.DEFAULT;
+    }
+
     private final class Instance extends Phase {
 
         private final Mark newNodesMark;
@@ -260,9 +266,9 @@
             if (node instanceof ValueNode) {
                 ValueNode valueNode = (ValueNode) node;
                 boolean improvedStamp = tryInferStamp(valueNode);
-                Constant constant = valueNode.stamp().asConstant();
+                Constant constant = valueNode.stamp(NodeView.DEFAULT).asConstant();
                 if (constant != null && !(node instanceof ConstantNode)) {
-                    ConstantNode stampConstant = ConstantNode.forConstant(valueNode.stamp(), constant, context.getMetaAccess(), graph);
+                    ConstantNode stampConstant = ConstantNode.forConstant(valueNode.stamp(NodeView.DEFAULT), constant, context.getMetaAccess(), graph);
                     debug.log("Canonicalizer: constant stamp replaces %1s with %1s", valueNode, stampConstant);
                     valueNode.replaceAtUsages(InputType.Value, stampConstant);
                     GraphUtil.tryKillUnused(valueNode);
@@ -442,14 +448,16 @@
             return false;
         }
 
-        private final class Tool implements SimplifierTool {
+        private final class Tool implements SimplifierTool, NodeView {
 
             private final Assumptions assumptions;
             private final OptionValues options;
+            private NodeView nodeView;
 
             Tool(Assumptions assumptions, OptionValues options) {
                 this.assumptions = assumptions;
                 this.options = options;
+                this.nodeView = getNodeView();
             }
 
             @Override
@@ -513,6 +521,11 @@
             public OptionValues getOptions() {
                 return options;
             }
+
+            @Override
+            public Stamp stamp(ValueNode node) {
+                return nodeView.stamp(node);
+            }
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -58,6 +58,7 @@
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -414,7 +415,7 @@
                     Stamp bestPossibleStamp = null;
                     for (int i = 0; i < phi.valueCount(); ++i) {
                         ValueNode valueAt = phi.valueAt(i);
-                        Stamp curBestStamp = valueAt.stamp();
+                        Stamp curBestStamp = valueAt.stamp(NodeView.DEFAULT);
                         InfoElement infoElement = phiInfoElements.get(merge.forwardEndAt(i));
                         if (infoElement != null) {
                             curBestStamp = curBestStamp.join(infoElement.getStamp());
@@ -427,7 +428,7 @@
                         }
                     }
 
-                    Stamp oldStamp = phi.stamp();
+                    Stamp oldStamp = phi.stamp(NodeView.DEFAULT);
                     if (oldStamp.tryImproveWith(bestPossibleStamp) != null) {
 
                         // Need to be careful to not run into stamp update cycles with the iterative
@@ -460,7 +461,7 @@
                             ValuePhiNode newPhi = graph.addWithoutUnique(new ValuePhiNode(bestPossibleStamp, merge));
                             for (int i = 0; i < phi.valueCount(); ++i) {
                                 ValueNode valueAt = phi.valueAt(i);
-                                if (bestPossibleStamp.meet(valueAt.stamp()).equals(bestPossibleStamp)) {
+                                if (bestPossibleStamp.meet(valueAt.stamp(NodeView.DEFAULT)).equals(bestPossibleStamp)) {
                                     // Pi not required here.
                                 } else {
                                     InfoElement infoElement = phiInfoElements.get(merge.forwardEndAt(i));
@@ -494,7 +495,7 @@
                     InfoElement infoElement = this.getInfoElements(valueAt);
                     while (infoElement != null) {
                         Stamp newStamp = infoElement.getStamp();
-                        if (phi.stamp().tryImproveWith(newStamp) != null) {
+                        if (phi.stamp(NodeView.DEFAULT).tryImproveWith(newStamp) != null) {
                             if (mergeMap == null) {
                                 mergeMap = EconomicMap.create();
                                 mergeMaps.put(merge, mergeMap);
@@ -547,7 +548,7 @@
                              * It's equivalent to or'ing in the mask value since those values are
                              * known to be set.
                              */
-                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp()).getOr();
+                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT)).getOr();
                             IntegerStamp newStampX = (IntegerStamp) op.foldStamp(getSafeStamp(andX), getOtherSafeStamp(y));
                             registerNewStamp(andX, newStampX, guard);
                         }
@@ -580,7 +581,7 @@
                 if (y.isConstant()) {
                     InfoElement infoElement = getInfoElements(x);
                     while (infoElement != null) {
-                        Stamp result = binary.foldStamp(infoElement.stamp, y.stamp());
+                        Stamp result = binary.foldStamp(infoElement.stamp, y.stamp(NodeView.DEFAULT));
                         if (result != null) {
                             return Pair.create(infoElement, result);
                         }
@@ -597,7 +598,7 @@
          * registered info elements is in the same chain of pi nodes.
          */
         private static Stamp getSafeStamp(ValueNode x) {
-            return x.stamp();
+            return x.stamp(NodeView.DEFAULT);
         }
 
         /**
@@ -610,9 +611,9 @@
          */
         private static Stamp getOtherSafeStamp(ValueNode x) {
             if (x.isConstant()) {
-                return x.stamp();
+                return x.stamp(NodeView.DEFAULT);
             }
-            return x.stamp().unrestricted();
+            return x.stamp(NodeView.DEFAULT).unrestricted();
         }
 
         /**
@@ -777,7 +778,7 @@
                 ValueNode y = binaryOpLogicNode.getY();
                 infoElement = getInfoElements(x);
                 while (infoElement != null) {
-                    TriState result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp());
+                    TriState result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp(NodeView.DEFAULT));
                     if (result.isKnown()) {
                         return rewireGuards(infoElement.getGuard(), result.toBoolean(), infoElement.getProxifiedInput(), infoElement.getStamp(), rewireGuardFunction);
                     }
@@ -787,7 +788,7 @@
                 if (y.isConstant()) {
                     Pair<InfoElement, Stamp> foldResult = recursiveFoldStampFromInfo(x);
                     if (foldResult != null) {
-                        TriState result = binaryOpLogicNode.tryFold(foldResult.getRight(), y.stamp());
+                        TriState result = binaryOpLogicNode.tryFold(foldResult.getRight(), y.stamp(NodeView.DEFAULT));
                         if (result.isKnown()) {
                             return rewireGuards(foldResult.getLeft().getGuard(), result.toBoolean(), foldResult.getLeft().getProxifiedInput(), foldResult.getRight(), rewireGuardFunction);
                         }
@@ -795,7 +796,7 @@
                 } else {
                     infoElement = getInfoElements(y);
                     while (infoElement != null) {
-                        TriState result = binaryOpLogicNode.tryFold(x.stamp(), infoElement.getStamp());
+                        TriState result = binaryOpLogicNode.tryFold(x.stamp(NodeView.DEFAULT), infoElement.getStamp());
                         if (result.isKnown()) {
                             return rewireGuards(infoElement.getGuard(), result.toBoolean(), infoElement.getProxifiedInput(), infoElement.getStamp(), rewireGuardFunction);
                         }
@@ -815,8 +816,8 @@
                     if (binary.getY().isConstant()) {
                         infoElement = getInfoElements(binary.getX());
                         while (infoElement != null) {
-                            Stamp newStampX = binary.foldStamp(infoElement.getStamp(), binary.getY().stamp());
-                            TriState result = binaryOpLogicNode.tryFold(newStampX, y.stamp());
+                            Stamp newStampX = binary.foldStamp(infoElement.getStamp(), binary.getY().stamp(NodeView.DEFAULT));
+                            TriState result = binaryOpLogicNode.tryFold(newStampX, y.stamp(NodeView.DEFAULT));
                             if (result.isKnown()) {
                                 return rewireGuards(infoElement.getGuard(), result.toBoolean(), infoElement.getProxifiedInput(), newStampX, rewireGuardFunction);
                             }
@@ -834,7 +835,7 @@
                              * It's equivalent to or'ing in the mask value since those values are
                              * known to be set.
                              */
-                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp()).getOr();
+                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT)).getOr();
                             IntegerStamp newStampX = (IntegerStamp) op.foldStamp(getSafeStamp(and.getX()), getOtherSafeStamp(y));
                             if (foldPendingTest(thisGuard, and.getX(), newStampX, rewireGuardFunction)) {
                                 return true;
@@ -899,7 +900,7 @@
                 do {
                     counterStampsRegistered.increment(debug);
                     debug.log("\t Saving stamp for node %s stamp %s guarded by %s", value, stamp, guard);
-                    assert value instanceof LogicNode || stamp.isCompatible(value.stamp()) : stamp + " vs. " + value.stamp() + " (" + value + ")";
+                    assert value instanceof LogicNode || stamp.isCompatible(value.stamp(NodeView.DEFAULT)) : stamp + " vs. " + value.stamp(NodeView.DEFAULT) + " (" + value + ")";
                     map.setAndGrow(value, new InfoElement(stamp, guard, proxiedValue, map.getAndGrow(value)));
                     undoOperations.push(value);
                     if (value instanceof StampInverter) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ShortCircuitOrNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -68,15 +69,15 @@
         StructuredGraph graph = normalize.graph();
         ValueNode x = normalize.getX();
         ValueNode y = normalize.getY();
-        if (x.stamp() instanceof FloatStamp) {
-            equalComp = graph.addOrUniqueWithInputs(FloatEqualsNode.create(x, y));
-            lessComp = graph.addOrUniqueWithInputs(FloatLessThanNode.create(x, y, normalize.isUnorderedLess()));
+        if (x.stamp(NodeView.DEFAULT) instanceof FloatStamp) {
+            equalComp = graph.addOrUniqueWithInputs(FloatEqualsNode.create(x, y, NodeView.DEFAULT));
+            lessComp = graph.addOrUniqueWithInputs(FloatLessThanNode.create(x, y, normalize.isUnorderedLess(), NodeView.DEFAULT));
         } else {
-            equalComp = graph.addOrUniqueWithInputs(IntegerEqualsNode.create(x, y));
-            lessComp = graph.addOrUniqueWithInputs(IntegerLessThanNode.create(x, y));
+            equalComp = graph.addOrUniqueWithInputs(IntegerEqualsNode.create(x, y, NodeView.DEFAULT));
+            lessComp = graph.addOrUniqueWithInputs(IntegerLessThanNode.create(x, y, NodeView.DEFAULT));
         }
 
-        Stamp stamp = normalize.stamp();
+        Stamp stamp = normalize.stamp(NodeView.DEFAULT);
         ConditionalNode equalValue = graph.unique(
                         new ConditionalNode(equalComp, ConstantNode.forIntegerStamp(stamp, 0, graph), ConstantNode.forIntegerStamp(stamp, 1, graph)));
         ConditionalNode value = graph.unique(new ConditionalNode(lessComp, ConstantNode.forIntegerStamp(stamp, -1, graph), equalValue));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -115,7 +116,7 @@
                 replaceCurrent(fixedAccess);
             } else if (node instanceof PiNode) {
                 PiNode piNode = (PiNode) node;
-                if (piNode.stamp().isCompatible(piNode.getOriginalNode().stamp())) {
+                if (piNode.stamp(NodeView.DEFAULT).isCompatible(piNode.getOriginalNode().stamp(NodeView.DEFAULT))) {
                     // Pi nodes are no longer necessary at this point.
                     piNode.replaceAndDelete(piNode.getOriginalNode());
                 }
@@ -178,7 +179,7 @@
                                 }
                                 counterConstantInputReplacements.increment(node.getDebug());
                                 ConstantNode stampConstant = ConstantNode.forConstant(bestStamp, constant, metaAccess, graph);
-                                assert stampConstant.stamp().isCompatible(valueNode.stamp());
+                                assert stampConstant.stamp(NodeView.DEFAULT).isCompatible(valueNode.stamp(NodeView.DEFAULT));
                                 replaceInput(p, node, stampConstant);
                                 replacements++;
                             }
@@ -258,7 +259,7 @@
                                 bestStamp = bestStamp.meet(currentEndMap.get(phi));
                             }
 
-                            if (!bestStamp.equals(phi.stamp())) {
+                            if (!bestStamp.equals(phi.stamp(NodeView.DEFAULT))) {
                                 endMap.put(phi, bestStamp);
                             }
                         }
@@ -293,7 +294,7 @@
                                     bestStamp = bestStamp.meet(otherEndsStamp);
                                 }
 
-                                if (nodeWithNewStamp.stamp().tryImproveWith(bestStamp) == null) {
+                                if (nodeWithNewStamp.stamp(NodeView.DEFAULT).tryImproveWith(bestStamp) == null) {
                                     // No point in registering the stamp.
                                 } else {
                                     endMap.put(nodeWithNewStamp, bestStamp);
@@ -462,7 +463,7 @@
             ValueNode originalNode = value;
             StampElement currentStamp = stampMap.getAndGrow(originalNode);
             if (currentStamp == null) {
-                return value.stamp();
+                return value.stamp(NodeView.DEFAULT);
             }
             return currentStamp.getStamp();
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NonNullParametersPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NonNullParametersPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.phases.Phase;
@@ -39,8 +40,8 @@
     protected void run(StructuredGraph graph) {
         Stamp nonNull = StampFactory.objectNonNull();
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
-            if (param.stamp() instanceof ObjectStamp) {
-                ObjectStamp paramStamp = (ObjectStamp) param.stamp();
+            if (param.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
+                ObjectStamp paramStamp = (ObjectStamp) param.stamp(NodeView.DEFAULT);
                 param.setStamp(paramStamp.join(nonNull));
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -160,7 +160,7 @@
             return 10;
         } else if (node instanceof Access) {
             return 2;
-        } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) {
+        } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof NotNode) {
             return 1;
         } else if (node instanceof IntegerDivRemNode || node instanceof FloatDivNode || node instanceof RemNode) {
             return 10;
@@ -168,7 +168,7 @@
             return 3;
         } else if (node instanceof Invoke) {
             return 5;
-        } else if (node instanceof IfNode || node instanceof SafepointNode) {
+        } else if (node instanceof IfNode || node instanceof SafepointNode || node instanceof BinaryNode) {
             return 1;
         } else if (node instanceof SwitchNode) {
             return node.successors().count();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Thu Dec 07 11:54:55 2017 +0000
@@ -69,6 +69,7 @@
 import org.graalvm.compiler.nodes.KillingBeginNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
@@ -827,7 +828,7 @@
         if (newReceiver.getStackKind() == JavaKind.Object) {
 
             if (invoke.getInvokeKind() == InvokeKind.Special) {
-                Stamp paramStamp = newReceiver.stamp();
+                Stamp paramStamp = newReceiver.stamp(NodeView.DEFAULT);
                 Stamp stamp = paramStamp.join(StampFactory.object(TypeReference.create(graph.getAssumptions(), callTarget.targetMethod().getDeclaringClass())));
                 if (!stamp.equals(paramStamp)) {
                     // The verifier and previous optimizations guarantee unconditionally that the
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -191,7 +192,7 @@
 
         PhiNode returnValuePhi = null;
         if (invoke.asNode().getStackKind() != JavaKind.Void) {
-            returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp().unrestricted(), returnMerge));
+            returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
         }
 
         AbstractMergeNode exceptionMerge = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -111,9 +112,9 @@
     private void createGuard(StructuredGraph graph, Providers providers) {
         ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
         LoadHubNode receiverHub = graph.unique(new LoadHubNode(providers.getStampProvider(), nonNullReceiver));
-        ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(), providers.getConstantReflection().asObjectHub(type), providers.getMetaAccess(), graph);
+        ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(NodeView.DEFAULT), providers.getConstantReflection().asObjectHub(type), providers.getMetaAccess(), graph);
 
-        LogicNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub, providers.getConstantReflection());
+        LogicNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub, providers.getConstantReflection(), NodeView.DEFAULT);
         FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
         assert invoke.predecessor() != null;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@@ -120,8 +121,8 @@
     }
 
     private static Stamp improvedStamp(ValueNode arg, ParameterNode param) {
-        Stamp joinedStamp = param.stamp().join(arg.stamp());
-        if (joinedStamp == null || joinedStamp.equals(param.stamp())) {
+        Stamp joinedStamp = param.stamp(NodeView.DEFAULT).join(arg.stamp(NodeView.DEFAULT));
+        if (joinedStamp == null || joinedStamp.equals(param.stamp(NodeView.DEFAULT))) {
             return null;
         }
         return joinedStamp;
@@ -162,7 +163,7 @@
                     parameterUsages = trackParameterUsages(param, parameterUsages);
                     // collect param usages before replacing the param
                     param.replaceAtUsagesAndDelete(graph.unique(
-                                    ConstantNode.forConstant(arg.stamp(), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
+                                    ConstantNode.forConstant(arg.stamp(NodeView.DEFAULT), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
                     // param-node gone, leaving a gap in the sequence given by param.index()
                 } else {
                     Stamp impro = improvedStamp(arg, param);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Thu Dec 07 11:54:55 2017 +0000
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.CallTargetNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -192,10 +193,10 @@
         assert callTarget.invokeKind().isIndirect();
 
         ResolvedJavaType holder = targetMethod.getDeclaringClass();
-        if (!(callTarget.receiver().stamp() instanceof ObjectStamp)) {
+        if (!(callTarget.receiver().stamp(NodeView.DEFAULT) instanceof ObjectStamp)) {
             return null;
         }
-        ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp();
+        ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp(NodeView.DEFAULT);
         if (receiverStamp.alwaysNull()) {
             // Don't inline if receiver is known to be null
             return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/InferStamps.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/InferStamps.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -50,9 +51,9 @@
         for (Node n : graph.getNodes()) {
             if (n instanceof ValuePhiNode) {
                 ValueNode node = (ValueNode) n;
-                if (node.stamp() instanceof ObjectStamp) {
-                    assert node.stamp().hasValues() : "We assume all Phi and Proxy stamps are legal before the analysis";
-                    node.setStamp(node.stamp().empty());
+                if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
+                    assert node.stamp(NodeView.DEFAULT).hasValues() : "We assume all Phi and Proxy stamps are legal before the analysis";
+                    node.setStamp(node.stamp(NodeView.DEFAULT).empty());
                 }
             }
         }
@@ -71,7 +72,7 @@
             for (Node n : graph.getNodes()) {
                 if (n instanceof ValueNode) {
                     ValueNode node = (ValueNode) n;
-                    if (node.stamp() instanceof ObjectStamp) {
+                    if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
                         stampChanged |= node.inferStamp();
                     }
                 }
@@ -90,7 +91,8 @@
         for (Node n : graph.getNodes()) {
             if (n instanceof ValuePhiNode) {
                 ValueNode node = (ValueNode) n;
-                assert node.stamp().hasValues() : "Stamp is empty after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
+                assert node.stamp(
+                                NodeView.DEFAULT).hasValues() : "Stamp is empty after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
             }
         }
         return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.nodes.ControlSinkNode;
 import org.graalvm.compiler.nodes.EndNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.UnwindNode;
@@ -52,7 +53,7 @@
                     singleResult = result;
                 } else if (phiResult == null) {
                     /* Found a second result value, so create phi node. */
-                    phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp().unrestricted(), merge));
+                    phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp(NodeView.DEFAULT).unrestricted(), merge));
                     for (int i = 0; i < merge.forwardEndCount(); i++) {
                         phiResult.addInput(singleResult);
                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodes.CallTargetNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
@@ -234,7 +235,7 @@
 
     protected void verifyDumpObjectParameter(StructuredGraph callerGraph, MethodCallTargetNode debugCallTarget, ValueNode arg, ResolvedJavaMethod verifiedCallee, Integer dumpLevel)
                     throws org.graalvm.compiler.phases.VerifyPhase.VerificationError {
-        ResolvedJavaType argType = ((ObjectStamp) arg.stamp()).type();
+        ResolvedJavaType argType = ((ObjectStamp) arg.stamp(NodeView.DEFAULT)).type();
         if (metaAccess.lookupJavaType(Graph.class).isAssignableFrom(argType)) {
             verifyStructuredGraphDumping(callerGraph, debugCallTarget, verifiedCallee, dumpLevel);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyUsageWithEquals.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyUsageWithEquals.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -80,7 +81,7 @@
      * Determines whether the type of {@code node} is assignable to the {@link #restrictedClass}.
      */
     private boolean isAssignableToRestrictedType(ValueNode node, MetaAccessProvider metaAccess) {
-        if (node.stamp() instanceof ObjectStamp) {
+        if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
             ResolvedJavaType restrictedType = metaAccess.lookupJavaType(restrictedClass);
             ResolvedJavaType nodeType = StampTool.typeOrNull(node);
             if (nodeType == null && node instanceof LoadFieldNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyVirtualizableUsage.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyVirtualizableUsage.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
@@ -81,7 +82,7 @@
         int i = 0;
         for (Node arg : arguments) {
             if (i >= startIdx) {
-                Stamp argStamp = ((ValueNode) arg).stamp();
+                Stamp argStamp = ((ValueNode) arg).stamp(NodeView.DEFAULT);
                 if (argStamp instanceof ObjectStamp) {
                     ObjectStamp objectStamp = (ObjectStamp) argStamp;
                     ResolvedJavaType argStampType = objectStamp.type();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -92,7 +92,7 @@
 
     @Override
     public void beginGroup(DebugContext debug, String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) throws IOException {
-        output.beginGroup(new GraphInfo(debug, null), name, shortName, method, bci, properties);
+        output.beginGroup(new GraphInfo(debug, null), name, shortName, method, bci, DebugContext.addVersionProperties(properties));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -48,7 +49,7 @@
     public static final NodeClass<AArch64CountLeadingZerosNode> TYPE = NodeClass.create(AArch64CountLeadingZerosNode.class);
 
     public AArch64CountLeadingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
     }
 
     @Override
@@ -57,7 +58,7 @@
     }
 
     private static Stamp computeStamp(Stamp newStamp, ValueNode theValue) {
-        assert newStamp.isCompatible(theValue.stamp());
+        assert newStamp.isCompatible(theValue.stamp(NodeView.DEFAULT));
         assert theValue.getStackKind() == JavaKind.Int || theValue.getStackKind() == JavaKind.Long;
         return StampTool.stampForLeadingZeros((IntegerStamp) newStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -50,7 +51,7 @@
     public static final NodeClass<AArch64CountTrailingZerosNode> TYPE = NodeClass.create(AArch64CountTrailingZerosNode.class);
 
     public AArch64CountTrailingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -60,7 +61,7 @@
     }
 
     static Stamp computeStamp(Stamp newStamp, ValueNode value) {
-        assert newStamp.isCompatible(value.stamp());
+        assert newStamp.isCompatible(value.stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         return StampTool.stampForTrailingZeros(valueStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.RemNode;
@@ -63,7 +64,7 @@
     }
 
     public void lower(RemNode node, LoweringTool tool) {
-        JavaKind kind = node.stamp().getStackKind();
+        JavaKind kind = node.stamp(NodeView.DEFAULT).getStackKind();
         assert kind == JavaKind.Float || kind == JavaKind.Double;
         if (node instanceof SafeNode) {
             // We already introduced the necessary checks, nothing to do.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FixedBinaryNode;
@@ -84,7 +85,7 @@
     }
 
     public void lower(FixedBinaryNode node, LoweringTool tool) {
-        JavaKind kind = node.stamp().getStackKind();
+        JavaKind kind = node.stamp(NodeView.DEFAULT).getStackKind();
         assert kind == JavaKind.Int || kind == JavaKind.Long;
         SnippetTemplate.SnippetInfo snippet;
         if (node instanceof SafeNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.SignExtendNode;
@@ -66,7 +67,7 @@
         AArch64LIRGenerator lirgen = (AArch64LIRGenerator) gen.getLIRGeneratorTool();
         AArch64ArithmeticLIRGenerator arithgen = (AArch64ArithmeticLIRGenerator) lirgen.getArithmetic();
         AArch64Kind readKind = (AArch64Kind) lirgen.getLIRKind(accessStamp).getPlatformKind();
-        int resultBits = ((IntegerStamp) stamp()).getBits();
+        int resultBits = ((IntegerStamp) stamp(NodeView.DEFAULT)).getBits();
         gen.setResult(this, arithgen.emitExtendMemory(isSigned, readKind, resultBits, (AArch64AddressValue) gen.operand(getAddress()), gen.state(this)));
     }
 
@@ -86,7 +87,7 @@
 
         AddressNode address = readNode.getAddress();
         LocationIdentity location = readNode.getLocationIdentity();
-        Stamp stamp = usage.stamp();
+        Stamp stamp = usage.stamp(NodeView.DEFAULT);
         GuardingNode guard = readNode.getGuard();
         BarrierType barrierType = readNode.getBarrierType();
         boolean nullCheck = readNode.getNullCheck();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -50,7 +51,7 @@
     public static final NodeClass<AMD64CountLeadingZerosNode> TYPE = NodeClass.create(AMD64CountLeadingZerosNode.class);
 
     public AMD64CountLeadingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -60,7 +61,7 @@
     }
 
     private static Stamp computeStamp(Stamp newStamp, ValueNode theValue) {
-        assert newStamp.isCompatible(theValue.stamp());
+        assert newStamp.isCompatible(theValue.stamp(NodeView.DEFAULT));
         assert theValue.getStackKind() == JavaKind.Int || theValue.getStackKind() == JavaKind.Long;
         return StampTool.stampForLeadingZeros((IntegerStamp) newStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -50,7 +51,7 @@
     public static final NodeClass<AMD64CountTrailingZerosNode> TYPE = NodeClass.create(AMD64CountTrailingZerosNode.class);
 
     public AMD64CountTrailingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -60,7 +61,7 @@
     }
 
     static Stamp computeStamp(Stamp newStamp, ValueNode value) {
-        assert newStamp.isCompatible(value.stamp());
+        assert newStamp.isCompatible(value.stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         return StampTool.stampForTrailingZeros(valueStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64RoundNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64RoundNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -52,7 +53,7 @@
     private final RoundingMode mode;
 
     public AMD64RoundNode(ValueNode value, RoundingMode mode) {
-        super(TYPE, roundStamp((FloatStamp) value.stamp(), mode), value);
+        super(TYPE, roundStamp((FloatStamp) value.stamp(NodeView.DEFAULT), mode), value);
         this.mode = mode;
     }
 
@@ -83,7 +84,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return roundStamp((FloatStamp) newStamp, mode);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.replacements.test;
 
+import org.graalvm.compiler.nodes.NodeView;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Test;
@@ -83,7 +84,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountIntSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 24), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 24), result.stamp(NodeView.DEFAULT));
     }
 
     public static int bitCountIntEmptySnippet(int v) {
@@ -97,7 +98,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountIntEmptySnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 24), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 24), result.stamp(NodeView.DEFAULT));
     }
 
     @Test
@@ -117,7 +118,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountLongSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 40), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 40), result.stamp(NodeView.DEFAULT));
     }
 
     public static int bitCountLongEmptySnippet(long v) {
@@ -131,7 +132,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountLongEmptySnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 40), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 40), result.stamp(NodeView.DEFAULT));
     }
 
     /*
@@ -155,7 +156,7 @@
     @Test
     public void testScanForwardInt() {
         ValueNode result = parseAndInline("scanForwardIntSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 4, 8), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 4, 8), result.stamp(NodeView.DEFAULT));
     }
 
     public static int scanForwardLongConstantSnippet() {
@@ -175,7 +176,7 @@
     @Test
     public void testScanForwardLong() {
         ValueNode result = parseAndInline("scanForwardLongSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 32), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 32), result.stamp(NodeView.DEFAULT));
     }
 
     public static int scanForwardLongEmptySnippet(long v) {
@@ -187,7 +188,7 @@
     @Test
     public void testScanForwardLongEmpty() {
         ValueNode result = parseAndInline("scanForwardLongEmptySnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp(NodeView.DEFAULT));
     }
 
     /*
@@ -213,7 +214,7 @@
         /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */
         ValueNode result = parseAndInline("scanReverseIntSnippet", BitScanReverseNode.class);
         if (result != null) {
-            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 16, 20), result.stamp());
+            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 16, 20), result.stamp(NodeView.DEFAULT));
         }
     }
 
@@ -238,7 +239,7 @@
         /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */
         ValueNode result = parseAndInline("scanReverseLongSnippet", BitScanReverseNode.class);
         if (result != null) {
-            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 48, 64), result.stamp());
+            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 48, 64), result.stamp(NodeView.DEFAULT));
         }
     }
 
@@ -253,7 +254,7 @@
         /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */
         ValueNode result = parseAndInline("scanReverseLongEmptySnippet", BitScanReverseNode.class);
         if (result != null) {
-            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp());
+            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp(NodeView.DEFAULT));
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ReturnNode;
@@ -95,7 +96,7 @@
         ValueNode node = findNode(graph);
         boolean overflowExpected = node instanceof IntegerExactArithmeticNode;
 
-        IntegerStamp resultStamp = (IntegerStamp) node.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) node.stamp(NodeView.DEFAULT);
         operation.verifyOverflow(lowerBoundA, upperBoundA, lowerBoundB, upperBoundB, bits, overflowExpected, resultStamp);
     }
 
@@ -120,7 +121,7 @@
         ValueNode node = findNode(graph);
         boolean overflowExpected = node instanceof IntegerExactArithmeticSplitNode;
 
-        IntegerStamp resultStamp = (IntegerStamp) node.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) node.stamp(NodeView.DEFAULT);
         operation.verifyOverflow(lowerBoundA, upperBoundA, lowerBoundB, upperBoundB, bits, overflowExpected, resultStamp);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
@@ -50,8 +51,12 @@
  */
 public abstract class MethodSubstitutionTest extends GraalCompilerTest {
 
+    protected StructuredGraph testGraph(final String snippet) {
+        return testGraph(snippet, null);
+    }
+
     @SuppressWarnings("try")
-    protected StructuredGraph testGraph(final String snippet) {
+    protected StructuredGraph testGraph(final String snippet, String name) {
         DebugContext debug = getDebugContext();
         try (DebugContext.Scope s = debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
@@ -69,7 +74,20 @@
                 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
             }
             assertNotInGraph(graph, MacroNode.class);
-            assertNotInGraph(graph, Invoke.class);
+            if (name != null) {
+                for (Node node : graph.getNodes()) {
+                    if (node instanceof Invoke) {
+                        Invoke invoke = (Invoke) node;
+                        if (invoke.callTarget() instanceof MethodCallTargetNode) {
+                            MethodCallTargetNode call = (MethodCallTargetNode) invoke.callTarget();
+                            assertTrue(!call.targetMethod().getName().equals(name), "Unexpected invoke of intrinsic %s", call.targetMethod());
+                        }
+                    }
+
+                }
+            } else {
+                assertNotInGraph(graph, Invoke.class);
+            }
             return graph;
         } catch (Throwable e) {
             throw debug.handle(e);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MonitorTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MonitorTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -221,7 +221,8 @@
      * Reproduces issue reported in https://github.com/graalvm/graal-core/issues/201. The stamp in
      * the PiNode returned by {@link BoxingSnippets#longValueOf} was overwritten when the node was
      * subsequently canonicalized because {@code PiNode.computeValue()} ignored the
-     * {@link ValueNode#stamp()} field and used the {@code PiNode.piStamp} field.
+     * {@link ValueNode#stamp(org.graalvm.compiler.nodes.NodeView)} field and used the
+     * {@code PiNode.piStamp} field.
      */
     @Test
     public void test8() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@@ -93,7 +94,7 @@
 
     private static void assertRead(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity) {
         JavaReadNode read = (JavaReadNode) graph.start().next();
-        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
+        Assert.assertEquals(kind.getStackKind(), read.stamp(NodeView.DEFAULT).getStackKind());
 
         OffsetAddressNode address = (OffsetAddressNode) read.getAddress();
         Assert.assertEquals(graph.getParameter(0), address.getBase());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@@ -105,12 +106,12 @@
         WordCastNode cast = (WordCastNode) graph.start().next();
 
         JavaReadNode read = (JavaReadNode) cast.next();
-        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
+        Assert.assertEquals(kind.getStackKind(), read.stamp(NodeView.DEFAULT).getStackKind());
 
         OffsetAddressNode address = (OffsetAddressNode) read.getAddress();
         Assert.assertEquals(cast, address.getBase());
         Assert.assertEquals(graph.getParameter(0), cast.getInput());
-        Assert.assertEquals(target.wordJavaKind, cast.stamp().getStackKind());
+        Assert.assertEquals(target.wordJavaKind, cast.stamp(NodeView.DEFAULT).getStackKind());
 
         Assert.assertEquals(locationIdentity, read.getLocationIdentity());
 
@@ -137,7 +138,7 @@
         OffsetAddressNode address = (OffsetAddressNode) write.getAddress();
         Assert.assertEquals(cast, address.getBase());
         Assert.assertEquals(graph.getParameter(0), cast.getInput());
-        Assert.assertEquals(target.wordJavaKind, cast.stamp().getStackKind());
+        Assert.assertEquals(target.wordJavaKind, cast.stamp(NodeView.DEFAULT).getStackKind());
 
         Assert.assertEquals(locationIdentity, write.getLocationIdentity());
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SystemArrayCopyTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ *
+ * 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.graalvm.compiler.replacements.test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static java.lang.reflect.Modifier.isStatic;
+
+@RunWith(Parameterized.class)
+public class SystemArrayCopyTest extends GraalCompilerTest {
+
+    @Parameter(0) public Object src;
+    @Parameter(1) public Object dst;
+    @Parameter(2) public int len;
+    @Parameter(3) public String name;
+
+    @Parameters(name = "{3}")
+    public static Collection<Object[]> data() {
+        Object[] srcs = {new int[4], new double[4], new Integer[4], new Number[4], new String[4], new Object[]{"Graal", 0, 0, 0}, new Object()};
+        Object[] dsts = {new int[4], new Number[4]};
+        int[] lens = {-1, 0, 2, 8};
+
+        ArrayList<Object[]> ret = new ArrayList<>(srcs.length * dsts.length * lens.length);
+        for (Object src : srcs) {
+            for (Object dst : dsts) {
+                for (int length : lens) {
+                    ret.add(new Object[]{src, dst, length, src.getClass().getSimpleName() + ", 0, " + dst.getClass().getSimpleName() + ", 0, " + length});
+                }
+            }
+        }
+        return ret;
+    }
+
+    public static void testArrayCopySnippet(Object src, Object dst, int length) {
+        System.arraycopy(src, 0, dst, 0, length);
+    }
+
+    private static final int PARAMETER_LENGTH = 3;
+    private Object[] argsToBind;
+
+    @Test
+    public void testArrayCopy() {
+        ResolvedJavaMethod method = getResolvedJavaMethod("testArrayCopySnippet");
+        Object receiver = method.isStatic() ? null : this;
+        Object[] args = {src, dst, len};
+
+        Result expect = executeExpected(method, receiver, args);
+        testAgainstExpected(method, expect, receiver, args);
+
+        // test composition of constant binding
+        for (int i = 1; i < (1 << PARAMETER_LENGTH); i++) {
+            argsToBind = new Object[PARAMETER_LENGTH];
+            for (int j = 0; j < PARAMETER_LENGTH; j++) {
+                if ((i & (1 << j)) != 0) {
+                    argsToBind[j] = args[j];
+                }
+            }
+            testAgainstExpected(method, expect, receiver, args);
+        }
+    }
+
+    @Override
+    protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
+        StructuredGraph graph = super.parse(builder, graphBuilderSuite);
+        if (argsToBind != null) {
+            ResolvedJavaMethod m = graph.method();
+            Object receiver = isStatic(m.getModifiers()) ? null : this;
+            Object[] args = argsWithReceiver(receiver, argsToBind);
+            JavaType[] parameterTypes = m.toParameterTypes();
+            assert parameterTypes.length == args.length;
+            for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
+                int index = param.index();
+                if (args[index] != null) {
+                    JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[index].getJavaKind(), args[index]);
+                    ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
+                    param.replaceAtUsages(replacement);
+                }
+            }
+        }
+        return graph;
+    }
+
+    @Override
+    protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
+        return super.getCode(method, graph, true, installAsDefault, options);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Thu Dec 07 11:54:55 2017 +0000
@@ -58,6 +58,7 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -113,7 +114,6 @@
 import org.graalvm.compiler.nodes.memory.WriteNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -247,7 +247,7 @@
                     indexOfSnippets.lower(node, tool);
                 }
             };
-            SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Char), n.stamp(), n.toArgumentArray());
+            SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Char), n.stamp(NodeView.DEFAULT), n.toArgumentArray());
             n.graph().add(snippetLower);
             n.graph().replaceFixedWithFixed(n, snippetLower);
         }
@@ -347,7 +347,7 @@
         ResolvedJavaField field = loadField.field();
         ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object();
         object = createNullCheckedValue(object, loadField, tool);
-        Stamp loadStamp = loadStamp(loadField.stamp(), getStorageKind(field));
+        Stamp loadStamp = loadStamp(loadField.stamp(NodeView.DEFAULT), getStorageKind(field));
 
         AddressNode address = createFieldAddress(graph, object, field);
         assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName();
@@ -419,7 +419,7 @@
         ValueNode array = loadIndexed.array();
         array = createNullCheckedValue(array, loadIndexed, tool);
         JavaKind elementKind = loadIndexed.elementKind();
-        Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind);
+        Stamp loadStamp = loadStamp(loadIndexed.stamp(NodeView.DEFAULT), elementKind);
 
         GuardingNode boundsCheck = getBoundsCheck(loadIndexed, array, tool);
         AddressNode address = createArrayIndexAddress(graph, array, elementKind, loadIndexed.index(), boundsCheck);
@@ -575,7 +575,7 @@
 
     protected AddressNode createUnsafeAddress(StructuredGraph graph, ValueNode object, ValueNode offset) {
         if (object.isConstant() && object.asConstant().isDefaultForKind()) {
-            return graph.unique(new RawAddressNode(offset));
+            return graph.addOrUniqueWithInputs(OffsetAddressNode.create(offset));
         } else {
             return graph.unique(new OffsetAddressNode(object, offset));
         }
@@ -584,7 +584,7 @@
     protected ReadNode createUnsafeRead(StructuredGraph graph, RawLoadNode load, GuardingNode guard) {
         boolean compressible = load.accessKind() == JavaKind.Object;
         JavaKind readKind = load.accessKind();
-        Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible);
+        Stamp loadStamp = loadStamp(load.stamp(NodeView.DEFAULT), readKind, compressible);
         AddressNode address = createUnsafeAddress(graph, load.object(), load.offset());
         ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, BarrierType.NONE));
         if (guard == null) {
@@ -603,8 +603,8 @@
         StructuredGraph graph = load.graph();
         JavaKind readKind = load.getKind();
         assert readKind != JavaKind.Object;
-        Stamp loadStamp = loadStamp(load.stamp(), readKind, false);
-        AddressNode address = graph.unique(new RawAddressNode(load.getAddress()));
+        Stamp loadStamp = loadStamp(load.stamp(NodeView.DEFAULT), readKind, false);
+        AddressNode address = graph.addOrUniqueWithInputs(OffsetAddressNode.create(load.getAddress()));
         ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, BarrierType.NONE));
         // An unsafe read must not float otherwise it may float above
         // a test guaranteeing the read is safe.
@@ -639,7 +639,7 @@
         assert store.getValue().getStackKind() != JavaKind.Object;
         JavaKind valueKind = store.getKind();
         ValueNode value = implicitStoreConvert(graph, valueKind, store.getValue(), false);
-        AddressNode address = graph.unique(new RawAddressNode(store.getAddress()));
+        AddressNode address = graph.addOrUniqueWithInputs(OffsetAddressNode.create(store.getAddress()));
         WriteNode write = graph.add(new WriteNode(address, store.getLocationIdentity(), value, BarrierType.NONE));
         write.setStateAfter(store.stateAfter());
         graph.replaceFixedWithFixed(store, write);
@@ -648,7 +648,7 @@
     protected void lowerJavaReadNode(JavaReadNode read) {
         StructuredGraph graph = read.graph();
         JavaKind valueKind = read.getReadKind();
-        Stamp loadStamp = loadStamp(read.stamp(), valueKind, read.isCompressible());
+        Stamp loadStamp = loadStamp(read.stamp(NodeView.DEFAULT), valueKind, read.isCompressible());
 
         ReadNode memoryRead = graph.add(new ReadNode(read.getAddress(), read.getLocationIdentity(), loadStamp, read.getBarrierType()));
         GuardingNode guard = read.getGuard();
@@ -1041,7 +1041,7 @@
             arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
         }
 
-        LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength);
+        LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength, NodeView.DEFAULT);
         if (boundsCheck.isTautology()) {
             return null;
         }
@@ -1060,7 +1060,7 @@
         if (nullCheck == null) {
             return object;
         }
-        return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
+        return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp(NodeView.DEFAULT)).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
     }
 
     @Override
@@ -1069,10 +1069,10 @@
         ValueNode offset = ((OffsetAddressNode) address).getOffset();
 
         int base = arrayBaseOffset(elementKind);
-        ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(), base, graph)));
+        ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(NodeView.DEFAULT), base, graph)));
 
         int shift = CodeUtil.log2(arrayScalingFactor(elementKind));
         ValueNode ret = graph.unique(new RightShiftNode(scaledIndex, ConstantNode.forInt(shift, graph)));
-        return IntegerConvertNode.convert(ret, StampFactory.forKind(JavaKind.Int), graph);
+        return IntegerConvertNode.convert(ret, StampFactory.forKind(JavaKind.Int), graph, NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -50,6 +50,7 @@
 import org.graalvm.compiler.nodes.KillingBeginNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
@@ -271,12 +272,12 @@
         int argIndex = 0;
         if (!isStatic) {
             JavaKind expected = asKind(method.getDeclaringClass());
-            JavaKind actual = args[argIndex++].stamp().getStackKind();
+            JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
             assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
         }
         for (int i = 0; i != signature.getParameterCount(false); i++) {
             JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
-            JavaKind actual = args[argIndex++].stamp().getStackKind();
+            JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
             if (expected != actual) {
                 throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ShortCircuitOrNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -183,7 +184,7 @@
             }
             if (condition == null || (!(condition instanceof CompareNode)) || ((CompareNode) condition).getY() != testValue) {
                 // Re-use previously generated condition if the trueValue for the test is the same
-                condition = createCompareNode(result.graph(), Condition.EQ, result, testValue, null);
+                condition = createCompareNode(result.graph(), Condition.EQ, result, testValue, null, NodeView.DEFAULT);
             }
             return condition;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java	Thu Dec 07 11:54:55 2017 +0000
@@ -83,6 +83,10 @@
                     // As such, it needs to recursively inline everything.
                     inlineEverything = args.length != argumentsList.size();
                 }
+                if (inlineEverything && !callTarget.targetMethod().hasBytecodes()) {
+                    // we need to force-inline but we can not, leave the invoke as-is
+                    return false;
+                }
                 b.handleReplacedInvoke(invoke.getInvokeKind(), callTarget.targetMethod(), argumentsList.toArray(new ValueNode[argumentsList.size()]), inlineEverything);
             }
             return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -63,6 +63,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.SimplifyingGraphDecoder;
@@ -583,7 +584,7 @@
             return callTarget.targetMethod();
         }
 
-        SpecialCallTargetCacheKey key = new SpecialCallTargetCacheKey(callTarget.invokeKind(), callTarget.targetMethod(), invokeData.contextType, callTarget.receiver().stamp());
+        SpecialCallTargetCacheKey key = new SpecialCallTargetCacheKey(callTarget.invokeKind(), callTarget.targetMethod(), invokeData.contextType, callTarget.receiver().stamp(NodeView.DEFAULT));
         Object specialCallTarget = specialCallTargetCache.get(key);
         if (specialCallTarget == null) {
             specialCallTarget = MethodCallTargetNode.devirtualizeCall(key.invokeKind, key.targetMethod, key.contextType, graph.getAssumptions(),
@@ -1066,7 +1067,7 @@
                 assert !methodScope.isInlinedMethod();
                 GraphBuilderContext graphBuilderContext = new PENonAppendGraphBuilderContext(methodScope, null);
                 Node result = parameterPlugin.interceptParameter(graphBuilderContext, param.index(),
-                                StampPair.create(param.stamp(), param.uncheckedStamp()));
+                                StampPair.create(param.stamp(NodeView.DEFAULT), param.uncheckedStamp()));
                 if (result != null) {
                     return result;
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Thu Dec 07 11:54:55 2017 +0000
@@ -83,6 +83,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode.Placeholder;
@@ -750,7 +751,7 @@
                         nodeReplacements.put(parameter, placeholder);
                         placeholders[i] = placeholder;
                     } else if (args.info.isNonNullParameter(i)) {
-                        parameter.setStamp(parameter.stamp().join(StampFactory.objectNonNull()));
+                        parameter.setStamp(parameter.stamp(NodeView.DEFAULT).join(StampFactory.objectNonNull()));
                     }
                 }
             }
@@ -785,7 +786,8 @@
                             if (usage instanceof LoadIndexedNode) {
                                 LoadIndexedNode loadIndexed = (LoadIndexedNode) usage;
                                 debug.dump(DebugContext.INFO_LEVEL, snippetCopy, "Before replacing %s", loadIndexed);
-                                LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(new LoadSnippetVarargParameterNode(params, loadIndexed.index(), loadIndexed.stamp()));
+                                LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(
+                                                new LoadSnippetVarargParameterNode(params, loadIndexed.index(), loadIndexed.stamp(NodeView.DEFAULT)));
                                 snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);
                                 debug.dump(DebugContext.INFO_LEVEL, snippetCopy, "After replacing %s", loadIndexed);
                             } else if (usage instanceof StoreIndexedNode) {
@@ -829,7 +831,7 @@
             for (Node node : snippetCopy.getNodes()) {
                 if (node instanceof ValueNode) {
                     ValueNode valueNode = (ValueNode) node;
-                    if (valueNode.stamp() == PlaceholderStamp.singleton()) {
+                    if (valueNode.stamp(NodeView.DEFAULT) == PlaceholderStamp.singleton()) {
                         curPlaceholderStampedNodes.add(valueNode);
                     }
                 }
@@ -1502,7 +1504,7 @@
     private void updateStamps(ValueNode replacee, UnmodifiableEconomicMap<Node, Node> duplicates) {
         for (ValueNode node : placeholderStampedNodes) {
             ValueNode dup = (ValueNode) duplicates.get(node);
-            Stamp replaceeStamp = replacee.stamp();
+            Stamp replaceeStamp = replacee.stamp(NodeView.DEFAULT);
             if (node instanceof Placeholder) {
                 Placeholder placeholderDup = (Placeholder) dup;
                 placeholderDup.makeReplacement(replaceeStamp);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Thu Dec 07 11:54:55 2017 +0000
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.nodes.DeoptimizeNode;
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AbsNode;
@@ -296,14 +297,14 @@
         r.register2("divideUnsigned", type, type, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) {
-                b.push(kind, b.append(new UnsignedDivNode(dividend, divisor).canonical(null)));
+                b.push(kind, b.append(UnsignedDivNode.create(dividend, divisor, NodeView.DEFAULT)));
                 return true;
             }
         });
         r.register2("remainderUnsigned", type, type, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) {
-                b.push(kind, b.append(new UnsignedRemNode(dividend, divisor).canonical(null)));
+                b.push(kind, b.append(UnsignedRemNode.create(dividend, divisor, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -344,14 +345,14 @@
         r.register1("floatToRawIntBits", float.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Int, b.append(new ReinterpretNode(JavaKind.Int, value).canonical(null)));
+                b.push(JavaKind.Int, b.append(ReinterpretNode.create(JavaKind.Int, value, NodeView.DEFAULT)));
                 return true;
             }
         });
         r.register1("intBitsToFloat", int.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Float, b.append(new ReinterpretNode(JavaKind.Float, value).canonical(null)));
+                b.push(JavaKind.Float, b.append(ReinterpretNode.create(JavaKind.Float, value, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -362,14 +363,14 @@
         r.register1("doubleToRawLongBits", double.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Long, b.append(new ReinterpretNode(JavaKind.Long, value).canonical(null)));
+                b.push(JavaKind.Long, b.append(ReinterpretNode.create(JavaKind.Long, value, NodeView.DEFAULT)));
                 return true;
             }
         });
         r.register1("longBitsToDouble", long.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Double, b.append(new ReinterpretNode(JavaKind.Double, value).canonical(null)));
+                b.push(JavaKind.Double, b.append(ReinterpretNode.create(JavaKind.Double, value, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -421,7 +422,7 @@
         r.register1("sqrt", Double.TYPE, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Double, b.append(new SqrtNode(value).canonical(null)));
+                b.push(JavaKind.Double, b.append(SqrtNode.create(value, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -470,7 +471,7 @@
                 cond = cond.negate();
             }
 
-            LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs);
+            LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs, NodeView.DEFAULT);
             b.addPush(JavaKind.Boolean, new ConditionalNode(compare, trueValue, falseValue));
             return true;
         }
@@ -521,7 +522,7 @@
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                 ValueNode object = receiver.get();
-                ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), GraphUtil.originalValue(object));
+                ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object));
                 if (folded != null) {
                     b.addPush(JavaKind.Object, folded);
                 } else {
@@ -892,7 +893,8 @@
                         } else if (falseCount == 0 || trueCount == 0) {
                             boolean expected = falseCount == 0;
                             LogicNode condition = b.addWithInputs(
-                                            IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected))));
+                                            IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected)),
+                                                            NodeView.DEFAULT));
                             b.append(new FixedGuardNode(condition, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, true));
                             newResult = b.add(ConstantNode.forBoolean(expected));
                         } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/Classfile.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/Classfile.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -46,8 +46,8 @@
     private final ResolvedJavaType type;
     private final List<ClassfileBytecode> codeAttributes;
 
-    private static final int MAJOR_VERSION_JAVA7 = 51;
-    private static final int MAJOR_VERSION_JAVA9 = 53;
+    private static final int MAJOR_VERSION_JAVA_MIN = 51;
+    private static final int MAJOR_VERSION_JAVA_MAX = 54;
     private static final int MAGIC = 0xCAFEBABE;
 
     /**
@@ -65,7 +65,7 @@
 
         int minor = stream.readUnsignedShort();
         int major = stream.readUnsignedShort();
-        if (major < MAJOR_VERSION_JAVA7 || major > MAJOR_VERSION_JAVA9) {
+        if (major < MAJOR_VERSION_JAVA_MIN || major > MAJOR_VERSION_JAVA_MAX) {
             throw new UnsupportedClassVersionError("Unsupported class file version: " + major + "." + minor);
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValueNodeUtil;
 import org.graalvm.compiler.nodes.memory.MemoryAccess;
@@ -173,7 +174,7 @@
                             allEqual = false;
                         }
                     }
-                    if (entry1.stamp().alwaysDistinct(entry2.stamp())) {
+                    if (entry1.stamp(NodeView.DEFAULT).alwaysDistinct(entry2.stamp(NodeView.DEFAULT))) {
                         // the contents are different
                         tool.replaceWithValue(ConstantNode.forBoolean(false, graph()));
                         return;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
 import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
@@ -164,8 +165,8 @@
      * Returns true if this copy doesn't require store checks. Trivially true for primitive arrays.
      */
     public boolean isExact() {
-        ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp());
-        ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp());
+        ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp(NodeView.DEFAULT));
+        ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp(NodeView.DEFAULT));
         if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
             return false;
         }
@@ -173,7 +174,7 @@
             return true;
         }
 
-        if (StampTool.isExactType(getDestination().stamp())) {
+        if (StampTool.isExactType(getDestination().stamp(NodeView.DEFAULT))) {
             if (destType != null && destType.isAssignableFrom(srcType)) {
                 return true;
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.LoadFieldNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -65,7 +66,7 @@
     }
 
     protected Stamp computeStamp(ValueNode object) {
-        Stamp objectStamp = object.stamp();
+        Stamp objectStamp = object.stamp(NodeView.DEFAULT);
         if (objectStamp instanceof ObjectStamp) {
             objectStamp = objectStamp.join(StampFactory.objectNonNull());
         }
@@ -116,7 +117,7 @@
                 tool.replaceWithVirtual(newVirtual);
             }
         } else {
-            ResolvedJavaType type = getConcreteType(originalAlias.stamp());
+            ResolvedJavaType type = getConcreteType(originalAlias.stamp(NodeView.DEFAULT));
             if (type != null && !type.isArray()) {
                 VirtualInstanceNode newVirtual = createVirtualInstanceNode(type, true);
                 ResolvedJavaField[] fields = newVirtual.getFields();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryNode;
 import org.graalvm.compiler.nodes.calc.FloatDivNode;
@@ -86,13 +87,13 @@
 
     @Override
     public Stamp foldStamp(Stamp stampX, Stamp stampY) {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 
     protected BinaryMathIntrinsicNode(ValueNode forX, ValueNode forY, BinaryOperation op) {
         super(TYPE, StampFactory.forKind(JavaKind.Double), forX, forY);
-        assert forX.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(forX.stamp()) == 64;
-        assert forY.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(forY.stamp()) == 64;
+        assert forX.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(forX.stamp(NodeView.DEFAULT)) == 64;
+        assert forY.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(forY.stamp(NodeView.DEFAULT)) == 64;
         this.operation = op;
     }
 
@@ -118,6 +119,7 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode c = tryConstantFold(forX, forY, getOperation());
         if (c != null) {
             return c;
@@ -150,8 +152,8 @@
             }
 
             // x**0.5 = sqrt(x)
-            if (yValue == 0.5D && x.stamp() instanceof FloatStamp && ((FloatStamp) x.stamp()).lowerBound() >= 0.0D) {
-                return new SqrtNode(x);
+            if (yValue == 0.5D && x.stamp(view) instanceof FloatStamp && ((FloatStamp) x.stamp(view)).lowerBound() >= 0.0D) {
+                return SqrtNode.create(x, view);
             }
         }
         return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -48,7 +49,7 @@
     public static final NodeClass<BitCountNode> TYPE = NodeClass.create(BitCountNode.class);
 
     public BitCountNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -59,7 +60,7 @@
     }
 
     static Stamp computeStamp(Stamp newStamp, ValueNode theValue) {
-        assert newStamp.isCompatible(theValue.stamp());
+        assert newStamp.isCompatible(theValue.stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         assert (valueStamp.downMask() & CodeUtil.mask(valueStamp.getBits())) == valueStamp.downMask();
         assert (valueStamp.upMask() & CodeUtil.mask(valueStamp.getBits())) == valueStamp.upMask();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -53,13 +54,13 @@
     public static final NodeClass<BitScanForwardNode> TYPE = NodeClass.create(BitScanForwardNode.class);
 
     public BitScanForwardNode(ValueNode value) {
-        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp(NodeView.DEFAULT)).getBits()), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         int min;
         int max;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -53,13 +54,13 @@
     public static final NodeClass<BitScanReverseNode> TYPE = NodeClass.create(BitScanReverseNode.class);
 
     public BitScanReverseNode(ValueNode value) {
-        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp(NodeView.DEFAULT)).getBits()), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         int min;
         int max;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.GuardNode;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -263,7 +264,7 @@
                 // Try to get the most accurate receiver type
                 if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
                     ValueNode receiver = getReceiver(originalArguments);
-                    TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp());
+                    TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp(NodeView.DEFAULT));
                     if (receiverType != null) {
                         concreteMethod = receiverType.getType().findUniqueConcreteMethod(target);
                     }
@@ -317,7 +318,7 @@
              * type information anyway.
              */
             if (targetType != null && !targetType.getType().isPrimitive() && !argument.getStackKind().isPrimitive()) {
-                ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp());
+                ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp(NodeView.DEFAULT));
                 if (argumentType == null || (argumentType.isAssignableFrom(targetType.getType()) && !argumentType.equals(targetType.getType()))) {
                     LogicNode inst = InstanceOfNode.createAllowNull(targetType, argument, null, null);
                     assert !inst.isAlive();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -82,7 +83,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool generator) {
-        LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         Value result = register.asValue(kind);
         if (incoming) {
             generator.getLIRGeneratorTool().emitIncomingValues(new Value[]{result});
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReverseBytesNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReverseBytesNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -54,7 +55,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         if (getStackKind() == JavaKind.Int) {
             long mask = CodeUtil.mask(JavaKind.Int.getBitCount());
@@ -62,7 +63,7 @@
         } else if (getStackKind() == JavaKind.Long) {
             return IntegerStamp.stampForMask(valueStamp.getBits(), Long.reverse(valueStamp.downMask()), Long.reverse(valueStamp.upMask()));
         } else {
-            return stamp();
+            return stamp(NodeView.DEFAULT);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -106,8 +107,8 @@
     }
 
     protected UnaryMathIntrinsicNode(ValueNode value, UnaryOperation op) {
-        super(TYPE, computeStamp(value.stamp(), op), value);
-        assert value.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp()) == 64;
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), op), value);
+        assert value.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp(NodeView.DEFAULT)) == 64;
         this.operation = op;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -54,8 +55,8 @@
 
     public IntegerAddExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+        setStamp(x.stamp(NodeView.DEFAULT).unrestricted());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
     @Override
@@ -132,7 +133,7 @@
                 return forX;
             }
         }
-        if (!IntegerStamp.addCanOverflow((IntegerStamp) forX.stamp(), (IntegerStamp) forY.stamp())) {
+        if (!IntegerStamp.addCanOverflow((IntegerStamp) forX.stamp(NodeView.DEFAULT), (IntegerStamp) forY.stamp(NodeView.DEFAULT))) {
             return new AddNode(forX, forY).canonical(tool);
         }
         return this;
@@ -159,7 +160,7 @@
 
     @Override
     public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerAddExactSplitNode(stamp(), getX(), getY(), next, deopt));
+        return graph().add(new IntegerAddExactSplitNode(stamp(NodeView.DEFAULT), getX(), getY(), next, deopt));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -49,7 +50,8 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (!IntegerStamp.addCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        NodeView view = NodeView.from(tool);
+        if (!IntegerStamp.addCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
             tool.deleteBranch(overflowSuccessor);
             tool.addToWorkList(next);
             AddNode replacement = graph().unique(new AddNode(x, y));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -48,8 +49,8 @@
 
     public IntegerMulExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+        setStamp(x.stamp(NodeView.DEFAULT).unrestricted());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
     @Override
@@ -76,10 +77,10 @@
                 return forX;
             }
             if (c == 0) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
             }
         }
-        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(NodeView.DEFAULT), (IntegerStamp) y.stamp(NodeView.DEFAULT))) {
             return new MulNode(x, y).canonical(tool);
         }
         return this;
@@ -104,7 +105,7 @@
 
     @Override
     public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerMulExactSplitNode(stamp(), getX(), getY(), next, deopt));
+        return graph().add(new IntegerMulExactSplitNode(stamp(NodeView.DEFAULT), getX(), getY(), next, deopt));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -51,7 +52,8 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        NodeView view = NodeView.from(tool);
+        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
             tool.deleteBranch(overflowSuccessor);
             tool.addToWorkList(next);
             MulNode replacement = graph().unique(new MulNode(x, y));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulHighNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulHighNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -81,7 +82,7 @@
             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
                 long i = ((PrimitiveConstant) c).asLong();
                 if (i == 0 || i == 1) {
-                    return ConstantNode.forIntegerStamp(self.stamp(), 0);
+                    return ConstantNode.forIntegerStamp(self.stamp(NodeView.DEFAULT), 0);
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -49,8 +50,8 @@
 
     public IntegerSubExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+        setStamp(x.stamp(NodeView.DEFAULT).unrestricted());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
     @Override
@@ -67,7 +68,7 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forIntegerStamp(stamp(), 0);
+            return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
         }
         if (forX.isConstant() && forY.isConstant()) {
             return canonicalXYconstant(forX, forY);
@@ -77,7 +78,7 @@
                 return forX;
             }
         }
-        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(NodeView.DEFAULT), (IntegerStamp) y.stamp(NodeView.DEFAULT))) {
             return new SubNode(x, y).canonical(tool);
         }
         return this;
@@ -102,7 +103,7 @@
 
     @Override
     public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerSubExactSplitNode(stamp(), getX(), getY(), next, deopt));
+        return graph().add(new IntegerSubExactSplitNode(stamp(NodeView.DEFAULT), getX(), getY(), next, deopt));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -49,7 +50,8 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        NodeView view = NodeView.from(tool);
+        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
             tool.deleteBranch(overflowSuccessor);
             tool.addToWorkList(next);
             SubNode replacement = graph().unique(new SubNode(x, y));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -81,7 +82,7 @@
             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
                 long i = ((PrimitiveConstant) c).asLong();
                 if (i == 0 || i == 1) {
-                    return ConstantNode.forIntegerStamp(self.stamp(), 0);
+                    return ConstantNode.forIntegerStamp(self.stamp(NodeView.DEFAULT), 0);
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java	Thu Dec 07 11:54:55 2017 +0000
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -228,7 +229,8 @@
      */
     public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) {
         assert node != null && replacement != null : node + " " + replacement;
-        assert node.stamp().isCompatible(replacement.stamp()) : "Replacement node stamp not compatible " + node.stamp() + " vs " + replacement.stamp();
+        assert node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " +
+                        replacement.stamp(NodeView.DEFAULT);
         add("replace at usages", (graph, obsoleteNodes) -> {
             assert node.isAlive();
             ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement);
@@ -244,8 +246,8 @@
              * to improve the stamp information of the read. Such a read might later be replaced
              * with a read with a less precise stamp.
              */
-            if (!node.stamp().equals(replacementNode.stamp())) {
-                replacementNode = graph.unique(new PiNode(replacementNode, node.stamp()));
+            if (!node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
+                replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT)));
             }
             node.replaceAtUsages(replacementNode);
             if (node instanceof FixedWithNextNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
@@ -127,7 +128,7 @@
             VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
             for (int i = 0; i < instance.entryCount(); i++) {
                 JavaKind declaredKind = instance.field(i).getJavaKind();
-                if (declaredKind == stampToJavaKind(values.get(i).stamp())) {
+                if (declaredKind == stampToJavaKind(values.get(i).stamp(NodeView.DEFAULT))) {
                     // We won't cache unaligned field writes upon instantiation unless we add
                     // support for non-array objects in PEReadEliminationClosure.processUnsafeLoad.
                     readCache.put(new ReadCacheEntry(new FieldLocationIdentity(instance.field(i)), representation, -1, declaredKind, false), values.get(i));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java	Thu Dec 07 11:54:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
@@ -189,7 +190,7 @@
                 ValueNode object = GraphUtil.unproxify(load.object());
                 LocationIdentity location = NamedLocationIdentity.getArrayLocation(componentKind);
                 ValueNode cachedValue = state.getReadCache(object, location, index, accessKind, this);
-                assert cachedValue == null || load.stamp().isCompatible(cachedValue.stamp()) : "The RawLoadNode's stamp is not compatible with the cached value.";
+                assert cachedValue == null || load.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT)) : "The RawLoadNode's stamp is not compatible with the cached value.";
                 if (cachedValue != null) {
                     effects.replaceAtUsages(load, cachedValue, load);
                     addScalarAlias(load, cachedValue);
@@ -399,7 +400,7 @@
                     // e.g. unsafe loads / stores with different access kinds have different stamps
                     // although location, object and offset are the same, in this case we cannot
                     // create a phi nor can we set a common value
-                    if (otherValue == null || !value.stamp().isCompatible(otherValue.stamp())) {
+                    if (otherValue == null || !value.stamp(NodeView.DEFAULT).isCompatible(otherValue.stamp(NodeView.DEFAULT))) {
                         value = null;
                         phi = false;
                         break;
@@ -409,11 +410,11 @@
                     }
                 }
                 if (phi) {
-                    PhiNode phiNode = getPhi(key, value.stamp().unrestricted());
+                    PhiNode phiNode = getPhi(key, value.stamp(NodeView.DEFAULT).unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
                         ValueNode v = states.get(i).getReadCache(key.object, key.identity, key.index, key.kind, PEReadEliminationClosure.this);
-                        assert phiNode.stamp().isCompatible(v.stamp()) : "Cannot create read elimination phi for inputs with incompatible stamps.";
+                        assert phiNode.stamp(NodeView.DEFAULT).isCompatible(v.stamp(NodeView.DEFAULT)) : "Cannot create read elimination phi for inputs with incompatible stamps.";
                         setPhiInput(phiNode, i, v);
                     }
                     newState.readCache.put(key, phiNode);
@@ -444,13 +445,13 @@
                     ValueNode value = states.get(i).getReadCache(getPhiValueAt(phi, i), identity, index, kind, PEReadEliminationClosure.this);
                     // e.g. unsafe loads / stores with same identity and different access kinds see
                     // mergeReadCache(states)
-                    if (value == null || !values[i - 1].stamp().isCompatible(value.stamp())) {
+                    if (value == null || !values[i - 1].stamp(NodeView.DEFAULT).isCompatible(value.stamp(NodeView.DEFAULT))) {
                         return;
                     }
                     values[i] = value;
                 }
 
-                PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index, kind, overflowAccess), values[0].stamp().unrestricted());
+                PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index, kind, overflowAccess), values[0].stamp(NodeView.DEFAULT).unrestricted());
                 mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
                 for (int i = 0; i < values.length; i++) {
                     setPhiInput(phiNode, i, values[i]);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Thu Dec 07 11:54:55 2017 +0000
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -877,12 +878,12 @@
                         if (phis[valueIndex] == null) {
                             ValueNode field = states[i].getObjectState(getObject.applyAsInt(i)).getEntry(valueIndex);
                             if (values[valueIndex] != field) {
-                                phis[valueIndex] = createValuePhi(values[valueIndex].stamp().unrestricted());
+                                phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
                             }
                         }
                     }
-                    if (phis[valueIndex] != null && !phis[valueIndex].stamp().isCompatible(values[valueIndex].stamp())) {
-                        phis[valueIndex] = createValuePhi(values[valueIndex].stamp().unrestricted());
+                    if (phis[valueIndex] != null && !phis[valueIndex].stamp(NodeView.DEFAULT).isCompatible(values[valueIndex].stamp(NodeView.DEFAULT))) {
+                        phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
                     }
                     if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
                         // skip an entry after a long/double value that occupies two int slots
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java	Thu Dec 07 11:54:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -97,7 +98,7 @@
                 LoadCacheEntry identifier = new LoadCacheEntry(object, new FieldLocationIdentity(access.field()));
                 ValueNode cachedValue = state.getCacheEntry(identifier);
                 if (node instanceof LoadFieldNode) {
-                    if (cachedValue != null && access.stamp().isCompatible(cachedValue.stamp())) {
+                    if (cachedValue != null && access.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT))) {
                         effects.replaceAtUsages(access, cachedValue, access);
                         addScalarAlias(access, cachedValue);
                         deleted = true;
@@ -196,7 +197,7 @@
     }
 
     private static boolean areValuesReplaceable(ValueNode originalValue, ValueNode replacementValue, boolean considerGuards) {
-        return originalValue.stamp().isCompatible(replacementValue.stamp()) &&
+        return originalValue.stamp(NodeView.DEFAULT).isCompatible(replacementValue.stamp(NodeView.DEFAULT)) &&
                         (!considerGuards || (getGuard(originalValue) == null || getGuard(originalValue) == getGuard(replacementValue)));
     }
 
@@ -269,7 +270,7 @@
                     // E.g. unsafe loads / stores with different access kinds have different stamps
                     // although location, object and offset are the same. In this case we cannot
                     // create a phi nor can we set a common value.
-                    if (otherValue == null || !value.stamp().isCompatible(otherValue.stamp())) {
+                    if (otherValue == null || !value.stamp(NodeView.DEFAULT).isCompatible(otherValue.stamp(NodeView.DEFAULT))) {
                         value = null;
                         phi = false;
                         break;
@@ -279,11 +280,11 @@
                     }
                 }
                 if (phi) {
-                    PhiNode phiNode = getCachedPhi(key, value.stamp().unrestricted());
+                    PhiNode phiNode = getCachedPhi(key, value.stamp(NodeView.DEFAULT).unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
                         ValueNode v = states.get(i).getCacheEntry(key);
-                        assert phiNode.stamp().isCompatible(v.stamp()) : "Cannot create read elimination phi for inputs with incompatible stamps.";
+                        assert phiNode.stamp(NodeView.DEFAULT).isCompatible(v.stamp(NodeView.DEFAULT)) : "Cannot create read elimination phi for inputs with incompatible stamps.";
                         setPhiInput(phiNode, i, v);
                     }
                     newState.addCacheEntry(key, phiNode);
@@ -315,14 +316,14 @@
                     ValueNode value = states.get(i).getCacheEntry(identifier.duplicateWithObject(getPhiValueAt(phi, i)));
                     // e.g. unsafe loads / stores with same identity and different access kinds see
                     // mergeReadCache(states)
-                    if (value == null || !values[i - 1].stamp().isCompatible(value.stamp())) {
+                    if (value == null || !values[i - 1].stamp(NodeView.DEFAULT).isCompatible(value.stamp(NodeView.DEFAULT))) {
                         return;
                     }
                     values[i] = value;
                 }
 
                 CacheEntry<?> newIdentifier = identifier.duplicateWithObject(phi);
-                PhiNode phiNode = getCachedPhi(newIdentifier, values[0].stamp().unrestricted());
+                PhiNode phiNode = getCachedPhi(newIdentifier, values[0].stamp(NodeView.DEFAULT).unrestricted());
                 mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
                 for (int i = 0; i < values.length; i++) {
                     setPhiInput(phiNode, i, values[i]);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
@@ -179,7 +180,7 @@
                 } else if (oldValue.getStackKind() == JavaKind.Double || oldValue.getStackKind() == JavaKind.Long) {
                     // Splitting double word constant by storing over it with an int
                     getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing second half of double word value %s", current, oldValue);
-                    ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false);
+                    ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false, NodeView.DEFAULT);
                     addNode(secondHalf);
                     state.setEntry(virtual.getObjectId(), index + 1, secondHalf);
                 }
@@ -188,7 +189,7 @@
                 // Storing into second half of double, so replace previous value
                 ValueNode previous = getEntry(virtual, index - 1);
                 getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing first half of double word value %s", current, previous);
-                ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true);
+                ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true, NodeView.DEFAULT);
                 addNode(firstHalf);
                 state.setEntry(virtual.getObjectId(), index - 1, firstHalf);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java	Thu Dec 07 11:54:55 2017 +0000
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -73,17 +74,17 @@
     }
 
     public static WordCastNode addressToWord(ValueNode input, JavaKind wordKind) {
-        assert input.stamp() instanceof AbstractPointerStamp;
+        assert input.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input);
     }
 
     public static WordCastNode objectToTrackedPointer(ValueNode input, JavaKind wordKind) {
-        assert input.stamp() instanceof ObjectStamp;
+        assert input.stamp(NodeView.DEFAULT) instanceof ObjectStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input, true);
     }
 
     public static WordCastNode objectToUntrackedPointer(ValueNode input, JavaKind wordKind) {
-        assert input.stamp() instanceof ObjectStamp;
+        assert input.stamp(NodeView.DEFAULT) instanceof ObjectStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input, false);
     }
 
@@ -108,13 +109,13 @@
             return input;
         }
 
-        assert !stamp().isCompatible(input.stamp());
+        assert !stamp(NodeView.DEFAULT).isCompatible(input.stamp(NodeView.DEFAULT));
         if (input.isConstant()) {
             /* Null pointers are uncritical for GC, so they can be constant folded. */
             if (input.asJavaConstant().isNull()) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
             } else if (input.asJavaConstant().getJavaKind().isNumericInteger() && input.asJavaConstant().asLong() == 0) {
-                return ConstantNode.forConstant(stamp(), JavaConstant.NULL_POINTER, tool.getMetaAccess());
+                return ConstantNode.forConstant(stamp(NodeView.DEFAULT), JavaConstant.NULL_POINTER, tool.getMetaAccess());
             }
         }
 
@@ -124,7 +125,7 @@
     @Override
     public void generate(NodeLIRBuilderTool generator) {
         Value value = generator.operand(input);
-        ValueKind<?> kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+        ValueKind<?> kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         assert kind.getPlatformKind().getSizeInBytes() == value.getPlatformKind().getSizeInBytes();
 
         if (trackedPointer && LIRKind.isValue(kind) && !LIRKind.isValue(value)) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,6 +29,7 @@
 
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
 
 import com.sun.source.doctree.DocTree;
 
@@ -115,18 +116,10 @@
         return li;
     }
 
-    /**
-     * Add the member header.
-     *
-     * @param fieldType the class document to be listed
-     * @param fieldTypeStr the string for the field type to be documented
-     * @param fieldDimensions the dimensions of the field string to be added
-     * @param fieldName name of the field to be added
-     * @param contentTree the content tree to which the member header will be added
-     */
+    @Override
     public void addMemberHeader(TypeElement fieldType, String fieldTypeStr,
             String fieldDimensions, String fieldName, Content contentTree) {
-        Content nameContent = new RawHtml(fieldName);
+        Content nameContent = new StringContent(fieldName);
         Content heading = HtmlTree.HEADING(HtmlConstants.MEMBER_HEADING, nameContent);
         contentTree.addContent(heading);
         Content pre = new HtmlTree(HtmlTag.PRE);
@@ -142,6 +135,20 @@
         contentTree.addContent(pre);
     }
 
+    @Override
+    public void addMemberHeader(TypeMirror fieldType, String fieldName, Content contentTree) {
+        Content nameContent = new StringContent(fieldName);
+        Content heading = HtmlTree.HEADING(HtmlConstants.MEMBER_HEADING, nameContent);
+        contentTree.addContent(heading);
+        Content pre = new HtmlTree(HtmlTag.PRE);
+        Content fieldContent = writer.getLink(new LinkInfoImpl(
+                configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType));
+        pre.addContent(fieldContent);
+        pre.addContent(" ");
+        pre.addContent(fieldName);
+        contentTree.addContent(pre);
+    }
+
     /**
      * Add the deprecated information for this member.
      *
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/SerializedFormWriter.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/SerializedFormWriter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,6 +28,7 @@
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
 
 import com.sun.source.doctree.DocTree;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -227,8 +228,8 @@
          * Adds the member header.
          *
          * @param fieldType the type of the field
-         * @param fieldTypeStr the type of the field in string format.  We will
-         * print this out if we can't link to the type
+         * @param fieldTypeStr the type of the field in string format, used
+         *                     only if the type cannot be linked
          * @param fieldDimensions the dimensions of the field
          * @param fieldName the name of the field
          * @param contentTree content tree to which the member header will be added
@@ -237,6 +238,15 @@
             String fieldDimensions, String fieldName, Content contentTree);
 
         /**
+         * Adds the member header.
+         *
+         * @param fieldType the type of the field
+         * @param fieldName the name of the field
+         * @param contentTree content tree to which the member header will be added
+         */
+        public void addMemberHeader(TypeMirror fieldType, String fieldName, Content contentTree);
+
+        /**
          * Check to see if overview details should be printed. If
          * nocomment option set or if there is no text to be printed
          * for deprecation info, inline comment or tags,
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -450,8 +450,7 @@
     protected void buildFieldSubHeader(Content fieldsContentTree) {
         if (!utils.definesSerializableFields(currentTypeElement)) {
             VariableElement field = (VariableElement) currentMember;
-            fieldWriter.addMemberHeader(utils.asTypeElement(field.asType()),
-                    utils.getTypeName(field.asType(), false), utils.getDimension(field.asType()),
+            fieldWriter.addMemberHeader(field.asType(),
                     utils.getSimpleName(field),
                     fieldsContentTree);
         }
--- a/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java	Thu Dec 07 11:54:55 2017 +0000
@@ -69,8 +69,10 @@
             // look it up
             Monitor m = vm.findByName(id.getName());
             if (m == null) {
-                System.err.println("Warning: Unresolved Symbol: "
-                                   + id.getName() + " substituted NaN");
+                if (debug) {
+                    System.err.println("Warning: Unresolved Symbol: "
+                                       + id.getName() + " substituted NaN");
+                }
                 return new Literal(Double.valueOf(Double.NaN));
             }
             if (m.getVariability() == Variability.CONSTANT) {
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Dec 07 11:54:55 2017 +0000
@@ -430,7 +430,7 @@
                                                Set<String> roots)
     {
         if (Objects.requireNonNull(paths).isEmpty()) {
-             throw new IllegalArgumentException("Empty module path");
+             throw new IllegalArgumentException(taskHelper.getMessage("err.empty.module.path"));
         }
 
         Path[] entries = paths.toArray(new Path[0]);
@@ -447,8 +447,13 @@
 
             // java.base version is different than the current runtime version
             version = Runtime.Version.parse(v.toString());
-            if (Runtime.version().major() != version.major()) {
-                finder = ModulePath.of(version, true, entries);
+            if (Runtime.version().major() != version.major() ||
+                Runtime.version().minor() != version.minor()) {
+                // jlink version and java.base version do not match.
+                // We do not (yet) support this mode.
+                throw new IllegalArgumentException(taskHelper.getMessage("err.jlink.version.mismatch",
+                    Runtime.version().major(), Runtime.version().minor(),
+                    version.major(), version.minor()));
             }
         }
 
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Thu Dec 07 11:54:55 2017 +0000
@@ -54,11 +54,8 @@
 public final class GenerateJLIClassesPlugin implements Plugin {
 
     private static final String NAME = "generate-jli-classes";
-    private static final String IGNORE_VERSION = "ignore-version";
 
     private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
-    private static final String IGNORE_VERSION_WARNING = NAME + ".ignore.version.warn";
-    private static final String VERSION_MISMATCH_WARNING = NAME + ".version.mismatch.warn";
 
     private static final String DEFAULT_TRACE_FILE = "default_jli_trace.txt";
 
@@ -85,8 +82,6 @@
 
     String mainArgument;
 
-    boolean ignoreVersion;
-
     public GenerateJLIClassesPlugin() {
     }
 
@@ -170,7 +165,6 @@
     @Override
     public void configure(Map<String, String> config) {
         mainArgument = config.get(NAME);
-        ignoreVersion = Boolean.parseBoolean(config.get(IGNORE_VERSION));
     }
 
     public void initialize(ResourcePool in) {
@@ -208,26 +202,6 @@
         }
     }
 
-    private boolean checkVersion(Runtime.Version linkedVersion) {
-        Runtime.Version baseVersion = Runtime.version();
-        if (baseVersion.major() != linkedVersion.major() ||
-                baseVersion.minor() != linkedVersion.minor()) {
-            return false;
-        }
-        return true;
-    }
-
-    private Runtime.Version getLinkedVersion(ResourcePool in) {
-        ModuleDescriptor.Version version = in.moduleView()
-                .findModule("java.base")
-                .get()
-                .descriptor()
-                .version()
-                .orElseThrow(() -> new PluginException("No version defined in "
-                        + "the java.base being linked"));
-         return Runtime.Version.parse(version.toString());
-    }
-
     private void readTraceConfig(Stream<String> lines) {
         // Use TreeSet/TreeMap to keep things sorted in a deterministic
         // order to avoid scrambling the layout on small changes and to
@@ -315,24 +289,6 @@
 
     @Override
     public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
-        if (ignoreVersion) {
-            System.out.println(
-                    PluginsResourceBundle
-                            .getMessage(IGNORE_VERSION_WARNING));
-        } else if (!checkVersion(getLinkedVersion(in))) {
-            // The linked images are not version compatible
-            if (mainArgument != null) {
-                // Log a mismatch warning if an argument was specified
-                System.out.println(
-                        PluginsResourceBundle
-                                .getMessage(VERSION_MISMATCH_WARNING,
-                                            getLinkedVersion(in),
-                                            Runtime.version()));
-            }
-            in.transformAndCopy(entry -> entry, out);
-            return out.build();
-        }
-
         initialize(in);
         // Copy all but DMH_ENTRY to out
         in.transformAndCopy(entry -> {
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties	Thu Dec 07 11:54:55 2017 +0000
@@ -107,6 +107,8 @@
 error.prefix=Error:
 warn.prefix=Warning:
 
+err.empty.module.path=empty module path
+err.jlink.version.mismatch=jlink version {0}.{1} does not match target java.base version {2}.{3}
 err.automatic.module:automatic module cannot be used with jlink: {0} from {1}
 err.unknown.byte.order:unknown byte order {0}
 err.launcher.main.class.empty:launcher main class name cannot be empty: {0}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties	Thu Dec 07 11:54:55 2017 +0000
@@ -75,7 +75,7 @@
 exclude-jmod-section.description=\
 Specify a JMOD section to exclude
 
-generate-jli-classes.argument=@filename[:ignore-version=<true|false>]
+generate-jli-classes.argument=@filename
 
 generate-jli-classes.description=\
 Specify a file listing the java.lang.invoke classes to pre-generate. \n\
@@ -84,15 +84,6 @@
 created then code generation will be disabled by default to guarantee \n\
 correctness - add ignore-version=true to override this.
 
-generate-jli-classes.ignore.version.warn=\
-WARNING: --generate-jli-classes set to ignore version mismatch between \n\
-JDK running jlink and target image.
-
-generate-jli-classes.version.mismatch.warn=\
-WARNING: Pre-generation of JLI classes is only supported when linking \n\
-the same version of java.base ({0}) as the JDK running jlink ({1}), \n\
-class generation skipped - specify ignore-version to override.
-
 system-modules.argument=retainModuleTarget
 
 system-modules.description=Fast loading of module descriptors (always enabled)
--- a/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -70,10 +70,8 @@
 import javax.rmi.ssl.SslRMIClientSocketFactory;
 import javax.rmi.ssl.SslRMIServerSocketFactory;
 import javax.security.auth.Subject;
-
 import com.sun.jmx.remote.internal.rmi.RMIExporter;
 import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
-
 import jdk.internal.agent.Agent;
 import jdk.internal.agent.AgentConfigurationError;
 import static jdk.internal.agent.AgentConfigurationError.*;
@@ -102,6 +100,7 @@
         public static final String USE_REGISTRY_SSL = "false";
         public static final String USE_AUTHENTICATION = "true";
         public static final String PASSWORD_FILE_NAME = "jmxremote.password";
+        public static final String HASH_PASSWORDS = "true";
         public static final String ACCESS_FILE_NAME = "jmxremote.access";
         public static final String SSL_NEED_CLIENT_AUTH = "false";
     }
@@ -129,6 +128,8 @@
                 "com.sun.management.jmxremote.authenticate";
         public static final String PASSWORD_FILE_NAME =
                 "com.sun.management.jmxremote.password.file";
+        public static final String HASH_PASSWORDS
+                = "com.sun.management.jmxremote.password.toHashes";
         public static final String ACCESS_FILE_NAME =
                 "com.sun.management.jmxremote.access.file";
         public static final String LOGIN_CONFIG_NAME =
@@ -412,6 +413,7 @@
 
         String loginConfigName = null;
         String passwordFileName = null;
+        boolean shouldHashPasswords = true;
         String accessFileName = null;
 
         // Initialize settings when authentication is active
@@ -426,6 +428,11 @@
                 passwordFileName =
                         props.getProperty(PropertyNames.PASSWORD_FILE_NAME,
                         getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));
+                String hashPasswords
+                        = props.getProperty(PropertyNames.HASH_PASSWORDS,
+                                DefaultValues.HASH_PASSWORDS);
+                shouldHashPasswords = Boolean.parseBoolean(hashPasswords);
+
                 checkPasswordFile(passwordFileName);
             }
 
@@ -474,7 +481,7 @@
                     sslConfigFileName, enabledCipherSuitesList,
                     enabledProtocolsList, sslNeedClientAuth,
                     useAuthentication, loginConfigName,
-                    passwordFileName, accessFileName, bindAddress, jmxRmiFilter);
+                    passwordFileName, shouldHashPasswords, accessFileName, bindAddress, jmxRmiFilter);
             cs = data.jmxConnectorServer;
             url = data.jmxRemoteURL;
             config("startRemoteConnectorServer",
@@ -569,6 +576,10 @@
             throw new AgentConfigurationError(PASSWORD_FILE_NOT_READABLE, passwordFileName);
         }
 
+        if(!file.canWrite() && PropertyNames.HASH_PASSWORDS.equalsIgnoreCase("true")) {
+            logger.log(Level.WARNING, "");
+        }
+
         FileSystem fs = FileSystem.open();
         try {
             if (fs.supportsFileSecurity(file)) {
@@ -729,6 +740,7 @@
             boolean useAuthentication,
             String loginConfigName,
             String passwordFileName,
+            boolean shouldHashPasswords,
             String accessFileName,
             String bindAddress,
             String jmxRmiFilter)
@@ -761,6 +773,9 @@
             if (passwordFileName != null) {
                 env.put("jmx.remote.x.password.file", passwordFileName);
             }
+            if (shouldHashPasswords) {
+                env.put("jmx.remote.x.password.toHashes", "true");
+            }
 
             env.put("jmx.remote.x.access.file", accessFileName);
 
--- a/src/jdk.management.agent/share/conf/jmxremote.password.template	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.management.agent/share/conf/jmxremote.password.template	Thu Dec 07 11:54:55 2017 +0000
@@ -3,11 +3,12 @@
 #
 # o Copy this template to jmxremote.password
 # o Set the user/password entries in jmxremote.password
-# o Change the permission of jmxremote.password to read-only
-#   by the owner.
+# o Change the permission of jmxremote.password to be accessible
+#   only by the owner.
+# o The jmxremote.passwords file will be re-written by the server
+#   to replace all plain text passwords with hashed passwords when
+#   the file is read by the server.
 #
-# See below for the location of jmxremote.password file.
-# ----------------------------------------------------------------------
 
 ##############################################################
 #        Password File for Remote JMX Monitoring
@@ -24,41 +25,91 @@
 # the management config file $JRE/conf/management/management.properties
 # or by specifying a system property (See that file for details).
 
-
 ##############################################################
-#    File permissions of the jmxremote.password file
+#    File format of the jmxremote.password file
 ##############################################################
-#      Since there are cleartext passwords stored in this file,
-#      this file must be readable by ONLY the owner,
-#      otherwise the program will exit with an error.
 #
-# The file format for password and access files is syntactically the same
-# as the Properties file format.  The syntax is described in the Javadoc
-# for java.util.Properties.load.
-# Typical password file has multiple  lines, where each line is blank,
+# The file contains multiple lines where each line is blank,
 # a comment (like this one), or a password entry.
 #
+# password entry follows the below syntax
+#   role_name W [clearPassword|hashedPassword]
 #
-# A password entry consists of a role name and an associated
-# password.  The role name is any string that does not itself contain
-# spaces or tabs.  The password is again any string that does not
-# contain spaces or tabs.  Note that passwords appear in the clear in
-# this file, so it is a good idea not to use valuable passwords.
+# role_name is any string that does not itself contain spaces or tabs.
+# W = spaces or tabs
+#
+# Passwords can be specified via clear text or via a hash. Clear text password
+# is any string that does not contain spaces or tabs. Hashed passwords must
+# follow the below format.
+# hashedPassword = base64_encoded_64_byte_salt W base64_encoded_hash W hash_algorithm
+# where,
+#   base64_encoded_64_byte_salt = 64 byte random salt
+#   base64_encoded_hash = Hash_algorithm(password + salt)
+#   W = spaces or tabs
+#   hash_algorithm = Algorithm string specified using the format below
+#       https://docs.oracle.com/javase/9/docs/specs/security/standard-names.html#messagedigest-algorithms
+#       This is an optional field. If not specified, SHA3-512 will be assumed.
+#
+# If passwords are in clear, they will be overwritten by their hash if all of
+# the below criteria are met.
+#   * com.sun.management.jmxremote.password.toHashes property is set to true in
+#     management.properties file
+#   * the password file is writable
+#   * the system security policy allows writing into the password file, if a
+#     security manager is configured
+#
+# In order to change the password for a role, replace the hashed password entry
+# with a new clear text password or a new hashed password. If the new password
+# is in clear, it will be replaced with its hash when a new login attempt is made.
 #
 # A given role should have at most one entry in this file.  If a role
 # has no entry, it has no access.
 # If multiple entries are found for the same role name, then the last one
 # is used.
 #
-# In a typical installation, this file can be read by anybody on the
+# A user generated hashed password file can also be used instead of clear-text
+# password file. If generated by the user, hashed passwords must follow the
+# format specified above.
+#
+# Caution: It is recommended not to edit the password file while the
+# agent is running, as edits could be lost if a client connection triggers the
+# hashing of the password file at the same time that the file is externally modified.
+# The integrity of the file is guaranteed, but any external edits made to the
+# file during the short period between the time that the agent reads the file
+# and the time that it writes it back might get lost
+
+##############################################################
+#    File permissions of the jmxremote.password file
+##############################################################
+#       This file must be made accessible by ONLY the owner,
+#       otherwise the program will exit with an error.
+#
+# In a typical installation, this file can be accessed by anybody on the
 # local machine, and possibly by people on other machines.
-# For # security, you should either restrict the access to this file,
+# For security, you should either restrict the access to this file except for owner,
 # or specify another, less accessible file in the management config file
 # as described above.
 #
-# Following are two commented-out entries.  The "measureRole" role has
-# password "QED".  The "controlRole" role has password "R&D".
+# In order to prevent inadverent edits to the password file in the 
+# production environment, it is recommended to deploy a read-only 
+# hashed password file. The hashed entries for clear passwords can be generated 
+# in advance by running the JMX agent.
 #
-# monitorRole  QED
-# controlRole   R&D
 
+##############################################################
+#    Sample of the jmxremote.password file
+##############################################################
+# Following are two commented-out entries.  The "monitorRole" role has
+# password "QED".  The "controlRole" role has password "R&D". This is an example
+# of specifying passwords in the clear
+#
+#   monitorRole  QED
+#   controlRole  R&D
+# 
+# Once a login attempt is made, passwords will be hashed and the file will have 
+# below entries with clear passwords overwritten by their respective 
+# SHA3-512 hash
+#
+#   monitorRole trilby APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512
+#   controlRole roHEJSbRqSSTII4Z4+NOCV2OJaZVQ/dw153Fy2u4ILDP9XiZ426GwzCzc3RtpoqNMwqYIcfdd74xWXSMrWtGaA== w9qDsekgKn0WOVJycDyU0kLBa081zbStcCjUAVEqlfon5Sgx7XHtaodbmzpLegA1jT7Ag36T0zHaEWRHJe2fdA== SHA3-512
+# 
\ No newline at end of file
--- a/src/jdk.management.agent/share/conf/management.properties	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.management.agent/share/conf/management.properties	Thu Dec 07 11:54:55 2017 +0000
@@ -301,6 +301,17 @@
 # com.sun.management.jmxremote.password.file=filepath
 
 #
+# ################# Hash passwords in password file ##############
+# com.sun.management.jmxremote.password.toHashes = true|false
+#      Default for this property is true.
+#      Specifies if passwords in the password file should be hashed or not.
+#      If this property is true, and if the password file is writable, and if the 
+#      system security policy allows writing into the password file,
+#      all the clear passwords in the password file will be replaced by
+#      their SHA3-512 hash when the file is read by the server
+#
+
+#
 # ################ RMI Access file location #####################
 #
 # com.sun.management.jmxremote.access.file=filepath
--- a/src/jdk.rmic/share/classes/sun/tools/java/RuntimeConstants.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/jdk.rmic/share/classes/sun/tools/java/RuntimeConstants.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -67,7 +67,7 @@
     /* Class File Constants */
     int JAVA_MAGIC                   = 0xcafebabe;
     int JAVA_MIN_SUPPORTED_VERSION   = 45;
-    int JAVA_MAX_SUPPORTED_VERSION   = 53;
+    int JAVA_MAX_SUPPORTED_VERSION   = 54;
     int JAVA_MAX_SUPPORTED_MINOR_VERSION = 0;
 
     /* Generate class file version for 1.1  by default */
--- a/src/utils/IdealGraphVisualizer/nbproject/platform.properties	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/utils/IdealGraphVisualizer/nbproject/platform.properties	Thu Dec 07 11:54:55 2017 +0000
@@ -6,7 +6,7 @@
 nbplatform.active.dir=${suite.dir}/nbplatform
 nbplatform.default.netbeans.dest.dir=${suite.dir}/nbplatform
 nbplatform.default.harness.dir=${nbplatform.default.netbeans.dest.dir}/harness
-bootstrap.url=http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastSuccessfulBuild/artifact/nbbuild/netbeans/harness/tasks.jar
+bootstrap.url=http://bits.netbeans.org/dev/nbms-and-javadoc/lastSuccessfulBuild/artifact/nbbuild/netbeans/harness/tasks.jar
 autoupdate.catalog.url=http://updates.netbeans.org/netbeans/updates/7.4/uc/final/distribution/catalog.xml.gz
 suite.dir=${basedir}
 nbplatform.active=default
--- a/src/utils/LogCompilation/Makefile	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/utils/LogCompilation/Makefile	Thu Dec 07 11:54:55 2017 +0000
@@ -25,7 +25,7 @@
 com.sun.hotspot.tools.compiler
 #END PKGLIST
 
-FILELIST = com/sun/hotspot/tools/compiler/*.java
+FILELIST = main/java/com/sun/hotspot/tools/compiler/*.java
 
 ifneq "x$(ALT_BOOTDIR)" "x"
   BOOTDIR := $(ALT_BOOTDIR)
--- a/src/utils/LogCompilation/README	Wed Dec 06 19:07:16 2017 +0000
+++ b/src/utils/LogCompilation/README	Thu Dec 07 11:54:55 2017 +0000
@@ -16,3 +16,10 @@
 https://wiki.openjdk.java.net/display/HotSpot/LogCompilation+overview
 https://wiki.openjdk.java.net/display/HotSpot/PrintCompilation
 https://wiki.openjdk.java.net/display/HotSpot/LogCompilation+tool
+
+The project layout is now for Maven. To build the project with Maven do:
+
+  mvn clean install
+
+The build also copies the resulting target jar to ./logc.jar for easy 
+interop with the Makefile build.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/pom.xml	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,110 @@
+<!--
+ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+
+   - Neither the name of Oracle nor the names of its
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.sun.hotspot.tools.compiler</groupId>
+  <artifactId>LogCompilation</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>LogCompilation</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+      <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>com.sun.hotspot.tools.compiler.LogCompilation</mainClass>
+                                </transformer>
+                            </transformers>
+                            <createDependencyReducedPom>false</createDependencyReducedPom>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <version>2.5.3</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>3.0.0-M1</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <version>1.8</version>
+                <executions>
+                    <execution>
+                        <id>copy</id>
+                        <phase>package</phase>
+                        <configuration>
+                            <target>
+                                <copy file="${basedir}/target/${artifactId}-${version}.jar" tofile="${basedir}/logc.jar"/>
+                            </target>
+                        </configuration>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                    </execution> 
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-
-/**
- * Provide basic data structures and behaviour for {@link LogEvent}s.
- */
-public abstract class BasicLogEvent implements LogEvent {
-
-    /**
-     * The event's ID. This is a number; we represent it as a string for
-     * convenience.
-     */
-    protected final String id;
-
-    /**
-     * The event's start time.
-     */
-    protected final double start;
-
-    /**
-     * The event's end time.
-     */
-    protected double end;
-
-    /**
-     * The compilation during which this event was signalled.
-     */
-    protected Compilation compilation;
-
-    BasicLogEvent(double start, String id) {
-        this.start = start;
-        this.end = start;
-        this.id = id;
-    }
-
-    public final double getStart() {
-        return start;
-    }
-
-    public final double getEnd() {
-        return end;
-    }
-
-    public final void setEnd(double end) {
-        this.end = end;
-    }
-
-    public final double getElapsedTime() {
-        return ((int) ((getEnd() - getStart()) * 1000)) / 1000.0;
-    }
-
-    public final String getId() {
-        return id;
-    }
-
-    public final Compilation getCompilation() {
-        return compilation;
-    }
-
-    /**
-     * Set the compilation for this event. This is not a {@code final} method
-     * as it is overridden in {@link UncommonTrapEvent}.
-     */
-    public void setCompilation(Compilation compilation) {
-        this.compilation = compilation;
-    }
-
-    abstract public void print(PrintStream stream, boolean printID);
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Representation of a compilation scope in a compilation log. This class is a
- * hybrid: its instances can represent original scopes of methods being
- * compiled, but are also used to represent call sites in given methods.
- */
-public class CallSite {
-
-    /**
-     * The index of the call in the caller. This will be 0 if this instance
-     * represents a compilation root.
-     */
-    private int bci;
-
-    /**
-     * The method that is called at this call site. This will be {@code null}
-     * if this instance represents a compilation root.
-     */
-    private Method method;
-
-    /**
-     * The invocation count for this call site.
-     */
-    private int count;
-
-    /**
-     * The receiver type of the call represented by this instance, if known.
-     */
-    private String receiver;
-
-    /**
-     * In case the {@linkplain receiver receiver type} of the call represented
-     * by this instance is known, this is how often the type was encountered.
-     */
-    private int receiver_count;
-
-    /**
-     * The reason for a success or failure of an inlining operation at this
-     * call site.
-     */
-    private String reason;
-
-    /**
-     * A list of all calls in this compilation scope.
-     */
-    private List<CallSite> calls;
-
-    /**
-     * Number of nodes in the graph at the end of parsing this compilation
-     * scope.
-     */
-    private int endNodes;
-
-    /**
-     * Number of live nodes in the graph at the end of parsing this compilation
-     * scope.
-     */
-    private int endLiveNodes;
-
-    /**
-     * Time in seconds since VM startup at which parsing this compilation scope
-     * ended.
-     */
-    private double timeStamp;
-
-    /**
-     * The inline ID in case the call represented by this instance is inlined,
-     * 0 otherwise.
-     */
-    private long inlineId;
-
-    /**
-     * List of uncommon traps in this compilation scope.
-     */
-    private List<UncommonTrap> traps;
-
-    /**
-     * Default constructor: used to create an instance that represents the top
-     * scope of a compilation.
-     */
-    CallSite() {}
-
-    /**
-     * Constructor to create an instance that represents an actual method call.
-     */
-    CallSite(int bci, Method m) {
-        this.bci = bci;
-        this.method = m;
-    }
-
-    /**
-     * Add a call site to the compilation scope represented by this instance.
-     */
-    void add(CallSite site) {
-        if (getCalls() == null) {
-            calls = new ArrayList<>();
-        }
-        getCalls().add(site);
-    }
-
-    /**
-     * Return the last of the {@linkplain #getCalls() call sites} in this
-     * compilation scope.
-     */
-    CallSite last() {
-        return getCalls().get(getCalls().size() - 1);
-    }
-
-    /**
-     * Return the last-but-one of the {@linkplain #getCalls() call sites} in
-     * this compilation scope.
-     */
-    CallSite lastButOne() {
-        return getCalls().get(getCalls().size() - 2);
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        if (getReason() == null) {
-            sb.append("  @ " + getBci() + " " + getMethod());
-        } else {
-            sb.append("- @ " + getBci() + " " + getMethod() + " " + getReason());
-        }
-        sb.append("\n");
-        if (getCalls() != null) {
-            for (CallSite site : getCalls()) {
-                sb.append(site);
-                sb.append("\n");
-            }
-        }
-        return sb.toString();
-    }
-
-    public void print(PrintStream stream) {
-        print(stream, 0, true, false);
-    }
-
-    void emit(PrintStream stream, int indent) {
-        for (int i = 0; i < indent; i++) {
-            stream.print(' ');
-        }
-    }
-
-    public void print(PrintStream stream, int indent, boolean printInlining, boolean printUncommonTraps) {
-        emit(stream, indent);
-        String m = getMethod().getHolder() + "::" + getMethod().getName();
-        if (getReason() == null) {
-            stream.print("  @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)");
-        } else {
-            stream.print("  @ " + getBci() + " " + m + " " + getReason());
-        }
-        stream.printf(" (end time: %6.4f", getTimeStamp());
-        if (getEndNodes() > 0) {
-            stream.printf(" nodes: %d live: %d", getEndNodes(), getEndLiveNodes());
-        }
-        stream.println(")");
-
-        if (getReceiver() != null) {
-            emit(stream, indent + 4);
-            stream.println("type profile " + getMethod().getHolder() + " -> " + getReceiver() + " (" +
-                    (getReceiverCount() * 100 / getCount()) + "%)");
-        }
-        if (printInlining && getCalls() != null) {
-            for (CallSite site : getCalls()) {
-                site.print(stream, indent + 2, printInlining, printUncommonTraps);
-            }
-        }
-        if (printUncommonTraps && getTraps() != null) {
-            for (UncommonTrap site : getTraps()) {
-                site.print(stream, indent + 2);
-            }
-        }
-    }
-
-    public int getBci() {
-        return bci;
-    }
-
-    public void setBci(int bci) {
-        this.bci = bci;
-    }
-
-    public Method getMethod() {
-        return method;
-    }
-
-    public void setMethod(Method method) {
-        this.method = method;
-    }
-
-    public int getCount() {
-        return count;
-    }
-
-    public void setCount(int count) {
-        this.count = count;
-    }
-
-    public String getReceiver() {
-        return receiver;
-    }
-
-    public void setReceiver(String receiver) {
-        this.receiver = receiver;
-    }
-
-    public int getReceiverCount() {
-        return receiver_count;
-    }
-
-    public void setReceiver_count(int receiver_count) {
-        this.receiver_count = receiver_count;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    public void setReason(String reason) {
-        this.reason = reason;
-    }
-
-    public List<CallSite> getCalls() {
-        return calls;
-    }
-
-    public List<UncommonTrap> getTraps() {
-        return traps;
-    }
-
-    void add(UncommonTrap e) {
-        if (traps == null) {
-            traps = new ArrayList<UncommonTrap>();
-        }
-        traps.add(e);
-    }
-
-    void setEndNodes(int n) {
-        endNodes = n;
-    }
-
-    public int getEndNodes() {
-        return endNodes;
-    }
-
-    void setEndLiveNodes(int n) {
-        endLiveNodes = n;
-    }
-
-    public int getEndLiveNodes() {
-        return endLiveNodes;
-    }
-
-    void setTimeStamp(double time) {
-        timeStamp = time;
-    }
-
-    public double getTimeStamp() {
-        return timeStamp;
-    }
-
-    /**
-     * Check whether this call site matches another. Every late inline call
-     * site has a unique inline ID. If the call site we're looking for has one,
-     * then use it; otherwise rely on method name and byte code index.
-     */
-    private boolean matches(CallSite other) {
-        if (other.inlineId != 0) {
-            return inlineId == other.inlineId;
-        }
-        return method.equals(other.method) && bci == other.bci;
-    }
-
-    /**
-     * Locate a late inline call site: find, in this instance's
-     * {@linkplain #calls call sites}, the one furthest down the given call
-     * stack.
-     *
-     * Multiple chains of identical call sites with the same method name / bci
-     * combination are possible, so we have to try them all until we find the
-     * late inline call site that has a matching inline ID.
-     *
-     * @return a matching call site, or {@code null} if none was found.
-     */
-    public CallSite findCallSite(ArrayDeque<CallSite> sites) {
-        if (calls == null) {
-            return null;
-        }
-        CallSite site = sites.pop();
-        for (CallSite c : calls) {
-            if (c.matches(site)) {
-                if (!sites.isEmpty()) {
-                    CallSite res = c.findCallSite(sites);
-                    if (res != null) {
-                        sites.push(site);
-                        return res;
-                    }
-                } else {
-                    sites.push(site);
-                    return c;
-                }
-            }
-        }
-        sites.push(site);
-        return null;
-    }
-
-    /**
-     * Locate a late inline call site in the tree spanned by all this instance's
-     * {@linkplain #calls call sites}, and return the sequence of call sites
-     * (scopes) leading to that late inline call site.
-     */
-    public ArrayDeque<CallSite> findCallSite2(CallSite site) {
-        if (calls == null) {
-            return null;
-        }
-
-        for (CallSite c : calls) {
-            if (c.matches(site)) {
-                ArrayDeque<CallSite> stack = new ArrayDeque<>();
-                stack.push(c);
-                return stack;
-            } else {
-                ArrayDeque<CallSite> stack = c.findCallSite2(site);
-                if (stack != null) {
-                    stack.push(c);
-                    return stack;
-                }
-            }
-        }
-        return null;
-    }
-
-    public long getInlineId() {
-        return inlineId;
-    }
-
-    public void setInlineId(long inlineId) {
-        this.inlineId = inlineId;
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-
-/**
- * One particular compilation, represented in the compilation log file as a
- * {@code task} element.
- */
-public class Compilation implements LogEvent {
-
-    /**
-     * The compilation ID.
-     */
-    private int id;
-
-    /**
-     * Whether this is a compilation for on-stack replacement (OSR).
-     */
-    private boolean osr;
-
-    /**
-     * The method being compiled.
-     */
-    private Method method;
-
-    /**
-     * The {@linkplain CallSite scope} of this compilation. This is created as
-     * an empty {@link CallSite} instance, to be filled with data (and
-     * meaning) later on.
-     */
-    private CallSite call = new CallSite();
-
-    /**
-     * In case a {@code late_inline} event occurs during the compilation, this
-     * field holds the information about it.
-     */
-    private CallSite lateInlineCall = new CallSite();
-
-    /**
-     * The bytecode instruction index for on-stack replacement compilations; -1
-     * if this is not an OSR compilation.
-     */
-    private int bci;
-
-    /**
-     * The method under compilation's invocation count.
-     */
-    private String icount;
-
-    /**
-     * The method under compilation's backedge count.
-     */
-    private String bcount;
-
-    /**
-     * Additional information for special compilations (e.g., adapters).
-     */
-    private String special;
-
-    /**
-     * The name of the compiler performing this compilation.
-     */
-    private String compiler;
-
-    /**
-     * Start time stamp.
-     */
-    private double start;
-
-    /**
-     * End time stamp.
-     */
-    private double end;
-
-    /**
-     * Trip count of the register allocator.
-     */
-    private int attempts;
-
-    /**
-     * The compilation result (a native method).
-     */
-    private NMethod nmethod;
-
-    /**
-     * The phases through which this compilation goes.
-     */
-    private ArrayList<Phase> phases = new ArrayList<>(4);
-
-    /**
-     * In case this compilation fails, the reason for that.
-     */
-    private String failureReason;
-
-    Compilation(int id) {
-        this.id = id;
-    }
-
-    void reset() {
-        call = new CallSite();
-        lateInlineCall = new CallSite();
-        phases = new ArrayList<>(4);
-    }
-
-    /**
-     * Get a compilation phase by name, or {@code null}.
-     *
-     * @param s the name of the phase to retrieve in this compilation.
-     *
-     * @return a compilation phase, or {@code null} if no phase with the given
-     *         name is found.
-     */
-    Phase getPhase(String s) {
-        for (Phase p : getPhases()) {
-            if (p.getName().equals(s)) {
-                return p;
-            }
-        }
-        return null;
-    }
-
-    double getRegallocTime() {
-        return getPhase("regalloc").getElapsedTime();
-    }
-
-    public double getStart() {
-        return start;
-    }
-
-    public void setCompiler(String compiler) {
-        this.compiler = compiler;
-    }
-
-    public String getCompiler() {
-        return compiler;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(getId());
-        sb.append(" ");
-        sb.append(getCompiler());
-        sb.append(" ");
-        sb.append(getMethod());
-        sb.append(" ");
-        sb.append(getIcount());
-        sb.append("+");
-        sb.append(getBcount());
-        sb.append("\n");
-        if (getCall() != null && getCall().getCalls() != null) {
-            for (CallSite site : getCall().getCalls()) {
-                sb.append(site);
-                sb.append("\n");
-            }
-        }
-        if (getLateInlineCall().getCalls() != null) {
-            sb.append("late inline:\n");
-            for (CallSite site : getLateInlineCall().getCalls()) {
-                sb.append(site);
-                sb.append("\n");
-            }
-        }
-        return sb.toString();
-    }
-
-    public void printShort(PrintStream stream) {
-        if (getMethod() == null) {
-            stream.println(getSpecial());
-        } else {
-            int bc = isOsr() ? getBCI() : -1;
-            stream.print(getId() + getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
-        }
-    }
-
-    public void print(PrintStream stream, boolean printID) {
-        print(stream, 0, printID, true, false);
-    }
-
-    public void print(PrintStream stream, boolean printID, boolean printInlining) {
-        print(stream, 0, printID, printInlining, false);
-    }
-
-    public void print(PrintStream stream, boolean printID, boolean printInlining, boolean printUncommonTraps) {
-        print(stream, 0, printID, printInlining, printUncommonTraps);
-    }
-
-    public void print(PrintStream stream, int indent, boolean printID, boolean printInlining, boolean printUncommonTraps) {
-        if (getMethod() == null) {
-            stream.println(getSpecial());
-        } else {
-            if (printID) {
-                stream.print(getId());
-            }
-            int bc = isOsr() ? getBCI() : -1;
-            stream.print(getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
-            stream.println();
-            if (getFailureReason() != null) {
-                stream.println("COMPILE SKIPPED: " + getFailureReason() + " (not retryable)");
-            }
-            if (printInlining && call.getCalls() != null) {
-                for (CallSite site : call.getCalls()) {
-                    site.print(stream, indent + 2, printInlining, printUncommonTraps);
-                }
-            }
-            if (printUncommonTraps && call.getTraps() != null) {
-                for (UncommonTrap site : call.getTraps()) {
-                    site.print(stream, indent + 2);
-                }
-            }
-            if (printInlining && lateInlineCall.getCalls() != null) {
-                stream.println("late inline:");
-                for (CallSite site : lateInlineCall.getCalls()) {
-                    site.print(stream, indent + 2, printInlining, printUncommonTraps);
-                }
-            }
-        }
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public boolean isOsr() {
-        return osr;
-    }
-
-    public void setOsr(boolean osr) {
-        this.osr = osr;
-    }
-
-    public int getBCI() {
-        return bci;
-    }
-
-    public void setBCI(int osrBci) {
-        this.bci = osrBci;
-    }
-
-    public String getIcount() {
-        return icount;
-    }
-
-    public void setICount(String icount) {
-        this.icount = icount;
-    }
-
-    public String getBcount() {
-        return bcount;
-    }
-
-    public void setBCount(String bcount) {
-        this.bcount = bcount;
-    }
-
-    public String getSpecial() {
-        return special;
-    }
-
-    public void setSpecial(String special) {
-        this.special = special;
-    }
-
-    public void setStart(double start) {
-        this.start = start;
-    }
-
-    public double getEnd() {
-        return end;
-    }
-
-    public void setEnd(double end) {
-        this.end = end;
-    }
-
-    public int getAttempts() {
-        return attempts;
-    }
-
-    public void setAttempts(int attempts) {
-        this.attempts = attempts;
-    }
-
-    public NMethod getNMethod() {
-        return nmethod;
-    }
-
-    public void setNMethod(NMethod NMethod) {
-        this.nmethod = NMethod;
-    }
-
-    public ArrayList<Phase> getPhases() {
-        return phases;
-    }
-
-    public String getFailureReason() {
-        return failureReason;
-    }
-
-    public void setFailureReason(String failureReason) {
-        this.failureReason = failureReason;
-    }
-
-    public Method getMethod() {
-        return method;
-    }
-
-    /**
-     * Set the method under compilation. If it is already set, ignore the
-     * argument to avoid changing the method by post-parse inlining info.
-     *
-     * @param method the method under compilation. May be ignored.
-     */
-    public void setMethod(Method method) {
-        if (getMethod() == null) {
-            this.method = method;
-        }
-    }
-
-    public CallSite getCall() {
-        return call;
-    }
-
-    public CallSite getLateInlineCall() {
-        return lateInlineCall;
-    }
-
-    public double getElapsedTime() {
-        return end - start;
-    }
-
-    public Compilation getCompilation() {
-        return this;
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Constants.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2009, 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 com.sun.hotspot.tools.compiler;
-
-interface Constants {
-    static final int  JVM_ACC_PUBLIC        = 0x0001;  /* visible to everyone */
-    static final int  JVM_ACC_PRIVATE       = 0x0002;  /* visible only to the defining class */
-    static final int  JVM_ACC_PROTECTED     = 0x0004;  /* visible to subclasses */
-    static final int  JVM_ACC_STATIC        = 0x0008;  /* instance variable is static */
-    static final int  JVM_ACC_FINAL         = 0x0010;  /* no further subclassing, overriding */
-    static final int  JVM_ACC_SYNCHRONIZED  = 0x0020;  /* wrap method call in monitor lock */
-    static final int  JVM_ACC_SUPER         = 0x0020;  /* funky handling of invokespecial */
-    static final int  JVM_ACC_VOLATILE      = 0x0040;  /* can not cache in registers */
-    static final int  JVM_ACC_BRIDGE        = 0x0040;  /* bridge method generated by compiler */
-    static final int  JVM_ACC_TRANSIENT     = 0x0080;  /* not persistent */
-    static final int  JVM_ACC_VARARGS       = 0x0080;  /* method declared with variable number of args */
-    static final int  JVM_ACC_NATIVE        = 0x0100;  /* implemented in C */
-    static final int  JVM_ACC_INTERFACE     = 0x0200;  /* class is an interface */
-    static final int  JVM_ACC_ABSTRACT      = 0x0400;  /* no definition provided */
-    static final int  JVM_ACC_STRICT        = 0x0800;  /* strict floating point */
-    static final int  JVM_ACC_SYNTHETIC     = 0x1000;  /* compiler-generated class, method or field */
-    static final int  JVM_ACC_ANNOTATION    = 0x2000;  /* annotation type */
-    static final int  JVM_ACC_ENUM          = 0x4000;  /* field is declared as element of enum */
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.*;
-import java.util.regex.*;
-
-/**
- * This class is a filter class to deal with malformed XML that used
- * to be produced by the JVM when generating LogCompilation.  In 1.6
- * and later releases it shouldn't be required.
- */
-class LogCleanupReader extends Reader {
-
-    private Reader reader;
-
-    private char[] buffer = new char[4096];
-
-    private int bufferCount;
-
-    private int bufferOffset;
-
-    private char[] line = new char[1024];
-
-    private int index;
-
-    private int length;
-
-    private char[] one = new char[1];
-
-    LogCleanupReader(Reader r) {
-        reader = r;
-    }
-
-    static final private Matcher duplicateCompileID = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher("");
-    static final private Matcher compilerName = Pattern.compile("' (C[12]) compile_id=").matcher("");
-    static final private Matcher destroyVM = Pattern.compile("'(destroy_vm)/").matcher("");
-
-    /**
-     * The log cleanup takes place in this method. If any of the three patterns
-     * ({@link #duplicateCompileID}, {@link #compilerName}, {@link #destroyVM})
-     * match, that indicates a problem in the log. The cleanup is performed by
-     * correcting the input line and writing it back into the {@link #line}
-     * buffer.
-     */
-    private void fill() throws IOException {
-        rawFill();
-        if (length != -1) {
-            boolean changed = false;
-            String s = new String(line, 0, length);
-
-            compilerName.reset(s);
-            if (compilerName.find()) {
-                s = s.substring(0, compilerName.start(1)) + s.substring(compilerName.end(1) + 1);
-                changed = true;
-            }
-
-            duplicateCompileID.reset(s);
-            if (duplicateCompileID.lookingAt()) {
-                s = s.substring(0, duplicateCompileID.start(1)) + s.substring(duplicateCompileID.end(1) + 1);
-                changed = true;
-            }
-
-            destroyVM.reset(s);
-            if (destroyVM.find()) {
-                s = s.substring(0, destroyVM.start(1)) + s.substring(destroyVM.end(1));
-                changed = true;
-            }
-
-            if (changed) {
-                s.getChars(0, s.length(), line, 0);
-                length = s.length();
-            }
-        }
-    }
-
-    private void rawFill() throws IOException {
-        if (bufferCount == -1) {
-            length = -1;
-            return;
-        }
-
-        int i = 0;
-        boolean fillNonEOL = true;
-        outer:
-        while (true) {
-            if (fillNonEOL) {
-                int p;
-                for (p = bufferOffset; p < bufferCount; p++) {
-                    char c = buffer[p];
-                    if (c == '\r' || c == '\n') {
-                        bufferOffset = p;
-                        fillNonEOL = false;
-                        continue outer;
-                    }
-                    if (i >= line.length) {
-                        // copy and enlarge the line array
-                        char[] newLine = new char[line.length * 2];
-                        System.arraycopy(line, 0, newLine, 0, line.length);
-                        line = newLine;
-                    }
-                    line[i++] = c;
-                }
-                bufferOffset = p;
-            } else {
-                int p;
-                for (p = bufferOffset; p < bufferCount; p++) {
-                    char c = buffer[p];
-                    if (c != '\r' && c != '\n') {
-                        bufferOffset = p;
-                        length = i;
-                        index = 0;
-                        return;
-                    }
-                    line[i++] = c;
-                }
-                bufferOffset = p;
-            }
-            if (bufferCount == -1) {
-                if (i == 0) {
-                    length = -1;
-                } else {
-                    length = i;
-                }
-                index = 0;
-                return;
-            }
-            if (bufferOffset != bufferCount) {
-                System.out.println(bufferOffset);
-                System.out.println(bufferCount);
-                throw new InternalError("how did we get here");
-            }
-            // load more data and try again.
-            bufferCount = reader.read(buffer, 0, buffer.length);
-            bufferOffset = 0;
-        }
-    }
-
-    public int read() throws java.io.IOException {
-        read(one, 0, 1);
-        return one[0];
-    }
-
-    public int read(char[] buffer) throws java.io.IOException {
-        return read(buffer, 0, buffer.length);
-    }
-
-    public int read(char[] b, int off, int len) throws java.io.IOException {
-        if (length == -1) {
-            return -1;
-        }
-
-        if (index == length) {
-            fill();
-            if (length == -1) {
-                return -1;
-            }
-        }
-        int n = Math.min(length - index, Math.min(b.length - off, len));
-        // System.out.printf("%d %d %d %d %d\n", index, length, off, len, n);
-        System.arraycopy(line, index, b, off, n);
-        index += n;
-        return n;
-    }
-
-    public long skip(long n) throws java.io.IOException {
-        long result = n;
-        while (n-- > 0) read();
-        return result;
-    }
-
-    public boolean ready() throws java.io.IOException {
-        return reader.ready() || (line != null && length > 0);
-    }
-
-    public boolean markSupported() {
-        return false;
-    }
-
-    public void mark(int unused) throws java.io.IOException {
-        throw new UnsupportedOperationException("mark not supported");
-    }
-
-    public void reset() throws java.io.IOException {
-        reader.reset();
-        line = null;
-        index = 0;
-    }
-
-    public void close() throws java.io.IOException {
-        reader.close();
-        line = null;
-        index = 0;
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.util.*;
-
-import org.xml.sax.*;
-import org.xml.sax.helpers.*;
-
-/**
- * The LogCompilation tool parses log files generated by HotSpot using the
- * {@code -XX:+LogCompilation} command line flag, and outputs the data
- * collected therein in a nicely formatted way. There are various sorting
- * options available, as well as options that select specific compilation
- * events (such as inlining decisions) for inclusion in the output.
- *
- * The tool is also capable of fixing broken compilation logs as sometimes
- * generated by Java 1.5 JVMs.
- */
-public class LogCompilation extends DefaultHandler implements ErrorHandler {
-
-    /**
-     * Print usage information and terminate with a given exit code.
-     */
-    public static void usage(int exitcode) {
-        System.out.println("Usage: LogCompilation [ -v ] [ -c ] [ -s ] [ -e | -n ] file1 ...");
-        System.out.println("By default, the tool will print the logged compilations ordered by start time.");
-        System.out.println("  -c:   clean up malformed 1.5 xml");
-        System.out.println("  -i:   print inlining decisions");
-        System.out.println("  -S:   print compilation statistics");
-        System.out.println("  -U:   print uncommon trap statistics");
-        System.out.println("  -t:   print with time stamps");
-        System.out.println("  -s:   sort events by start time (default)");
-        System.out.println("  -e:   sort events by elapsed time");
-        System.out.println("  -n:   sort events by name and start");
-        System.out.println("  -C:   compare logs (give files to compare on command line)");
-        System.out.println("  -d:   do not print compilation IDs");
-        System.exit(exitcode);
-    }
-
-    /**
-     * Process command line arguments, parse log files and trigger desired
-     * functionality.
-     */
-    public static void main(String[] args) throws Exception {
-        Comparator<LogEvent> sort = LogParser.sortByStart;
-        boolean statistics = false;
-        boolean printInlining = false;
-        boolean cleanup = false;
-        boolean trapHistory = false;
-        boolean printTimeStamps = false;
-        boolean compare = false;
-        boolean printID = true;
-        int index = 0;
-
-        while (args.length > index) {
-            String a = args[index];
-            if (a.equals("-e")) {
-                sort = LogParser.sortByElapsed;
-                index++;
-            } else if (a.equals("-n")) {
-                sort = LogParser.sortByNameAndStart;
-                index++;
-            } else if (a.equals("-s")) {
-                sort = LogParser.sortByStart;
-                index++;
-            } else if (a.equals("-t")) {
-                printTimeStamps = true;
-                index++;
-            } else if (a.equals("-c")) {
-                cleanup = true;
-                index++;
-            } else if (a.equals("-S")) {
-                statistics = true;
-                index++;
-            } else if (a.equals("-U")) {
-                trapHistory = true;
-                index++;
-            } else if (a.equals("-h")) {
-                usage(0);
-            } else if (a.equals("-i")) {
-                printInlining = true;
-                index++;
-            } else if (a.equals("-C")) {
-                compare = true;
-                index++;
-            } else if (a.equals("-d")) {
-                printID = false;
-                index++;
-            } else {
-                if (a.charAt(0) == '-') {
-                    System.out.println("Unknown option '" + a + "', assuming file name.");
-                }
-                break;
-            }
-        }
-
-        if (index >= args.length) {
-            usage(1);
-        }
-
-        if (compare) {
-            compareLogs(index, args);
-            return;
-        }
-
-        while (index < args.length) {
-            ArrayList<LogEvent> events = null;
-            try {
-                events = LogParser.parse(args[index], cleanup);
-            } catch (FileNotFoundException fnfe) {
-                System.out.println("File not found: " + args[index]);
-                System.exit(1);
-            }
-
-            Collections.sort(events, sort);
-
-            if (statistics) {
-                printStatistics(events, System.out);
-            } else if (trapHistory) {
-                printTrapHistory(events, System.out);
-            } else {
-                for (LogEvent c : events) {
-                    if (c instanceof NMethod) {
-                        // skip these
-                        continue;
-                    }
-                    if (printTimeStamps) {
-                        System.out.print(c.getStart() + ": ");
-                    }
-                    if (c instanceof Compilation) {
-                        Compilation comp = (Compilation) c;
-                        comp.print(System.out, printID, printInlining);
-                    } else {
-                        c.print(System.out, printID);
-                    }
-                }
-            }
-            index++;
-        }
-    }
-
-    /**
-     * Print extensive statistics from parsed log files.
-     */
-    public static void printStatistics(ArrayList<LogEvent> events, PrintStream out) {
-        // track code cache size
-        long cacheSize = 0;
-        long maxCacheSize = 0;
-        // track number of nmethods
-        int nmethodsCreated = 0;
-        int nmethodsLive = 0;
-        // track how many compilations were attempted multiple times
-        // (indexed by attempts, mapping to number of compilations)
-        int[] attempts = new int[32];
-        int maxattempts = 0;
-
-        // track time spent in compiler phases
-        LinkedHashMap<String, Double> phaseTime = new LinkedHashMap<>(7);
-        // track nodes created per phase
-        LinkedHashMap<String, Integer> phaseNodes = new LinkedHashMap<>(7);
-        double elapsed = 0;
-
-        for (LogEvent e : events) {
-            if (e instanceof Compilation) {
-                Compilation c = (Compilation) e;
-                c.printShort(out);
-                out.printf(" %6.4f\n", c.getElapsedTime());
-                attempts[c.getAttempts()]++;
-                maxattempts = Math.max(maxattempts,c.getAttempts());
-                elapsed += c.getElapsedTime();
-                for (Phase phase : c.getPhases()) {
-                    Double v = phaseTime.get(phase.getName());
-                    if (v == null) {
-                        v = Double.valueOf(0.0);
-                    }
-                    phaseTime.put(phase.getName(), Double.valueOf(v.doubleValue() + phase.getElapsedTime()));
-
-                    Integer v2 = phaseNodes.get(phase.getName());
-                    if (v2 == null) {
-                        v2 = Integer.valueOf(0);
-                    }
-                    phaseNodes.put(phase.getName(), Integer.valueOf(v2.intValue() + phase.getNodes()));
-                    // Print phase name, elapsed time, nodes at the start of
-                    // the phase, nodes created in the phase, live nodes at the
-                    // start of the phase, live nodes added in the phase.
-                    out.printf("\t%s %6.4f %d %d %d %d\n", phase.getName(), phase.getElapsedTime(), phase.getStartNodes(), phase.getNodes(), phase.getStartLiveNodes(), phase.getAddedLiveNodes());
-                }
-            } else if (e instanceof MakeNotEntrantEvent) {
-                MakeNotEntrantEvent mne = (MakeNotEntrantEvent) e;
-                NMethod nm = mne.getNMethod();
-                if (mne.isZombie()) {
-                    if (nm == null) {
-                        System.err.println("zombie make not entrant event without nmethod: " + mne.getId());
-                    }
-                    cacheSize -= nm.getSize();
-                    nmethodsLive--;
-                }
-            } else if (e instanceof NMethod) {
-                nmethodsLive++;
-                nmethodsCreated++;
-                NMethod nm = (NMethod) e;
-                cacheSize += nm.getSize();
-                maxCacheSize = Math.max(cacheSize, maxCacheSize);
-            }
-        }
-        out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n", nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize);
-        out.println("Phase times:");
-        for (String name : phaseTime.keySet()) {
-            Double v = phaseTime.get(name);
-            Integer v2 = phaseNodes.get(name);
-            out.printf("%20s %6.4f %d\n", name, v.doubleValue(), v2.intValue());
-        }
-        out.printf("%20s %6.4f\n", "total", elapsed);
-
-        if (maxattempts > 0) {
-            out.println("Distribution of regalloc passes:");
-            for (int i = 0; i <= maxattempts; i++) {
-                out.printf("%2d %8d\n", i, attempts[i]);
-            }
-        }
-    }
-
-    /**
-     * Container class for a pair of a method and a bytecode instruction index
-     * used by a compiler. This is used in
-     * {@linkplain #compareLogs() comparing logs}.
-     */
-    static class MethodBCIPair {
-        public MethodBCIPair(Method m, int b, String c) {
-            method = m;
-            bci = b;
-            compiler = c;
-        }
-
-        Method method;
-        int bci;
-        String compiler;
-
-        public boolean equals(Object other) {
-            if (!(other instanceof MethodBCIPair)) {
-                return false;
-            }
-            MethodBCIPair otherp = (MethodBCIPair)other;
-            return (otherp.bci == bci &&
-                    otherp.method.equals(method) &&
-                    otherp.compiler.equals(compiler));
-        }
-
-        public int hashCode() {
-            return method.hashCode() + bci;
-        }
-
-        public String toString() {
-            if (bci != -1) {
-                return method + "@" + bci + " (" + compiler + ")";
-            } else {
-                return method + " (" + compiler + ")";
-            }
-        }
-    }
-
-    /**
-     * Compare a number of compilation log files. Each of the logs is parsed,
-     * and all compilations found therein are written to a sorted file (prefix
-     * {@code sorted-}. A summary is written to a new file {@code summary.txt}.
-     *
-     * @param index the index in the command line arguments at which to start
-     *              looking for files to compare.
-     * @param args  the command line arguments with which {@link LogCompilation}
-     *              was originally invoked.
-     *
-     * @throws Exception in case any exceptions are thrown in the called
-     *         methods.
-     */
-    @SuppressWarnings("unchecked")
-    static void compareLogs(int index, String[] args) throws Exception {
-        HashMap<MethodBCIPair,MethodBCIPair> methods = new HashMap<>();
-        ArrayList<HashMap<MethodBCIPair,Object>> logs = new ArrayList<>();
-        PrintStream[] outs = new PrintStream[args.length - index];
-        PrintStream summary = new PrintStream(new FileOutputStream("summary.txt"));
-        int o = 0;
-        // Process all logs given on the command line: collect compilation
-        // data; in particular, method/bci pairs.
-        while (index < args.length) {
-            String basename = new File(args[index]).getName();
-            String outname = "sorted-" + basename;
-            System.out.println("Sorting " + basename + " to " + outname);
-            outs[o] = new PrintStream(new FileOutputStream(outname));
-            o++;
-            System.out.println("Parsing " + args[index]);
-            ArrayList<LogEvent> events = LogParser.parse(args[index], false);
-            HashMap<MethodBCIPair,Object> compiles = new HashMap<>();
-            logs.add(compiles);
-            for (LogEvent c : events) {
-                if (c instanceof Compilation) {
-                    Compilation comp = (Compilation) c;
-                    MethodBCIPair key = new MethodBCIPair(comp.getMethod(), comp.getBCI(),
-                                                          comp.getCompiler());
-                    MethodBCIPair e = methods.get(key);
-                    if (e == null) {
-                        methods.put(key, key);
-                    } else {
-                        key = e;
-                    }
-                    Object other = compiles.get(key);
-                    if (other == null) {
-                        compiles.put(key, comp);
-                    } else {
-                        if (!(other instanceof List)) {
-                            List<Object> l = new LinkedList<>();
-                            l.add(other);
-                            l.add(comp);
-                            compiles.put(key, l);
-                        } else {
-                            List<Object> l = (List<Object>) other;
-                            l.add(comp);
-                        }
-                    }
-                }
-            }
-            index++;
-        }
-
-        // Process the collected method/bci pairs and write the output.
-        for (MethodBCIPair pair : methods.keySet()) {
-            summary.print(pair + " ");
-            int base = -1;
-            String first = null;
-            boolean mismatch = false;
-            boolean different = false;
-            String[] output = new String[outs.length];
-            o = 0;
-            for (HashMap<MethodBCIPair,Object> set : logs) {
-                Object e = set.get(pair);
-                String thisone = null;
-                Compilation lastc = null;
-                int n;
-                if (e == null) {
-                    n = 0;
-                } else if (e instanceof Compilation) {
-                    n = 1;
-                    lastc = (Compilation) e;
-                } else {
-                    // Compare the last compilation that was done for this method
-                    n = ((List<Object>) e).size();
-                    lastc = (Compilation) ((List<Object>) e).get(n - 1);
-                }
-                if (lastc != null) {
-                    n = 1;
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    PrintStream ps = new PrintStream(baos);
-                    lastc.print(ps, false);
-                    ps.close();
-                    thisone = new String(baos.toByteArray());
-                }
-                if (base == -1) {
-                    base = n;
-                } else if (base != n) {
-                    mismatch = true;
-                }
-                output[o++] = thisone;
-                if (thisone != null) {
-                    if (first == null) {
-                        first = thisone;
-                    } else {
-                        if (!first.equals(thisone)) {
-                            different = true;
-                        }
-                    }
-                }
-                if (different) {
-                    summary.print(n + "d ");
-                } else {
-                    summary.print(n + " ");
-                }
-            }
-            if (mismatch) {
-                summary.print("mismatch");
-            }
-            summary.println();
-            if (different) {
-                for (int i = 0; i < outs.length; i++) {
-                    if (output[i] != null) {
-                        outs[i].println(output[i]);
-                    }
-                }
-            }
-        }
-        for (int i = 0; i < outs.length; i++) {
-            outs[i].close();
-        }
-        if (summary != System.out) {
-            summary.close();
-        }
-    }
-
-    /**
-     * Print the history of uncommon trap events.
-     */
-    public static void printTrapHistory(ArrayList<LogEvent> events, PrintStream out) {
-        // map method names to a list of log events
-        LinkedHashMap<String, ArrayList<LogEvent>> traps = new LinkedHashMap<>();
-        // map compilation IDs to compilations
-        HashMap<Integer, Compilation> comps = new HashMap<>();
-
-        // First, iterate over all logged events, collecting data about
-        // uncommon trap events.
-        for (LogEvent e : events) {
-            if (e instanceof NMethod) {
-                // skip these
-                continue;
-            }
-            if (e instanceof Compilation) {
-                Compilation c = (Compilation) e;
-                String name = c.getMethod().getFullName();
-                ArrayList<LogEvent> elist = traps.get(name);
-                if (elist != null && comps.get(c.getId()) == null) {
-                    comps.put(c.getId(), c);
-                    // If there were previous events for the method
-                    // then keep track of later compiles too.
-                    elist.add(c);
-                }
-                continue;
-            }
-            if (e instanceof BasicLogEvent) {
-                BasicLogEvent ble = (BasicLogEvent) e;
-                Compilation c = ble.getCompilation();
-                if (c == null) {
-                    if (!(ble instanceof NMethod)) {
-                        throw new InternalError("only nmethods should have a null compilation; here's a " + ble.getClass());
-                    }
-                    continue;
-                }
-                String name = c.getMethod().getFullName();
-                ArrayList<LogEvent> elist = traps.get(name);
-                if (elist == null) {
-                    elist = new ArrayList<LogEvent>();
-                    traps.put(name, elist);
-                }
-                int bleId = Integer.parseInt(ble.getId());
-                if (comps.get(bleId) == null) {
-                    comps.put(bleId, c);
-                    // Add the associated compile to the list.  It
-                    // will likely go at the end but we need to search
-                    // backwards for the proper insertion point.
-                    double start = c.getStart();
-                    int ipoint = 0;
-                    while (ipoint < elist.size() && elist.get(ipoint).getStart() < start) {
-                        ipoint++;
-                    }
-                    if (ipoint == elist.size()) {
-                        elist.add(c);
-                    } else {
-                        elist.add(ipoint, c);
-                    }
-                }
-                elist.add(ble);
-            }
-        }
-
-        // Second, iterate over collected traps and output information.
-        for (String c: traps.keySet()) {
-            ArrayList<LogEvent> elist = traps.get(c);
-            String name = ((Compilation) elist.get(0)).getMethod().getFullName();
-            System.out.println(name);
-            double start = 0;
-            for (LogEvent e: elist) {
-                if (start > e.getStart() && e.getStart() != 0) {
-                    throw new InternalError("wrong sorting order for traps");
-                }
-                start = e.getStart();
-                out.print(e.getStart() + ": ");
-                if (e instanceof Compilation) {
-                    ((Compilation) e).print(out, true, true, true);
-                } else {
-                    e.print(out, true);
-                }
-            }
-            out.println();
-        }
-    }
-
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-
-/**
- * The interface of an event from a HotSpot compilation log. Events can have a
- * duration, e.g., a compiler {@link Phase} is an event, and so is an entire
- * {@link Compilation}.
- */
-public interface LogEvent {
-
-    /**
-     * The event's start time.
-     */
-    public double getStart();
-
-    /**
-     * The event's duration in milliseconds.
-     */
-    public double getElapsedTime();
-
-    /**
-     * The compilation during which this event was signalled.
-     */
-    public Compilation getCompilation();
-
-    /**
-     * Print the event to the given stream.
-     */
-    public void print(PrintStream stream, boolean printID);
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1295 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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.
- *
- */
-
-/**
- * A SAX based parser of LogCompilation output from HotSpot.  It takes a complete
- */
-
-package com.sun.hotspot.tools.compiler;
-
-import java.io.FileReader;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * A SAX parser for HotSpot compilation logs. The bulk of the parsing and event
- * maintenance work is done in the {@link #startElement(String,String,String,Attributes)}
- * and {@link #endElement(String,String,String)} methods.
- */
-public class LogParser extends DefaultHandler implements ErrorHandler {
-
-    static final Pattern spacePattern = Pattern.compile(" ");
-
-    /**
-     * Map internal array type descriptors to Java names.
-     */
-    static final HashMap<String, String> type2printableMap;
-
-    /**
-     * Map Java primitive type names to internal type descriptors.
-     */
-    static final HashMap<String, String> type2vmtypeMap;
-
-    static {
-        type2printableMap = new HashMap<>();
-        type2printableMap.put("[I", "int[]");
-        type2printableMap.put("[C", "char[]");
-        type2printableMap.put("[Z", "boolean[]");
-        type2printableMap.put("[L", "Object[]");
-        type2printableMap.put("[B", "byte[]");
-
-        type2vmtypeMap = new HashMap<>();
-        type2vmtypeMap.put("void", "V");
-        type2vmtypeMap.put("boolean", "Z");
-        type2vmtypeMap.put("byte", "B");
-        type2vmtypeMap.put("char", "C");
-        type2vmtypeMap.put("short", "S");
-        type2vmtypeMap.put("int", "I");
-        type2vmtypeMap.put("long", "J");
-        type2vmtypeMap.put("float", "F");
-        type2vmtypeMap.put("double", "D");
-    }
-
-    static String[] bytecodes = new String[] {
-        "nop",
-        "aconst_null",
-        "iconst_m1",
-        "iconst_0",
-        "iconst_1",
-        "iconst_2",
-        "iconst_3",
-        "iconst_4",
-        "iconst_5",
-        "lconst_0",
-        "lconst_1",
-        "fconst_0",
-        "fconst_1",
-        "fconst_2",
-        "dconst_0",
-        "dconst_1",
-        "bipush",
-        "sipush",
-        "ldc",
-        "ldc_w",
-        "ldc2_w",
-        "iload",
-        "lload",
-        "fload",
-        "dload",
-        "aload",
-        "iload_0",
-        "iload_1",
-        "iload_2",
-        "iload_3",
-        "lload_0",
-        "lload_1",
-        "lload_2",
-        "lload_3",
-        "fload_0",
-        "fload_1",
-        "fload_2",
-        "fload_3",
-        "dload_0",
-        "dload_1",
-        "dload_2",
-        "dload_3",
-        "aload_0",
-        "aload_1",
-        "aload_2",
-        "aload_3",
-        "iaload",
-        "laload",
-        "faload",
-        "daload",
-        "aaload",
-        "baload",
-        "caload",
-        "saload",
-        "istore",
-        "lstore",
-        "fstore",
-        "dstore",
-        "astore",
-        "istore_0",
-        "istore_1",
-        "istore_2",
-        "istore_3",
-        "lstore_0",
-        "lstore_1",
-        "lstore_2",
-        "lstore_3",
-        "fstore_0",
-        "fstore_1",
-        "fstore_2",
-        "fstore_3",
-        "dstore_0",
-        "dstore_1",
-        "dstore_2",
-        "dstore_3",
-        "astore_0",
-        "astore_1",
-        "astore_2",
-        "astore_3",
-        "iastore",
-        "lastore",
-        "fastore",
-        "dastore",
-        "aastore",
-        "bastore",
-        "castore",
-        "sastore",
-        "pop",
-        "pop2",
-        "dup",
-        "dup_x1",
-        "dup_x2",
-        "dup2",
-        "dup2_x1",
-        "dup2_x2",
-        "swap",
-        "iadd",
-        "ladd",
-        "fadd",
-        "dadd",
-        "isub",
-        "lsub",
-        "fsub",
-        "dsub",
-        "imul",
-        "lmul",
-        "fmul",
-        "dmul",
-        "idiv",
-        "ldiv",
-        "fdiv",
-        "ddiv",
-        "irem",
-        "lrem",
-        "frem",
-        "drem",
-        "ineg",
-        "lneg",
-        "fneg",
-        "dneg",
-        "ishl",
-        "lshl",
-        "ishr",
-        "lshr",
-        "iushr",
-        "lushr",
-        "iand",
-        "land",
-        "ior",
-        "lor",
-        "ixor",
-        "lxor",
-        "iinc",
-        "i2l",
-        "i2f",
-        "i2d",
-        "l2i",
-        "l2f",
-        "l2d",
-        "f2i",
-        "f2l",
-        "f2d",
-        "d2i",
-        "d2l",
-        "d2f",
-        "i2b",
-        "i2c",
-        "i2s",
-        "lcmp",
-        "fcmpl",
-        "fcmpg",
-        "dcmpl",
-        "dcmpg",
-        "ifeq",
-        "ifne",
-        "iflt",
-        "ifge",
-        "ifgt",
-        "ifle",
-        "if_icmpeq",
-        "if_icmpne",
-        "if_icmplt",
-        "if_icmpge",
-        "if_icmpgt",
-        "if_icmple",
-        "if_acmpeq",
-        "if_acmpne",
-        "goto",
-        "jsr",
-        "ret",
-        "tableswitch",
-        "lookupswitch",
-        "ireturn",
-        "lreturn",
-        "freturn",
-        "dreturn",
-        "areturn",
-        "return",
-        "getstatic",
-        "putstatic",
-        "getfield",
-        "putfield",
-        "invokevirtual",
-        "invokespecial",
-        "invokestatic",
-        "invokeinterface",
-        "invokedynamic",
-        "new",
-        "newarray",
-        "anewarray",
-        "arraylength",
-        "athrow",
-        "checkcast",
-        "instanceof",
-        "monitorenter",
-        "monitorexit",
-        "wide",
-        "multianewarray",
-        "ifnull",
-        "ifnonnull",
-        "goto_w",
-        "jsr_w",
-        "breakpoint"
-    };
-
-    /**
-     * Sort log events by start time.
-     */
-    static Comparator<LogEvent> sortByStart = new Comparator<LogEvent>() {
-
-        public int compare(LogEvent a, LogEvent b) {
-            double difference = (a.getStart() - b.getStart());
-            if (difference < 0) {
-                return -1;
-            }
-            if (difference > 0) {
-                return 1;
-            }
-            return 0;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return 7;
-        }
-    };
-
-    /**
-     * Sort log events first by the name of the compiled method, then by start
-     * time. In case one of the events has no associated compilation (or the
-     * associated compilation has no method name), the event with a compilation
-     * and/or name is considered the larger one.
-     */
-    static Comparator<LogEvent> sortByNameAndStart = new Comparator<LogEvent>() {
-
-        public int compare(LogEvent a, LogEvent b) {
-            Compilation c1 = a.getCompilation();
-            Compilation c2 = b.getCompilation();
-            if (c1 != null && c1.getMethod() != null && c2 != null && c2.getMethod() != null) {
-                int result = c1.getMethod().toString().compareTo(c2.getMethod().toString());
-                if (result != 0) {
-                    return result;
-                }
-            } else if ((c1 == null || c1.getMethod() == null) && c2 != null && c2.getMethod() != null) {
-                return -1;
-            } else if ((c2 == null || c2.getMethod() == null) && c1 != null && c1.getMethod() != null) {
-                return 1;
-            }
-            return Double.compare(a.getStart(), b.getStart());
-        }
-
-        public boolean equals(Object other) {
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return 7;
-        }
-    };
-
-    /**
-     * Sort log events by duration.
-     */
-    static Comparator<LogEvent> sortByElapsed = new Comparator<LogEvent>() {
-
-        public int compare(LogEvent a, LogEvent b) {
-            double difference = (a.getElapsedTime() - b.getElapsedTime());
-            if (difference < 0) {
-                return -1;
-            }
-            if (difference > 0) {
-                return 1;
-            }
-            return 0;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return 7;
-        }
-    };
-
-    /**
-     * Shrink-wrapped representation of a JVMState (tailored to meet this
-     * tool's needs). It only records a method and bytecode instruction index.
-     */
-    class Jvms {
-        Jvms(Method method, int bci) {
-            this.method = method;
-            this.bci = bci;
-        }
-        final public Method method;
-        final public int bci;
-        final public String toString() {
-            return "@" + bci + " " + method;
-        }
-    }
-
-    /**
-     * Representation of a lock elimination. Locks, corresponding to
-     * synchronized blocks and method calls, may be eliminated if the object in
-     * question is guaranteed to be used thread-locally.
-     */
-    class LockElimination extends BasicLogEvent {
-
-        /**
-         * Track all locations from which this lock was eliminated.
-         */
-        ArrayList<Jvms> jvms = new ArrayList<>(1);
-
-        /**
-         * The kind of lock (coarsened, nested, non-escaping, unknown).
-         */
-        final String kind;
-
-        /**
-         * The lock class (unlock, lock, unknown).
-         */
-        final String classId;
-
-        /**
-         * The precise type of lock.
-         */
-        final String tagName;
-
-        LockElimination(String tagName, double start, String id, String kind, String classId) {
-            super(start, id);
-            this.kind = kind;
-            this.classId = classId;
-            this.tagName = tagName;
-        }
-
-        @Override
-        public void print(PrintStream stream, boolean printID) {
-            if (printID) {
-                stream.printf("%s ", getId());
-            }
-            stream.printf("%s %s %s  %.3f ", tagName, kind, classId, getStart());
-            stream.print(jvms.toString());
-            stream.print("\n");
-        }
-
-        void addJVMS(Method method, int bci) {
-            jvms.add(new Jvms(method, bci));
-        }
-
-    }
-
-    /**
-     * A list of log events. This is populated with the events found in the
-     * compilation log file during parsing.
-     */
-    private ArrayList<LogEvent> events = new ArrayList<>();
-
-    /**
-     * Map compilation log IDs to type names.
-     */
-    private HashMap<String, String> types = new HashMap<>();
-
-    /**
-     * Map compilation log IDs to methods.
-     */
-    private HashMap<String, Method> methods = new HashMap<>();
-
-    /**
-     * Map compilation IDs ({@see #makeId()}) to newly created nmethods.
-     */
-    private LinkedHashMap<String, NMethod> nmethods = new LinkedHashMap<>();
-
-    /**
-     * Map compilation task IDs {@see #makeId()}) to {@link Compilation}
-     * objects.
-     */
-    private HashMap<String, Compilation> compiles = new HashMap<>();
-
-    /**
-     * Track compilation failure reasons.
-     */
-    private String failureReason;
-
-    /**
-     * The current bytecode instruction index.
-     */
-    private int current_bci;
-
-    /**
-     * The current bytecode instruction.
-     */
-    private int current_bytecode;
-
-    /**
-     * A sequence of {@link CallSite}s representing a call stack. A scope
-     * typically holds several {@link CallSite}s that represent calls
-     * originating from that scope.
-     *
-     * New scopes are typically pushed when parse log events are encountered
-     * ({@see #startElement()}) and popped when parsing of a given Java method
-     * is done ({@see #endElement()}). Parsing events can be nested. Several
-     * other events add information to scopes ({@see #startElement()}).
-     */
-    private Deque<CallSite> scopes = new ArrayDeque<>();
-
-    /**
-     * The current compilation.
-     */
-    private Compilation compile;
-
-    /**
-     * The {@linkplain CallSite compilation scope} currently in focus.
-     */
-    private CallSite site;
-
-    /**
-     * The {@linkplain CallSite method handle call site} currently under
-     * observation.
-     */
-    private CallSite methodHandleSite;
-
-    /**
-     * Keep track of potentially nested compiler {@linkplain Phase phases}.
-     */
-    private Deque<Phase> phaseStack = new ArrayDeque<>();
-
-    /**
-     * The {@linkplain LockElimination lock elimination event} currently being
-     * processed.
-     */
-    private LockElimination currentLockElimination;
-
-    /**
-     * The {@linkplain UncommonTrapEvent uncommon trap event} currently being
-     * processed.
-     */
-    private UncommonTrapEvent currentTrap;
-
-    /**
-     * During the processing of a late inline event, this stack holds the
-     * {@link CallSite}s that represent the inlining event's call stack.
-     */
-    private Deque<CallSite> lateInlineScope;
-
-    /**
-     * Denote whether a late inlining event is currently being processed.
-     */
-    private boolean lateInlining;
-
-    /**
-     * A document locator to provide better error messages: this allows the
-     * tool to display in which line of the log file the problem occurred.
-     */
-    private Locator locator;
-
-    /**
-     * Callback for the SAX framework to set the document locator.
-     */
-    @Override
-    public void setDocumentLocator(Locator locator) {
-        this.locator = locator;
-    }
-
-    /**
-     * Report an internal error explicitly raised, i.e., not derived from an
-     * exception.
-     *
-     * @param msg The error message to report.
-     */
-    private void reportInternalError(String msg) {
-        reportInternalError(msg, null);
-    }
-
-    /**
-     * Report an internal error derived from an exception.
-     *
-     * @param msg The beginning of the error message to report. The message
-     * from the exception will be appended to this.
-     * @param e The exception that led to the internal error.
-     */
-    private void reportInternalError(String msg, Exception e) {
-        if (locator != null) {
-            msg += " at " + locator.getLineNumber() + ":" + locator.getColumnNumber();
-            if (e != null) {
-                msg += " - " + e.getMessage();
-            }
-        }
-        if (e != null) {
-            throw new Error(msg, e);
-        } else {
-            throw new Error(msg);
-        }
-    }
-
-    /**
-     * Parse a long hexadecimal address into a {@code long} value. As Java only
-     * supports positive {@code long} values, extra error handling and parsing
-     * logic is provided.
-     */
-    long parseLong(String l) {
-        try {
-            return Long.decode(l).longValue();
-        } catch (NumberFormatException nfe) {
-            int split = l.length() - 8;
-            String s1 = "0x" + l.substring(split);
-            String s2 = l.substring(0, split);
-            long v1 = Long.decode(s1).longValue() & 0xffffffffL;
-            long v2 = (Long.decode(s2).longValue() & 0xffffffffL) << 32;
-            if (!l.equals("0x" + Long.toHexString(v1 + v2))) {
-                System.out.println(l);
-                System.out.println(s1);
-                System.out.println(s2);
-                System.out.println(v1);
-                System.out.println(v2);
-                System.out.println(Long.toHexString(v1 + v2));
-                reportInternalError("bad conversion");
-            }
-            return v1 + v2;
-        }
-    }
-
-    /**
-     * Entry point for log file parsing with a file name.
-     *
-     * @param file The name of the log file to parse.
-     * @param cleanup Whether to perform bad XML cleanup during parsing (this
-     * is relevant for some log files generated by the 1.5 JVM).
-     * @return a list of {@link LogEvent} instances describing the events found
-     * in the log file.
-     */
-    public static ArrayList<LogEvent> parse(String file, boolean cleanup) throws Exception {
-        return parse(new FileReader(file), cleanup);
-    }
-
-    /**
-     * Entry point for log file parsing with a file reader.
-     * {@see #parse(String,boolean)}
-     */
-    public static ArrayList<LogEvent> parse(Reader reader, boolean cleanup) throws Exception {
-        // Create the XML input factory
-        SAXParserFactory factory = SAXParserFactory.newInstance();
-
-        // Create the XML LogEvent reader
-        SAXParser p = factory.newSAXParser();
-
-        if (cleanup) {
-            // some versions of the log have slightly malformed XML, so clean it
-            // up before passing it to SAX
-            reader = new LogCleanupReader(reader);
-        }
-
-        LogParser log = new LogParser();
-        try {
-            p.parse(new InputSource(reader), log);
-        } catch (Throwable th) {
-            th.printStackTrace();
-            // Carry on with what we've got...
-        }
-
-        // Associate compilations with their NMethods and other kinds of events
-        for (LogEvent e : log.events) {
-            if (e instanceof BasicLogEvent) {
-                BasicLogEvent ble = (BasicLogEvent) e;
-                Compilation c = log.compiles.get(ble.getId());
-                if (c == null) {
-                    if (!(ble instanceof NMethod)) {
-                        throw new InternalError("only nmethods should have a null compilation, here's a " + ble.getClass());
-                    }
-                    continue;
-                }
-                ble.setCompilation(c);
-                if (ble instanceof NMethod) {
-                    c.setNMethod((NMethod) ble);
-                }
-            }
-        }
-
-        return log.events;
-    }
-
-    /**
-     * Retrieve a given attribute's value from a collection of XML tag
-     * attributes. Report an error if the requested attribute is not found.
-     *
-     * @param attr A collection of XML tag attributes.
-     * @param name The name of the attribute the value of which is to be found.
-     * @return The value of the requested attribute, or {@code null} if it was
-     * not found.
-     */
-    String search(Attributes attr, String name) {
-        String result = attr.getValue(name);
-        if (result != null) {
-            return result;
-        } else {
-            reportInternalError("can't find " + name);
-            return null;
-        }
-    }
-
-    /**
-     * Retrieve a given attribute's value from a collection of XML tag
-     * attributes. Return a default value if the requested attribute is not
-     * found.
-     *
-     * @param attr A collection of XML tag attributes.
-     * @param name The name of the attribute the value of which is to be found.
-     * @param defaultValue The default value to return if the attribute is not
-     * found.
-     * @return The value of the requested attribute, or the default value if it
-     * was not found.
-     */
-    String search(Attributes attr, String name, String defaultValue) {
-        String result = attr.getValue(name);
-        if (result != null) {
-            return result;
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Map a type ID from the compilation log to an actual type name. In case
-     * the type represents an internal array type descriptor, return a
-     * Java-level name. If the type ID cannot be mapped to a name, raise an
-     * error.
-     */
-    String type(String id) {
-        String result = types.get(id);
-        if (result == null) {
-            reportInternalError(id);
-        }
-        String remapped = type2printableMap.get(result);
-        if (remapped != null) {
-            return remapped;
-        }
-        return result;
-    }
-
-    /**
-     * Register a mapping from log file type ID to type name.
-     */
-    void type(String id, String name) {
-        assert type(id) == null;
-        types.put(id, name);
-    }
-
-    /**
-     * Map a log file type ID to an internal type declarator.
-     */
-    String sigtype(String id) {
-        String result = types.get(id);
-        String remapped = type2vmtypeMap.get(result);
-        if (remapped != null) {
-            return remapped;
-        }
-        if (result == null) {
-            reportInternalError(id);
-        }
-        if (result.charAt(0) == '[') {
-            return result;
-        }
-        return "L" + result + ";";
-    }
-
-    /**
-     * Retrieve a method based on the log file ID it was registered under.
-     * Raise an error if the ID does not map to a method.
-     */
-    Method method(String id) {
-        Method result = methods.get(id);
-        if (result == null) {
-            reportInternalError(id);
-        }
-        return result;
-    }
-
-    /**
-     * From a compilation ID and kind, assemble a compilation ID for inclusion
-     * in the output.
-     *
-     * @param atts A collection of XML attributes from which the required
-     * attributes are retrieved.
-     */
-    public String makeId(Attributes atts) {
-        String id = atts.getValue("compile_id");
-        String kind = atts.getValue("kind");
-        if (kind != null && kind.equals("osr")) {
-            id += "%";
-        }
-        return id;
-    }
-
-    /**
-     * Process the start of a compilation log XML element.<ul>
-     * <li><b>phase:</b> record the beginning of a compilation phase, pushing
-     * it on the {@linkplain #phaseStack phase stack} and collecting
-     * information about the compiler graph.</li>
-     * <li><b>phase_done:</b> record the end of a compilation phase, popping it
-     * off the {@linkplain #phaseStack phase stack} and collecting information
-     * about the compiler graph (number of nodes and live nodes).</li>
-     * <li><b>task:</b> register the start of a new compilation.</li>
-     * <li><b>type:</b> register a type.</li>
-     * <li><b>bc:</b> note the current bytecode index and instruction name,
-     * updating {@link #current_bci} and {@link #current_bytecode}.</li>
-     * <li><b>klass:</b> register a type (class).</li>
-     * <li><b>method:</b> register a Java method.</li>
-     * <li><b>call:</b> process a call, populating {@link #site} with the
-     * appropriate data.</li>
-     * <li><b>regalloc:</b> record the register allocator's trip count in the
-     * {@linkplain #compile current compilation}.</li>
-     * <li><b>inline_fail:</b> record the reason for a failed inline
-     * operation.</li>
-     * <li><b>inline_success:</b> record a successful inlining operation,
-     * noting the success reason in the {@linkplain #site call site}.</li>
-     * <li><b>failure:</b> note a compilation failure, storing the reason
-     * description in {@link #failureReason}.</li>
-     * <li><b>task_done:</b> register the end of a compilation, recording time
-     * stamp and success information.</li>
-     * <li><b>make_not_entrant:</b> deal with making a native method
-     * non-callable (e.g., during an OSR compilation, if there are still
-     * activations) or a zombie (when the method can be deleted).</li>
-     * <li><b>uncommon_trap:</b> process an uncommon trap, setting the
-     * {@link #currentTrap} field.</li>
-     * <li><b>eliminate_lock:</b> record the start of a lock elimination,
-     * setting the {@link #currentLockElimination} event.</li>
-     * <li><b>late_inline:</b> start processing a late inline decision:
-     * initialize the {@linkplain #lateInlineScope inline scope stack}, create
-     * an {@linkplain #site initial scope} with a bogus bytecode index and the
-     * right inline ID, and push the scope with the inline ID attached. Note
-     * that most of late inlining processing happens in
-     * {@link #endElement()}.</li>
-     * <li><b>jvms:</b> record a {@linkplain Jvms JVMState}. Depending on the
-     * context in which this event is encountered, this can mean adding
-     * information to the currently being processed trap, lock elimination, or
-     * inlining operation.</li>
-     * <li><b>inline_id:</b> set the inline ID in the
-     * {@linkplain #site current call site}.</li>
-     * <li><b>nmethod:</b> record the creation of a new {@link NMethod} and
-     * store it in the {@link #nmethods} map.</li>
-     * <li><b>parse:</b> begin parsing a Java method's bytecode and
-     * transforming it into an initial compiler IR graph.</li>
-     * <li><b>parse_done:</b> finish parsing a Java method's bytecode.</li>
-     * </ul>
-     */
-    @Override
-    public void startElement(String uri, String localName, String qname, Attributes atts) {
-        if (qname.equals("phase")) {
-            Phase p = new Phase(search(atts, "name"),
-                    Double.parseDouble(search(atts, "stamp")),
-                    Integer.parseInt(search(atts, "nodes", "0")),
-                    Integer.parseInt(search(atts, "live", "0")));
-            phaseStack.push(p);
-        } else if (qname.equals("phase_done")) {
-            Phase p = phaseStack.pop();
-            String phaseName = search(atts, "name", null);
-            if (phaseName != null && !p.getId().equals(phaseName)) {
-                System.out.println("phase: " + p.getId());
-                reportInternalError("phase name mismatch");
-            }
-            p.setEnd(Double.parseDouble(search(atts, "stamp")));
-            p.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
-            p.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
-            compile.getPhases().add(p);
-        } else if (qname.equals("task")) {
-            String id = makeId(atts);
-
-            // Create the new Compilation instance and populate it with readily
-            // available data.
-            compile = new Compilation(Integer.parseInt(search(atts, "compile_id", "-1")));
-            compile.setStart(Double.parseDouble(search(atts, "stamp")));
-            compile.setICount(search(atts, "count", "0"));
-            compile.setBCount(search(atts, "backedge_count", "0"));
-            compile.setBCI(Integer.parseInt(search(atts, "osr_bci", "-1")));
-            String compiler = atts.getValue("compiler");
-            if (compiler == null) {
-                compiler = "";
-            }
-            compile.setCompiler(compiler);
-
-            // Extract the name of the compiled method.
-            String[] parts = spacePattern.split(atts.getValue("method"));
-            String methodName = parts[0] + "::" + parts[1];
-
-            // Continue collecting compilation meta-data.
-            String kind = atts.getValue("compile_kind");
-            if (kind == null) {
-                kind = "normal";
-            }
-            if (kind.equals("osr")) {
-                compile.setOsr(true);
-            } else if (kind.equals("c2i")) {
-                compile.setSpecial("--- adapter " + methodName);
-            } else {
-                compile.setSpecial(compile.getId() + " " + methodName + " (0 bytes)");
-            }
-
-            // Build a dummy method to stuff in the Compilation at the
-            // beginning.
-            Method m = new Method();
-            m.setHolder(parts[0]);
-            m.setName(parts[1]);
-            m.setSignature(parts[2]);
-            m.setFlags("0");
-            m.setBytes(search(atts, "bytes", "unknown"));
-            compile.setMethod(m);
-            events.add(compile);
-            compiles.put(id, compile);
-            site = compile.getCall();
-        } else if (qname.equals("type")) {
-            type(search(atts, "id"), search(atts, "name"));
-        } else if (qname.equals("bc")) {
-            current_bci = Integer.parseInt(search(atts, "bci"));
-            current_bytecode = Integer.parseInt(search(atts, "code"));
-        } else if (qname.equals("klass")) {
-            type(search(atts, "id"), search(atts, "name"));
-        } else if (qname.equals("method")) {
-            String id = search(atts, "id");
-            Method m = new Method();
-            m.setHolder(type(search(atts, "holder")));
-            m.setName(search(atts, "name"));
-            m.setReturnType(type(search(atts, "return")));
-            String arguments = atts.getValue("arguments");;
-            if (arguments == null) {
-                m.setSignature("()" + sigtype(atts.getValue("return")));
-            } else {
-                String[] args = spacePattern.split(arguments);
-                StringBuilder sb = new StringBuilder("(");
-                for (int i = 0; i < args.length; i++) {
-                    sb.append(sigtype(args[i]));
-                }
-                sb.append(")");
-                sb.append(sigtype(atts.getValue("return")));
-                m.setSignature(sb.toString());
-            }
-
-            if (search(atts, "unloaded", "0").equals("0")) {
-               m.setBytes(search(atts, "bytes"));
-               m.setIICount(search(atts, "iicount"));
-               m.setFlags(search(atts, "flags"));
-            }
-            methods.put(id, m);
-        } else if (qname.equals("call")) {
-            if (methodHandleSite != null) {
-                methodHandleSite = null;
-            }
-            Method m = method(search(atts, "method"));
-            if (lateInlining && scopes.size() == 0) {
-                // re-attempting already seen call site (late inlining for MH invokes)
-                if (m != site.getMethod()) {
-                    if (current_bci != site.getBci()) {
-                        System.err.println(m + " bci: " + current_bci);
-                        System.err.println(site.getMethod() +  " bci: " + site.getBci());
-                        reportInternalError("bci mismatch after late inlining");
-                    }
-                    site.setMethod(m);
-                }
-            } else {
-                // We're dealing with a new call site; the called method is
-                // likely to be parsed next.
-                site = new CallSite(current_bci, m);
-            }
-            site.setCount(Integer.parseInt(search(atts, "count", "0")));
-            String receiver = atts.getValue("receiver");
-            if (receiver != null) {
-                site.setReceiver(type(receiver));
-                site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count")));
-            }
-            int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0"));
-            if (lateInlining && scopes.size() == 0) {
-                // The call was already added before this round of late
-                // inlining. Ignore.
-            } else if (methodHandle == 0) {
-                scopes.peek().add(site);
-            } else {
-                // method handle call site can be followed by another
-                // call (in case it is inlined). If that happens we
-                // discard the method handle call site. So we keep
-                // track of it but don't add it to the list yet.
-                methodHandleSite = site;
-            }
-        } else if (qname.equals("regalloc")) {
-            compile.setAttempts(Integer.parseInt(search(atts, "attempts")));
-        } else if (qname.equals("inline_fail")) {
-            if (methodHandleSite != null) {
-                scopes.peek().add(methodHandleSite);
-                methodHandleSite = null;
-            }
-            if (lateInlining && scopes.size() == 0) {
-                site.setReason("fail: " + search(atts, "reason"));
-                lateInlining = false;
-            } else {
-                scopes.peek().last().setReason("fail: " + search(atts, "reason"));
-            }
-        } else if (qname.equals("inline_success")) {
-            if (methodHandleSite != null) {
-                reportInternalError("method handle site should have been replaced");
-            }
-            site.setReason("succeed: " + search(atts, "reason"));
-        } else if (qname.equals("failure")) {
-            failureReason = search(atts, "reason");
-        } else if (qname.equals("task_done")) {
-            compile.setEnd(Double.parseDouble(search(atts, "stamp")));
-            if (Integer.parseInt(search(atts, "success")) == 0) {
-                compile.setFailureReason(failureReason);
-                failureReason = null;
-            }
-        } else if (qname.equals("make_not_entrant")) {
-            String id = makeId(atts);
-            NMethod nm = nmethods.get(id);
-            if (nm == null) reportInternalError("nm == null");
-            LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, "stamp")), id,
-                                                 atts.getValue("zombie") != null, nm);
-            events.add(e);
-        } else if (qname.equals("uncommon_trap")) {
-            String id = atts.getValue("compile_id");
-            if (id != null) {
-                id = makeId(atts);
-                currentTrap = new UncommonTrapEvent(Double.parseDouble(search(atts, "stamp")),
-                        id,
-                        atts.getValue("reason"),
-                        atts.getValue("action"),
-                        Integer.parseInt(search(atts, "count", "0")));
-                events.add(currentTrap);
-            } else {
-                if (atts.getValue("method") != null) {
-                    // These are messages from ciTypeFlow that don't
-                    // actually correspond to generated code.
-                    return;
-                }
-                try {
-                    if (scopes.size() == 0) {
-                        reportInternalError("scope underflow");
-                    }
-                    scopes.peek().add(new UncommonTrap(Integer.parseInt(search(atts, "bci")),
-                                                       search(atts, "reason"),
-                                                       search(atts, "action"),
-                                                       bytecodes[current_bytecode]));
-                } catch (Error e) {
-                    e.printStackTrace();
-                }
-            }
-        } else if (qname.startsWith("eliminate_lock")) {
-            String id = atts.getValue("compile_id");
-            if (id != null) {
-                id = makeId(atts);
-                String kind = atts.getValue("kind");
-                String classId = atts.getValue("class_id");
-                currentLockElimination = new LockElimination(qname, Double.parseDouble(search(atts, "stamp")), id, kind, classId);
-                events.add(currentLockElimination);
-            }
-        } else if (qname.equals("late_inline")) {
-            long inlineId = 0;
-            try {
-                inlineId = Long.parseLong(search(atts, "inline_id"));
-            } catch (InternalError ex) {
-                // Log files from older hotspots may lack inline_id,
-                // and zero is an acceptable substitute that allows processing to continue.
-            }
-            lateInlineScope = new ArrayDeque<>();
-            Method m = method(search(atts, "method"));
-            site = new CallSite(-999, m);
-            site.setInlineId(inlineId);
-            lateInlineScope.push(site);
-        } else if (qname.equals("jvms")) {
-            // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
-            if (currentTrap != null) {
-                String[] parts = spacePattern.split(atts.getValue("method"));
-                currentTrap.addMethodAndBCI(parts[0].replace('/', '.') + '.' + parts[1] + parts[2], Integer.parseInt(atts.getValue("bci")));
-            } else if (currentLockElimination != null) {
-                  currentLockElimination.addJVMS(method(atts.getValue("method")), Integer.parseInt(atts.getValue("bci")));
-            } else if (lateInlineScope != null) {
-                current_bci = Integer.parseInt(search(atts, "bci"));
-                Method m = method(search(atts, "method"));
-                site = new CallSite(current_bci, m);
-                lateInlineScope.push(site);
-            } else {
-                // Ignore <eliminate_allocation type='667'>,
-                //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
-            }
-        } else if (qname.equals("inline_id")) {
-            if (methodHandleSite != null) {
-                reportInternalError("method handle site should have been replaced");
-            }
-            long id = Long.parseLong(search(atts, "id"));
-            site.setInlineId(id);
-        } else if (qname.equals("nmethod")) {
-            String id = makeId(atts);
-            NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")),
-                    id,
-                    parseLong(atts.getValue("address")),
-                    parseLong(atts.getValue("size")));
-            nmethods.put(id, nm);
-            events.add(nm);
-        } else if (qname.equals("parse")) {
-            if (failureReason != null && scopes.size() == 0 && !lateInlining) {
-                // A compilation just failed, and we're back at a top
-                // compilation scope.
-                failureReason = null;
-                compile.reset();
-                site = compile.getCall();
-            }
-
-            // Error checking.
-            if (methodHandleSite != null) {
-                reportInternalError("method handle site should have been replaced");
-            }
-            Method m = method(search(atts, "method")); // this is the method being parsed
-            if (lateInlining && scopes.size() == 0) {
-                if (site.getMethod() != m) {
-                    reportInternalError("Unexpected method mismatch during late inlining (method at call site: " +
-                        site.getMethod() + ", method being parsed: " + m + ")");
-                }
-            }
-
-            if (scopes.size() == 0 && !lateInlining) {
-                // The method being parsed is actually the method being
-                // compiled; i.e., we're dealing with a compilation top scope,
-                // which we must consequently push to the scopes stack.
-                compile.setMethod(m);
-                scopes.push(site);
-            } else {
-                // The method being parsed is *not* the current compilation's
-                // top scope; i.e., we're dealing with an actual call site
-                // in the top scope or somewhere further down a call stack.
-                if (site.getMethod() == m) {
-                    // We're dealing with monomorphic inlining that didn't have
-                    // to be narrowed down, because the receiver was known
-                    // beforehand.
-                    scopes.push(site);
-                } else if (scopes.peek().getCalls().size() > 2 && m == scopes.peek().lastButOne().getMethod()) {
-                    // We're dealing with an at least bimorphic call site, and
-                    // the compiler has now decided to parse the last-but-one
-                    // method. The last one may already have been parsed for
-                    // inlining.
-                    scopes.push(scopes.peek().lastButOne());
-                } else {
-                    // The method has been narrowed down to the one we're now
-                    // going to parse, which is inlined here. It's monomorphic
-                    // inlining, but was not immediately clear as such.
-                    //
-                    // C1 prints multiple method tags during inlining when it
-                    // narrows the method being inlined. Example:
-                    //   ...
-                    //   <method id="813" holder="694" name="toString" return="695" flags="1" bytes="36" iicount="1"/>
-                    //   <call method="813" instr="invokevirtual"/>
-                    //   <inline_success reason="receiver is statically known"/>
-                    //   <method id="814" holder="792" name="toString" return="695" flags="1" bytes="5" iicount="3"/>
-                    //   <parse method="814">
-                    //   ...
-                    site.setMethod(m);
-                    scopes.push(site);
-                }
-            }
-        } else if (qname.equals("parse_done")) {
-            // Attach collected information about IR nodes to the current
-            // parsing scope before it's popped off the stack in endElement()
-            // (see where the parse tag is handled).
-            CallSite call = scopes.peek();
-            call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
-            call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
-            call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
-        }
-    }
-
-    /**
-     * Process the end of a compilation log XML element.<ul>
-     * <li><b>parse:</b> finish transforming a Java method's bytecode
-     * instructions to an initial compiler IR graph.</li>
-     * <li><b>uncommon_trap:</b> record the end of processing an uncommon trap,
-     * resetting {@link #currentTrap}.</li>
-     * <li><b>eliminate_lock:</b> record the end of a lock elimination,
-     * resetting {@link #currentLockElimination}.</li>
-     * <li><b>late_inline:</b> the closing tag for late_inline does not denote
-     * the end of a late inlining operation, but the end of the descriptive log
-     * data given at its beginning. That is, we're now in the position to
-     * assemble details about the inlining chain (bytecode instruction index in
-     * caller, called method). The {@link #lateInlining} flag is set to
-     * {@code true} here. (It will be reset when parsing the inlined methods is
-     * done; this happens for the successful case in this method as well, when
-     * {@code parse} elements are processed; and for inlining failures, in
-     * {@link #startElement()}, when {@code inline_fail} elements are
-     * processed.)</li>
-     * <li><b>task:</b> perform cleanup at the end of a compilation. Note that
-     * the explicit {@code task_done} event is handled in
-     * {@link #startElement()}.</li>
-     * </ul>
-     */
-    @Override
-    public void endElement(String uri, String localName, String qname) {
-        try {
-            if (qname.equals("parse")) {
-                // Finish dealing with the current call scope. If no more are
-                // left, no late inlining can be going on.
-                scopes.pop();
-                if (scopes.size() == 0) {
-                    lateInlining = false;
-                }
-            } else if (qname.equals("uncommon_trap")) {
-                currentTrap = null;
-            } else if (qname.startsWith("eliminate_lock")) {
-                currentLockElimination = null;
-            } else if (qname.equals("late_inline")) {
-                // Populate late inlining info.
-                if (scopes.size() != 0) {
-                    reportInternalError("scopes should be empty for late inline");
-                }
-                // late inline scopes are specified in reverse order:
-                // compiled method should be on top of stack.
-                CallSite caller = lateInlineScope.pop();
-                Method m = compile.getMethod();
-                if (!m.equals(caller.getMethod())) {
-                    reportInternalError(String.format("call site and late_inline info don't match:\n  method %s\n  caller method %s, bci %d", m, caller.getMethod(), current_bci));
-                }
-
-                // Walk down the inlining chain and assemble bci+callee info.
-                // This needs to be converted from caller+bci info contained in
-                // the late_inline data.
-                CallSite lateInlineSite = compile.getLateInlineCall();
-                ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<>();
-                do {
-                    current_bci = caller.getBci();
-                    // Next inlined call.
-                    caller = lateInlineScope.pop();
-                    CallSite callee = new CallSite(current_bci, caller.getMethod());
-                    callee.setInlineId(caller.getInlineId());
-                    thisCallScopes.addLast(callee);
-                    lateInlineSite.add(callee);
-                    lateInlineSite = callee;
-                } while (!lateInlineScope.isEmpty());
-
-                site = compile.getCall().findCallSite(thisCallScopes);
-                if (site == null) {
-                    // Call site could not be found - report the problem in detail.
-                    System.err.println("call scopes:");
-                    for (CallSite c : thisCallScopes) {
-                        System.err.println(c.getMethod() + " " + c.getBci() + " " + c.getInlineId());
-                    }
-                    CallSite c = thisCallScopes.getLast();
-                    if (c.getInlineId() != 0) {
-                        System.err.println("Looking for call site in entire tree:");
-                        ArrayDeque<CallSite> stack = compile.getCall().findCallSite2(c);
-                        for (CallSite c2 : stack) {
-                            System.err.println(c2.getMethod() + " " + c2.getBci() + " " + c2.getInlineId());
-                        }
-                    }
-                    System.err.println(caller.getMethod() + " bci: " + current_bci);
-                    reportInternalError("couldn't find call site");
-                }
-                lateInlining = true;
-
-                if (caller.getBci() != -999) {
-                    System.out.println(caller.getMethod());
-                    reportInternalError("broken late_inline info");
-                }
-                if (site.getMethod() != caller.getMethod()) {
-                    if (site.getInlineId() == caller.getInlineId()) {
-                        site.setMethod(caller.getMethod());
-                    } else {
-                        System.out.println(site.getMethod());
-                        System.out.println(caller.getMethod());
-                        reportInternalError("call site and late_inline info don't match");
-                    }
-                }
-                // late_inline is followed by parse with scopes.size() == 0,
-                // 'site' will be pushed to scopes.
-                lateInlineScope = null;
-            } else if (qname.equals("task")) {
-                types.clear();
-                methods.clear();
-                site = null;
-            }
-        } catch (Exception e) {
-            reportInternalError("exception while processing end element", e);
-        }
-    }
-
-    //
-    // Handlers for problems that occur in XML parsing itself.
-    //
-
-    @Override
-    public void warning(org.xml.sax.SAXParseException e) {
-        System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
-        e.printStackTrace();
-    }
-
-    @Override
-    public void error(org.xml.sax.SAXParseException e) {
-        System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
-        e.printStackTrace();
-    }
-
-    @Override
-    public void fatalError(org.xml.sax.SAXParseException e) {
-        System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
-        e.printStackTrace();
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-
-/**
- * In a compilation log, represent the event of making a given compiled method
- * not-entrant, e.g., during an OSR compilation.
- */
-class MakeNotEntrantEvent extends BasicLogEvent {
-
-    /**
-     * Denote whether the method is marked as a zombie, i.e., no further
-     * activations exist.
-     */
-    private final boolean zombie;
-
-    /**
-     * The method in question.
-     */
-    private NMethod nmethod;
-
-    MakeNotEntrantEvent(double s, String i, boolean z, NMethod nm) {
-        super(s, i);
-        zombie = z;
-        nmethod = nm;
-    }
-
-    public NMethod getNMethod() {
-        return nmethod;
-    }
-
-    public void print(PrintStream stream, boolean printID) {
-        if (isZombie()) {
-            stream.printf("%s make_zombie\n", getId());
-        } else {
-            stream.printf("%s make_not_entrant\n", getId());
-        }
-    }
-
-    public boolean isZombie() {
-        return zombie;
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.util.Arrays;
-
-import static com.sun.hotspot.tools.compiler.Constants.*;
-
-/**
- * Representation of a Java method in a compilation log.
- */
-public class Method {
-
-    /**
-     * The name of the class holding the method.
-     */
-    private String holder;
-
-    /**
-     * The method's name.
-     */
-    private String name;
-
-    /**
-     * The return type of the method, as a fully qualified (source-level) class
-     * or primitive type name.
-     */
-    private String returnType;
-
-    /**
-     * The method's signature, in internal form.
-     */
-    private String signature;
-
-    /**
-     * The length of the method's byte code.
-     */
-    private String bytes;
-
-    /**
-     * The number of times this method was invoked in the interpreter.
-     */
-    private String iicount;
-
-    /**
-     * The method's flags, in the form of a {@code String} representing the
-     * {@code int} encoding them.
-     */
-    private String flags;
-
-    /**
-     * Decode the {@link flags} numerical string to a format for console
-     * output. The result does not honour all possible flags but includes
-     * information about OSR compilation.
-     *
-     * @param osr_bci the byte code index at which an OSR compilation takes
-     * place, or -1 if the compilation is not an OSR one.
-     */
-    String decodeFlags(int osr_bci) {
-        int f = Integer.parseInt(getFlags());
-        char[] c = new char[4];
-        Arrays.fill(c, ' ');
-        if (osr_bci >= 0) {
-            c[0] = '%';
-        }
-        if ((f & JVM_ACC_SYNCHRONIZED) != 0) {
-            c[1] = 's';
-        }
-        return new String(c);
-    }
-
-    /**
-     * Format this method for console output.
-     *
-     * @param osr_bci the byte code index at which OSR takes place, or -1 if no
-     * OSR compilation is going on.
-     */
-    String format(int osr_bci) {
-        if (osr_bci >= 0) {
-            return getHolder() + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
-        } else {
-            return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
-        }
-    }
-
-    @Override
-    public String toString() {
-        return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
-    }
-
-    public String getFullName() {
-        return getHolder().replace('/', '.') + "." + getName() + signature;
-    }
-
-    public String getHolder() {
-        return holder;
-    }
-
-    public void setHolder(String holder) {
-        this.holder = holder;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getReturnType() {
-        return returnType;
-    }
-
-    public void setReturnType(String returnType) {
-        this.returnType = returnType;
-    }
-
-    public String getSignature() {
-        return signature;
-    }
-
-    public void setSignature(String signature) {
-        this.signature = signature.replace('/', '.');
-    }
-
-    public String getArguments() {
-        return signature.substring(0, signature.indexOf(')') + 1);
-    }
-
-    public String getBytes() {
-        return bytes;
-    }
-
-    public void setBytes(String bytes) {
-        this.bytes = bytes;
-    }
-
-    public String getIICount() {
-        return iicount;
-    }
-
-    public void setIICount(String iicount) {
-        this.iicount = iicount;
-    }
-
-    public String getFlags() {
-        return flags;
-    }
-
-    public void setFlags(String flags) {
-        this.flags = flags;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof Method) {
-            Method other = (Method) o;
-            return holder.equals(other.holder) && name.equals(other.name) && signature.equals(other.signature);
-        }
-        return false;
-    }
-
-    public int hashCode() {
-        return holder.hashCode() ^ name.hashCode();
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-
-/**
- * A compilation log event that is signalled whenever a new nmethod (a native
- * method, a compilation result) is created.
- */
-public class NMethod extends BasicLogEvent {
-
-    /**
-     * The nmethod's starting address in memory.
-     */
-    private long address;
-
-    /**
-     * The nmethod's size in bytes.
-     */
-    private long size;
-
-    NMethod(double s, String i, long a, long sz) {
-        super(s, i);
-        address = a;
-        size = sz;
-    }
-
-    public void print(PrintStream out, boolean printID) {
-        // XXX Currently we do nothing
-        // throw new InternalError();
-    }
-
-    public long getAddress() {
-        return address;
-    }
-
-    public void setAddress(long address) {
-        this.address = address;
-    }
-
-    public long getSize() {
-        return size;
-    }
-
-    public void setSize(long size) {
-        this.size = size;
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-
-/**
- * Representation of a compilation phase as a log event.
- */
-public class Phase extends BasicLogEvent {
-
-    /**
-     * The number of nodes in the compilation at the beginning of this phase.
-     */
-    private final int startNodes;
-
-    /**
-     * The number of nodes in the compilation at the end of this phase.
-     */
-    private int endNodes;
-
-    /**
-     * The number of live nodes in the compilation at the beginning of this
-     * phase.
-     */
-    private final int startLiveNodes;
-
-    /**
-     * The number of live nodes in the compilation at the end of this phase.
-     */
-    private int endLiveNodes;
-
-    Phase(String n, double s, int nodes, int live) {
-        super(s, n);
-        startNodes = nodes;
-        startLiveNodes = live;
-    }
-
-    int getNodes() {
-        return getEndNodes() - getStartNodes();
-    }
-
-    void setEndNodes(int n) {
-        endNodes = n;
-    }
-
-    public String getName() {
-        return getId();
-    }
-
-    public int getStartNodes() {
-        return startNodes;
-    }
-
-    public int getEndNodes() {
-        return endNodes;
-    }
-
-    /**
-     * The number of live nodes added by this phase.
-     */
-    int getAddedLiveNodes() {
-        return getEndLiveNodes() - getStartLiveNodes();
-    }
-
-    void setEndLiveNodes(int n) {
-        endLiveNodes = n;
-    }
-
-    public int getStartLiveNodes() {
-        return startLiveNodes;
-    }
-
-    public int getEndLiveNodes() {
-        return endLiveNodes;
-    }
-
-    @Override
-    public void print(PrintStream stream, boolean printID) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrap.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-
-/**
- * An instance of this class represents an uncommon trap associated with a
- * given bytecode instruction. An uncommon trap is described in terms of its
- * reason and action to be taken. An instance of this class is always relative
- * to a specific method and only contains the relevant bytecode instruction
- * index.
- */
-class UncommonTrap {
-
-    private int bci;
-    private String reason;
-    private String action;
-    private String bytecode;
-
-    public UncommonTrap(int b, String r, String a, String bc) {
-        bci = b;
-        reason = r;
-        action = a;
-        bytecode = bc;
-    }
-
-    public int getBCI() {
-        return bci;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    public String getAction() {
-        return action;
-    }
-
-    public String getBytecode() {
-        return bytecode;
-    }
-
-    void emit(PrintStream stream, int indent) {
-        for (int i = 0; i < indent; i++) {
-            stream.print(' ');
-        }
-    }
-
-    public void print(PrintStream stream, int indent) {
-        emit(stream, indent);
-        stream.println(this);
-    }
-
-    public String toString() {
-        return "@ " + bci  + " " + getBytecode() + " uncommon trap " + getReason() + " " + getAction();
-    }
-}
--- a/src/utils/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents an uncommon trap encountered during a compilation.
- */
-class UncommonTrapEvent extends BasicLogEvent {
-
-    private final String reason;
-    private final String action;
-
-    /**
-     * Denote how many times this trap has been encountered.
-     */
-    private int count;
-
-    /**
-     * The name of the bytecode instruction at which the trap occurred.
-     */
-    private String bytecode;
-
-    private List<String> jvmsMethods = new ArrayList<>();
-
-    private List<Integer> jvmsBCIs = new ArrayList<>();
-
-    UncommonTrapEvent(double s, String i, String r, String a, int c) {
-        super(s, i);
-        reason = r;
-        action = a;
-        count = c;
-    }
-
-    public void updateCount(UncommonTrapEvent trap) {
-        setCount(Math.max(getCount(), trap.getCount()));
-    }
-
-    public void print(PrintStream stream, boolean printID) {
-        if (printID) {
-            stream.print(getId() + " ");
-        }
-        stream.printf("uncommon trap %s %s %s\n", bytecode, getReason(), getAction());
-        int indent = 2;
-        for (int j = 0; j < jvmsMethods.size(); j++) {
-            for (int i = 0; i < indent; i++) {
-                stream.print(' ');
-            }
-            stream.println("@ " + jvmsBCIs.get(j) + " " + jvmsMethods.get(j));
-            indent += 2;
-        }
-    }
-
-
-    public String getReason() {
-        return reason;
-    }
-
-    public String getAction() {
-        return action;
-    }
-
-    public int getCount() {
-        return count;
-    }
-
-    public void setCount(int count) {
-        this.count = count;
-    }
-
-    /**
-     * Set the compilation for this event. This involves identifying the call
-     * site to which this uncommon trap event belongs. In addition to setting
-     * the {@link #compilation} link, this method will consequently also set
-     * the {@link #bytecode} field.
-     */
-    public void setCompilation(Compilation compilation) {
-        super.setCompilation(compilation);
-        // Attempt to associate a bytecode with with this trap
-        CallSite site = compilation.getCall();
-        int i = 0;
-        try {
-            List<UncommonTrap> traps = site.getTraps();
-            while (i + 1 < jvmsMethods.size()) {
-                if (!jvmsMethods.get(i).equals(site.getMethod().getFullName())) {
-                    throw new InternalError(jvmsMethods.get(i) + " != " + site.getMethod().getFullName());
-                }
-                CallSite result = null;
-                for (CallSite call : site.getCalls()) {
-                    if (call.getBci() == jvmsBCIs.get(i) &&
-                        call.getMethod().getFullName().equals(jvmsMethods.get(i + 1)) &&
-                        call.getReceiver() == null) {
-                        result = call;
-                        i++;
-                        break;
-                    }
-                }
-                if (result == null) {
-                    throw new InternalError("couldn't find call site");
-                }
-                site = result;
-                traps = site.getTraps();
-            }
-            for (UncommonTrap trap : traps) {
-                if (trap.getBCI() == jvmsBCIs.get(i) &&
-                    trap.getReason().equals(getReason()) &&
-                    trap.getAction().equals(getAction())) {
-                    bytecode = trap.getBytecode();
-                    return;
-                }
-            }
-            throw new InternalError("couldn't find bytecode");
-        } catch (Exception e) {
-            bytecode = "<unknown>";
-        }
-    }
-
-    public void addMethodAndBCI(String method, int bci) {
-        jvmsMethods.add(0, method);
-        jvmsBCIs.add(0, bci);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/BasicLogEvent.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * Provide basic data structures and behaviour for {@link LogEvent}s.
+ */
+public abstract class BasicLogEvent implements LogEvent {
+
+    /**
+     * The event's ID. This is a number; we represent it as a string for
+     * convenience.
+     */
+    protected final String id;
+
+    /**
+     * The event's start time.
+     */
+    protected final double start;
+
+    /**
+     * The event's end time.
+     */
+    protected double end;
+
+    /**
+     * The compilation during which this event was signalled.
+     */
+    protected Compilation compilation;
+
+    BasicLogEvent(double start, String id) {
+        this.start = start;
+        this.end = start;
+        this.id = id;
+    }
+
+    public final double getStart() {
+        return start;
+    }
+
+    public final double getEnd() {
+        return end;
+    }
+
+    public final void setEnd(double end) {
+        this.end = end;
+    }
+
+    public final double getElapsedTime() {
+        return ((int) ((getEnd() - getStart()) * 1000)) / 1000.0;
+    }
+
+    public final String getId() {
+        return id;
+    }
+
+    public final Compilation getCompilation() {
+        return compilation;
+    }
+
+    /**
+     * Set the compilation for this event. This is not a {@code final} method
+     * as it is overridden in {@link UncommonTrapEvent}.
+     */
+    public void setCompilation(Compilation compilation) {
+        this.compilation = compilation;
+    }
+
+    abstract public void print(PrintStream stream, boolean printID);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/CallSite.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of a compilation scope in a compilation log. This class is a
+ * hybrid: its instances can represent original scopes of methods being
+ * compiled, but are also used to represent call sites in given methods.
+ */
+public class CallSite {
+
+    /**
+     * The index of the call in the caller. This will be 0 if this instance
+     * represents a compilation root.
+     */
+    private int bci;
+
+    /**
+     * The method that is called at this call site. This will be {@code null}
+     * if this instance represents a compilation root.
+     */
+    private Method method;
+
+    /**
+     * The invocation count for this call site.
+     */
+    private int count;
+
+    /**
+     * The receiver type of the call represented by this instance, if known.
+     */
+    private String receiver;
+
+    /**
+     * In case the {@linkplain receiver receiver type} of the call represented
+     * by this instance is known, this is how often the type was encountered.
+     */
+    private int receiver_count;
+
+    /**
+     * The reason for a success or failure of an inlining operation at this
+     * call site.
+     */
+    private String reason;
+
+    /**
+     * A list of all calls in this compilation scope.
+     */
+    private List<CallSite> calls;
+
+    /**
+     * Number of nodes in the graph at the end of parsing this compilation
+     * scope.
+     */
+    private int endNodes;
+
+    /**
+     * Number of live nodes in the graph at the end of parsing this compilation
+     * scope.
+     */
+    private int endLiveNodes;
+
+    /**
+     * Time in seconds since VM startup at which parsing this compilation scope
+     * ended.
+     */
+    private double timeStamp;
+
+    /**
+     * The inline ID in case the call represented by this instance is inlined,
+     * 0 otherwise.
+     */
+    private long inlineId;
+
+    /**
+     * List of uncommon traps in this compilation scope.
+     */
+    private List<UncommonTrap> traps;
+
+    /**
+     * Default constructor: used to create an instance that represents the top
+     * scope of a compilation.
+     */
+    CallSite() {}
+
+    /**
+     * Constructor to create an instance that represents an actual method call.
+     */
+    CallSite(int bci, Method m) {
+        this.bci = bci;
+        this.method = m;
+    }
+
+    /**
+     * Add a call site to the compilation scope represented by this instance.
+     */
+    void add(CallSite site) {
+        if (getCalls() == null) {
+            calls = new ArrayList<>();
+        }
+        getCalls().add(site);
+    }
+
+    /**
+     * Return the last of the {@linkplain #getCalls() call sites} in this
+     * compilation scope.
+     */
+    CallSite last() {
+        return getCalls().get(getCalls().size() - 1);
+    }
+
+    /**
+     * Return the last-but-one of the {@linkplain #getCalls() call sites} in
+     * this compilation scope.
+     */
+    CallSite lastButOne() {
+        return getCalls().get(getCalls().size() - 2);
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        if (getReason() == null) {
+            sb.append("  @ " + getBci() + " " + getMethod());
+        } else {
+            sb.append("- @ " + getBci() + " " + getMethod() + " " + getReason());
+        }
+        sb.append("\n");
+        if (getCalls() != null) {
+            for (CallSite site : getCalls()) {
+                sb.append(site);
+                sb.append("\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    public void print(PrintStream stream) {
+        print(stream, 0, true, false);
+    }
+
+    void emit(PrintStream stream, int indent) {
+        for (int i = 0; i < indent; i++) {
+            stream.print(' ');
+        }
+    }
+
+    public void print(PrintStream stream, int indent, boolean printInlining, boolean printUncommonTraps) {
+        emit(stream, indent);
+        String m = getMethod().getHolder() + "::" + getMethod().getName();
+        if (getReason() == null) {
+            stream.print("  @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)");
+        } else {
+            stream.print("  @ " + getBci() + " " + m + " " + getReason());
+        }
+        stream.printf(" (end time: %6.4f", getTimeStamp());
+        if (getEndNodes() > 0) {
+            stream.printf(" nodes: %d live: %d", getEndNodes(), getEndLiveNodes());
+        }
+        stream.println(")");
+
+        if (getReceiver() != null) {
+            emit(stream, indent + 4);
+            stream.println("type profile " + getMethod().getHolder() + " -> " + getReceiver() + " (" +
+                    (getReceiverCount() * 100 / getCount()) + "%)");
+        }
+        if (printInlining && getCalls() != null) {
+            for (CallSite site : getCalls()) {
+                site.print(stream, indent + 2, printInlining, printUncommonTraps);
+            }
+        }
+        if (printUncommonTraps && getTraps() != null) {
+            for (UncommonTrap site : getTraps()) {
+                site.print(stream, indent + 2);
+            }
+        }
+    }
+
+    public int getBci() {
+        return bci;
+    }
+
+    public void setBci(int bci) {
+        this.bci = bci;
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    public void setMethod(Method method) {
+        this.method = method;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public String getReceiver() {
+        return receiver;
+    }
+
+    public void setReceiver(String receiver) {
+        this.receiver = receiver;
+    }
+
+    public int getReceiverCount() {
+        return receiver_count;
+    }
+
+    public void setReceiver_count(int receiver_count) {
+        this.receiver_count = receiver_count;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public List<CallSite> getCalls() {
+        return calls;
+    }
+
+    public List<UncommonTrap> getTraps() {
+        return traps;
+    }
+
+    void add(UncommonTrap e) {
+        if (traps == null) {
+            traps = new ArrayList<UncommonTrap>();
+        }
+        traps.add(e);
+    }
+
+    void setEndNodes(int n) {
+        endNodes = n;
+    }
+
+    public int getEndNodes() {
+        return endNodes;
+    }
+
+    void setEndLiveNodes(int n) {
+        endLiveNodes = n;
+    }
+
+    public int getEndLiveNodes() {
+        return endLiveNodes;
+    }
+
+    void setTimeStamp(double time) {
+        timeStamp = time;
+    }
+
+    public double getTimeStamp() {
+        return timeStamp;
+    }
+
+    /**
+     * Check whether this call site matches another. Every late inline call
+     * site has a unique inline ID. If the call site we're looking for has one,
+     * then use it; otherwise rely on method name and byte code index.
+     */
+    private boolean matches(CallSite other) {
+        if (other.inlineId != 0) {
+            return inlineId == other.inlineId;
+        }
+        return method.equals(other.method) && bci == other.bci;
+    }
+
+    /**
+     * Locate a late inline call site: find, in this instance's
+     * {@linkplain #calls call sites}, the one furthest down the given call
+     * stack.
+     *
+     * Multiple chains of identical call sites with the same method name / bci
+     * combination are possible, so we have to try them all until we find the
+     * late inline call site that has a matching inline ID.
+     *
+     * @return a matching call site, or {@code null} if none was found.
+     */
+    public CallSite findCallSite(ArrayDeque<CallSite> sites) {
+        if (calls == null) {
+            return null;
+        }
+        CallSite site = sites.pop();
+        for (CallSite c : calls) {
+            if (c.matches(site)) {
+                if (!sites.isEmpty()) {
+                    CallSite res = c.findCallSite(sites);
+                    if (res != null) {
+                        sites.push(site);
+                        return res;
+                    }
+                } else {
+                    sites.push(site);
+                    return c;
+                }
+            }
+        }
+        sites.push(site);
+        return null;
+    }
+
+    /**
+     * Locate a late inline call site in the tree spanned by all this instance's
+     * {@linkplain #calls call sites}, and return the sequence of call sites
+     * (scopes) leading to that late inline call site.
+     */
+    public ArrayDeque<CallSite> findCallSite2(CallSite site) {
+        if (calls == null) {
+            return null;
+        }
+
+        for (CallSite c : calls) {
+            if (c.matches(site)) {
+                ArrayDeque<CallSite> stack = new ArrayDeque<>();
+                stack.push(c);
+                return stack;
+            } else {
+                ArrayDeque<CallSite> stack = c.findCallSite2(site);
+                if (stack != null) {
+                    stack.push(c);
+                    return stack;
+                }
+            }
+        }
+        return null;
+    }
+
+    public long getInlineId() {
+        return inlineId;
+    }
+
+    public void setInlineId(long inlineId) {
+        this.inlineId = inlineId;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/Compilation.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+
+/**
+ * One particular compilation, represented in the compilation log file as a
+ * {@code task} element.
+ */
+public class Compilation implements LogEvent {
+
+    /**
+     * The compilation ID.
+     */
+    private int id;
+
+    /**
+     * Whether this is a compilation for on-stack replacement (OSR).
+     */
+    private boolean osr;
+
+    /**
+     * The method being compiled.
+     */
+    private Method method;
+
+    /**
+     * The {@linkplain CallSite scope} of this compilation. This is created as
+     * an empty {@link CallSite} instance, to be filled with data (and
+     * meaning) later on.
+     */
+    private CallSite call = new CallSite();
+
+    /**
+     * In case a {@code late_inline} event occurs during the compilation, this
+     * field holds the information about it.
+     */
+    private CallSite lateInlineCall = new CallSite();
+
+    /**
+     * The bytecode instruction index for on-stack replacement compilations; -1
+     * if this is not an OSR compilation.
+     */
+    private int bci;
+
+    /**
+     * The method under compilation's invocation count.
+     */
+    private String icount;
+
+    /**
+     * The method under compilation's backedge count.
+     */
+    private String bcount;
+
+    /**
+     * Additional information for special compilations (e.g., adapters).
+     */
+    private String special;
+
+    /**
+     * The name of the compiler performing this compilation.
+     */
+    private String compiler;
+
+    /**
+     * Start time stamp.
+     */
+    private double start;
+
+    /**
+     * End time stamp.
+     */
+    private double end;
+
+    /**
+     * Trip count of the register allocator.
+     */
+    private int attempts;
+
+    /**
+     * The compilation result (a native method).
+     */
+    private NMethod nmethod;
+
+    /**
+     * The phases through which this compilation goes.
+     */
+    private ArrayList<Phase> phases = new ArrayList<>(4);
+
+    /**
+     * In case this compilation fails, the reason for that.
+     */
+    private String failureReason;
+
+    Compilation(int id) {
+        this.id = id;
+    }
+
+    void reset() {
+        call = new CallSite();
+        lateInlineCall = new CallSite();
+        phases = new ArrayList<>(4);
+    }
+
+    /**
+     * Get a compilation phase by name, or {@code null}.
+     *
+     * @param s the name of the phase to retrieve in this compilation.
+     *
+     * @return a compilation phase, or {@code null} if no phase with the given
+     *         name is found.
+     */
+    Phase getPhase(String s) {
+        for (Phase p : getPhases()) {
+            if (p.getName().equals(s)) {
+                return p;
+            }
+        }
+        return null;
+    }
+
+    double getRegallocTime() {
+        return getPhase("regalloc").getElapsedTime();
+    }
+
+    public double getStart() {
+        return start;
+    }
+
+    public void setCompiler(String compiler) {
+        this.compiler = compiler;
+    }
+
+    public String getCompiler() {
+        return compiler;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getId());
+        sb.append(" ");
+        sb.append(getCompiler());
+        sb.append(" ");
+        sb.append(getMethod());
+        sb.append(" ");
+        sb.append(getIcount());
+        sb.append("+");
+        sb.append(getBcount());
+        sb.append("\n");
+        if (getCall() != null && getCall().getCalls() != null) {
+            for (CallSite site : getCall().getCalls()) {
+                sb.append(site);
+                sb.append("\n");
+            }
+        }
+        if (getLateInlineCall().getCalls() != null) {
+            sb.append("late inline:\n");
+            for (CallSite site : getLateInlineCall().getCalls()) {
+                sb.append(site);
+                sb.append("\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    public void printShort(PrintStream stream) {
+        if (getMethod() == null) {
+            stream.println(getSpecial());
+        } else {
+            int bc = isOsr() ? getBCI() : -1;
+            stream.print(getId() + getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
+        }
+    }
+
+    public void print(PrintStream stream, boolean printID) {
+        print(stream, 0, printID, true, false);
+    }
+
+    public void print(PrintStream stream, boolean printID, boolean printInlining) {
+        print(stream, 0, printID, printInlining, false);
+    }
+
+    public void print(PrintStream stream, boolean printID, boolean printInlining, boolean printUncommonTraps) {
+        print(stream, 0, printID, printInlining, printUncommonTraps);
+    }
+
+    public void print(PrintStream stream, int indent, boolean printID, boolean printInlining, boolean printUncommonTraps) {
+        if (getMethod() == null) {
+            stream.println(getSpecial());
+        } else {
+            if (printID) {
+                stream.print(getId());
+            }
+            int bc = isOsr() ? getBCI() : -1;
+            stream.print(getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
+            stream.println();
+            if (getFailureReason() != null) {
+                stream.println("COMPILE SKIPPED: " + getFailureReason() + " (not retryable)");
+            }
+            if (printInlining && call.getCalls() != null) {
+                for (CallSite site : call.getCalls()) {
+                    site.print(stream, indent + 2, printInlining, printUncommonTraps);
+                }
+            }
+            if (printUncommonTraps && call.getTraps() != null) {
+                for (UncommonTrap site : call.getTraps()) {
+                    site.print(stream, indent + 2);
+                }
+            }
+            if (printInlining && lateInlineCall.getCalls() != null) {
+                stream.println("late inline:");
+                for (CallSite site : lateInlineCall.getCalls()) {
+                    site.print(stream, indent + 2, printInlining, printUncommonTraps);
+                }
+            }
+        }
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public boolean isOsr() {
+        return osr;
+    }
+
+    public void setOsr(boolean osr) {
+        this.osr = osr;
+    }
+
+    public int getBCI() {
+        return bci;
+    }
+
+    public void setBCI(int osrBci) {
+        this.bci = osrBci;
+    }
+
+    public String getIcount() {
+        return icount;
+    }
+
+    public void setICount(String icount) {
+        this.icount = icount;
+    }
+
+    public String getBcount() {
+        return bcount;
+    }
+
+    public void setBCount(String bcount) {
+        this.bcount = bcount;
+    }
+
+    public String getSpecial() {
+        return special;
+    }
+
+    public void setSpecial(String special) {
+        this.special = special;
+    }
+
+    public void setStart(double start) {
+        this.start = start;
+    }
+
+    public double getEnd() {
+        return end;
+    }
+
+    public void setEnd(double end) {
+        this.end = end;
+    }
+
+    public int getAttempts() {
+        return attempts;
+    }
+
+    public void setAttempts(int attempts) {
+        this.attempts = attempts;
+    }
+
+    public NMethod getNMethod() {
+        return nmethod;
+    }
+
+    public void setNMethod(NMethod NMethod) {
+        this.nmethod = NMethod;
+    }
+
+    public ArrayList<Phase> getPhases() {
+        return phases;
+    }
+
+    public String getFailureReason() {
+        return failureReason;
+    }
+
+    public void setFailureReason(String failureReason) {
+        this.failureReason = failureReason;
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    /**
+     * Set the method under compilation. If it is already set, ignore the
+     * argument to avoid changing the method by post-parse inlining info.
+     *
+     * @param method the method under compilation. May be ignored.
+     */
+    public void setMethod(Method method) {
+        if (getMethod() == null) {
+            this.method = method;
+        }
+    }
+
+    public CallSite getCall() {
+        return call;
+    }
+
+    public CallSite getLateInlineCall() {
+        return lateInlineCall;
+    }
+
+    public double getElapsedTime() {
+        return end - start;
+    }
+
+    public Compilation getCompilation() {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/Constants.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2009, 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 com.sun.hotspot.tools.compiler;
+
+interface Constants {
+    static final int  JVM_ACC_PUBLIC        = 0x0001;  /* visible to everyone */
+    static final int  JVM_ACC_PRIVATE       = 0x0002;  /* visible only to the defining class */
+    static final int  JVM_ACC_PROTECTED     = 0x0004;  /* visible to subclasses */
+    static final int  JVM_ACC_STATIC        = 0x0008;  /* instance variable is static */
+    static final int  JVM_ACC_FINAL         = 0x0010;  /* no further subclassing, overriding */
+    static final int  JVM_ACC_SYNCHRONIZED  = 0x0020;  /* wrap method call in monitor lock */
+    static final int  JVM_ACC_SUPER         = 0x0020;  /* funky handling of invokespecial */
+    static final int  JVM_ACC_VOLATILE      = 0x0040;  /* can not cache in registers */
+    static final int  JVM_ACC_BRIDGE        = 0x0040;  /* bridge method generated by compiler */
+    static final int  JVM_ACC_TRANSIENT     = 0x0080;  /* not persistent */
+    static final int  JVM_ACC_VARARGS       = 0x0080;  /* method declared with variable number of args */
+    static final int  JVM_ACC_NATIVE        = 0x0100;  /* implemented in C */
+    static final int  JVM_ACC_INTERFACE     = 0x0200;  /* class is an interface */
+    static final int  JVM_ACC_ABSTRACT      = 0x0400;  /* no definition provided */
+    static final int  JVM_ACC_STRICT        = 0x0800;  /* strict floating point */
+    static final int  JVM_ACC_SYNTHETIC     = 0x1000;  /* compiler-generated class, method or field */
+    static final int  JVM_ACC_ANNOTATION    = 0x2000;  /* annotation type */
+    static final int  JVM_ACC_ENUM          = 0x4000;  /* field is declared as element of enum */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogCleanupReader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.*;
+import java.util.regex.*;
+
+/**
+ * This class is a filter class to deal with malformed XML that used
+ * to be produced by the JVM when generating LogCompilation.  In 1.6
+ * and later releases it shouldn't be required.
+ */
+class LogCleanupReader extends Reader {
+
+    private Reader reader;
+
+    private char[] buffer = new char[4096];
+
+    private int bufferCount;
+
+    private int bufferOffset;
+
+    private char[] line = new char[1024];
+
+    private int index;
+
+    private int length;
+
+    private char[] one = new char[1];
+
+    LogCleanupReader(Reader r) {
+        reader = r;
+    }
+
+    static final private Matcher duplicateCompileID = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher("");
+    static final private Matcher compilerName = Pattern.compile("' (C[12]) compile_id=").matcher("");
+    static final private Matcher destroyVM = Pattern.compile("'(destroy_vm)/").matcher("");
+
+    /**
+     * The log cleanup takes place in this method. If any of the three patterns
+     * ({@link #duplicateCompileID}, {@link #compilerName}, {@link #destroyVM})
+     * match, that indicates a problem in the log. The cleanup is performed by
+     * correcting the input line and writing it back into the {@link #line}
+     * buffer.
+     */
+    private void fill() throws IOException {
+        rawFill();
+        if (length != -1) {
+            boolean changed = false;
+            String s = new String(line, 0, length);
+
+            compilerName.reset(s);
+            if (compilerName.find()) {
+                s = s.substring(0, compilerName.start(1)) + s.substring(compilerName.end(1) + 1);
+                changed = true;
+            }
+
+            duplicateCompileID.reset(s);
+            if (duplicateCompileID.lookingAt()) {
+                s = s.substring(0, duplicateCompileID.start(1)) + s.substring(duplicateCompileID.end(1) + 1);
+                changed = true;
+            }
+
+            destroyVM.reset(s);
+            if (destroyVM.find()) {
+                s = s.substring(0, destroyVM.start(1)) + s.substring(destroyVM.end(1));
+                changed = true;
+            }
+
+            if (changed) {
+                s.getChars(0, s.length(), line, 0);
+                length = s.length();
+            }
+        }
+    }
+
+    private void rawFill() throws IOException {
+        if (bufferCount == -1) {
+            length = -1;
+            return;
+        }
+
+        int i = 0;
+        boolean fillNonEOL = true;
+        outer:
+        while (true) {
+            if (fillNonEOL) {
+                int p;
+                for (p = bufferOffset; p < bufferCount; p++) {
+                    char c = buffer[p];
+                    if (c == '\r' || c == '\n') {
+                        bufferOffset = p;
+                        fillNonEOL = false;
+                        continue outer;
+                    }
+                    if (i >= line.length) {
+                        // copy and enlarge the line array
+                        char[] newLine = new char[line.length * 2];
+                        System.arraycopy(line, 0, newLine, 0, line.length);
+                        line = newLine;
+                    }
+                    line[i++] = c;
+                }
+                bufferOffset = p;
+            } else {
+                int p;
+                for (p = bufferOffset; p < bufferCount; p++) {
+                    char c = buffer[p];
+                    if (c != '\r' && c != '\n') {
+                        bufferOffset = p;
+                        length = i;
+                        index = 0;
+                        return;
+                    }
+                    line[i++] = c;
+                }
+                bufferOffset = p;
+            }
+            if (bufferCount == -1) {
+                if (i == 0) {
+                    length = -1;
+                } else {
+                    length = i;
+                }
+                index = 0;
+                return;
+            }
+            if (bufferOffset != bufferCount) {
+                System.out.println(bufferOffset);
+                System.out.println(bufferCount);
+                throw new InternalError("how did we get here");
+            }
+            // load more data and try again.
+            bufferCount = reader.read(buffer, 0, buffer.length);
+            bufferOffset = 0;
+        }
+    }
+
+    public int read() throws java.io.IOException {
+        read(one, 0, 1);
+        return one[0];
+    }
+
+    public int read(char[] buffer) throws java.io.IOException {
+        return read(buffer, 0, buffer.length);
+    }
+
+    public int read(char[] b, int off, int len) throws java.io.IOException {
+        if (length == -1) {
+            return -1;
+        }
+
+        if (index == length) {
+            fill();
+            if (length == -1) {
+                return -1;
+            }
+        }
+        int n = Math.min(length - index, Math.min(b.length - off, len));
+        // System.out.printf("%d %d %d %d %d\n", index, length, off, len, n);
+        System.arraycopy(line, index, b, off, n);
+        index += n;
+        return n;
+    }
+
+    public long skip(long n) throws java.io.IOException {
+        long result = n;
+        while (n-- > 0) read();
+        return result;
+    }
+
+    public boolean ready() throws java.io.IOException {
+        return reader.ready() || (line != null && length > 0);
+    }
+
+    public boolean markSupported() {
+        return false;
+    }
+
+    public void mark(int unused) throws java.io.IOException {
+        throw new UnsupportedOperationException("mark not supported");
+    }
+
+    public void reset() throws java.io.IOException {
+        reader.reset();
+        line = null;
+        index = 0;
+    }
+
+    public void close() throws java.io.IOException {
+        reader.close();
+        line = null;
+        index = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogCompilation.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.*;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ * The LogCompilation tool parses log files generated by HotSpot using the
+ * {@code -XX:+LogCompilation} command line flag, and outputs the data
+ * collected therein in a nicely formatted way. There are various sorting
+ * options available, as well as options that select specific compilation
+ * events (such as inlining decisions) for inclusion in the output.
+ *
+ * The tool is also capable of fixing broken compilation logs as sometimes
+ * generated by Java 1.5 JVMs.
+ */
+public class LogCompilation extends DefaultHandler implements ErrorHandler {
+
+    /**
+     * Print usage information and terminate with a given exit code.
+     */
+    public static void usage(int exitcode) {
+        System.out.println("Usage: LogCompilation [ -v ] [ -c ] [ -s ] [ -e | -n ] file1 ...");
+        System.out.println("By default, the tool will print the logged compilations ordered by start time.");
+        System.out.println("  -c:   clean up malformed 1.5 xml");
+        System.out.println("  -i:   print inlining decisions");
+        System.out.println("  -S:   print compilation statistics");
+        System.out.println("  -U:   print uncommon trap statistics");
+        System.out.println("  -t:   print with time stamps");
+        System.out.println("  -s:   sort events by start time (default)");
+        System.out.println("  -e:   sort events by elapsed time");
+        System.out.println("  -n:   sort events by name and start");
+        System.out.println("  -C:   compare logs (give files to compare on command line)");
+        System.out.println("  -d:   do not print compilation IDs");
+        System.exit(exitcode);
+    }
+
+    /**
+     * Process command line arguments, parse log files and trigger desired
+     * functionality.
+     */
+    public static void main(String[] args) throws Exception {
+        Comparator<LogEvent> sort = LogParser.sortByStart;
+        boolean statistics = false;
+        boolean printInlining = false;
+        boolean cleanup = false;
+        boolean trapHistory = false;
+        boolean printTimeStamps = false;
+        boolean compare = false;
+        boolean printID = true;
+        int index = 0;
+
+        while (args.length > index) {
+            String a = args[index];
+            if (a.equals("-e")) {
+                sort = LogParser.sortByElapsed;
+                index++;
+            } else if (a.equals("-n")) {
+                sort = LogParser.sortByNameAndStart;
+                index++;
+            } else if (a.equals("-s")) {
+                sort = LogParser.sortByStart;
+                index++;
+            } else if (a.equals("-t")) {
+                printTimeStamps = true;
+                index++;
+            } else if (a.equals("-c")) {
+                cleanup = true;
+                index++;
+            } else if (a.equals("-S")) {
+                statistics = true;
+                index++;
+            } else if (a.equals("-U")) {
+                trapHistory = true;
+                index++;
+            } else if (a.equals("-h")) {
+                usage(0);
+            } else if (a.equals("-i")) {
+                printInlining = true;
+                index++;
+            } else if (a.equals("-C")) {
+                compare = true;
+                index++;
+            } else if (a.equals("-d")) {
+                printID = false;
+                index++;
+            } else {
+                if (a.charAt(0) == '-') {
+                    System.out.println("Unknown option '" + a + "', assuming file name.");
+                }
+                break;
+            }
+        }
+
+        if (index >= args.length) {
+            usage(1);
+        }
+
+        if (compare) {
+            compareLogs(index, args);
+            return;
+        }
+
+        while (index < args.length) {
+            ArrayList<LogEvent> events = null;
+            try {
+                events = LogParser.parse(args[index], cleanup);
+            } catch (FileNotFoundException fnfe) {
+                System.out.println("File not found: " + args[index]);
+                System.exit(1);
+            }
+
+            Collections.sort(events, sort);
+
+            if (statistics) {
+                printStatistics(events, System.out);
+            } else if (trapHistory) {
+                printTrapHistory(events, System.out);
+            } else {
+                for (LogEvent c : events) {
+                    if (c instanceof NMethod) {
+                        // skip these
+                        continue;
+                    }
+                    if (printTimeStamps) {
+                        System.out.print(c.getStart() + ": ");
+                    }
+                    if (c instanceof Compilation) {
+                        Compilation comp = (Compilation) c;
+                        comp.print(System.out, printID, printInlining);
+                    } else {
+                        c.print(System.out, printID);
+                    }
+                }
+            }
+            index++;
+        }
+    }
+
+    /**
+     * Print extensive statistics from parsed log files.
+     */
+    public static void printStatistics(ArrayList<LogEvent> events, PrintStream out) {
+        // track code cache size
+        long cacheSize = 0;
+        long maxCacheSize = 0;
+        // track number of nmethods
+        int nmethodsCreated = 0;
+        int nmethodsLive = 0;
+        // track how many compilations were attempted multiple times
+        // (indexed by attempts, mapping to number of compilations)
+        int[] attempts = new int[32];
+        int maxattempts = 0;
+
+        // track time spent in compiler phases
+        LinkedHashMap<String, Double> phaseTime = new LinkedHashMap<>(7);
+        // track nodes created per phase
+        LinkedHashMap<String, Integer> phaseNodes = new LinkedHashMap<>(7);
+        double elapsed = 0;
+
+        for (LogEvent e : events) {
+            if (e instanceof Compilation) {
+                Compilation c = (Compilation) e;
+                c.printShort(out);
+                out.printf(" %6.4f\n", c.getElapsedTime());
+                attempts[c.getAttempts()]++;
+                maxattempts = Math.max(maxattempts,c.getAttempts());
+                elapsed += c.getElapsedTime();
+                for (Phase phase : c.getPhases()) {
+                    Double v = phaseTime.get(phase.getName());
+                    if (v == null) {
+                        v = Double.valueOf(0.0);
+                    }
+                    phaseTime.put(phase.getName(), Double.valueOf(v.doubleValue() + phase.getElapsedTime()));
+
+                    Integer v2 = phaseNodes.get(phase.getName());
+                    if (v2 == null) {
+                        v2 = Integer.valueOf(0);
+                    }
+                    phaseNodes.put(phase.getName(), Integer.valueOf(v2.intValue() + phase.getNodes()));
+                    // Print phase name, elapsed time, nodes at the start of
+                    // the phase, nodes created in the phase, live nodes at the
+                    // start of the phase, live nodes added in the phase.
+                    out.printf("\t%s %6.4f %d %d %d %d\n", phase.getName(), phase.getElapsedTime(), phase.getStartNodes(), phase.getNodes(), phase.getStartLiveNodes(), phase.getAddedLiveNodes());
+                }
+            } else if (e instanceof MakeNotEntrantEvent) {
+                MakeNotEntrantEvent mne = (MakeNotEntrantEvent) e;
+                NMethod nm = mne.getNMethod();
+                if (mne.isZombie()) {
+                    if (nm == null) {
+                        System.err.println("zombie make not entrant event without nmethod: " + mne.getId());
+                    }
+                    cacheSize -= nm.getSize();
+                    nmethodsLive--;
+                }
+            } else if (e instanceof NMethod) {
+                nmethodsLive++;
+                nmethodsCreated++;
+                NMethod nm = (NMethod) e;
+                cacheSize += nm.getSize();
+                maxCacheSize = Math.max(cacheSize, maxCacheSize);
+            }
+        }
+        out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n", nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize);
+        out.println("Phase times:");
+        for (String name : phaseTime.keySet()) {
+            Double v = phaseTime.get(name);
+            Integer v2 = phaseNodes.get(name);
+            out.printf("%20s %6.4f %d\n", name, v.doubleValue(), v2.intValue());
+        }
+        out.printf("%20s %6.4f\n", "total", elapsed);
+
+        if (maxattempts > 0) {
+            out.println("Distribution of regalloc passes:");
+            for (int i = 0; i <= maxattempts; i++) {
+                out.printf("%2d %8d\n", i, attempts[i]);
+            }
+        }
+    }
+
+    /**
+     * Container class for a pair of a method and a bytecode instruction index
+     * used by a compiler. This is used in
+     * {@linkplain #compareLogs() comparing logs}.
+     */
+    static class MethodBCIPair {
+        public MethodBCIPair(Method m, int b, String c) {
+            method = m;
+            bci = b;
+            compiler = c;
+        }
+
+        Method method;
+        int bci;
+        String compiler;
+
+        public boolean equals(Object other) {
+            if (!(other instanceof MethodBCIPair)) {
+                return false;
+            }
+            MethodBCIPair otherp = (MethodBCIPair)other;
+            return (otherp.bci == bci &&
+                    otherp.method.equals(method) &&
+                    otherp.compiler.equals(compiler));
+        }
+
+        public int hashCode() {
+            return method.hashCode() + bci;
+        }
+
+        public String toString() {
+            if (bci != -1) {
+                return method + "@" + bci + " (" + compiler + ")";
+            } else {
+                return method + " (" + compiler + ")";
+            }
+        }
+    }
+
+    /**
+     * Compare a number of compilation log files. Each of the logs is parsed,
+     * and all compilations found therein are written to a sorted file (prefix
+     * {@code sorted-}. A summary is written to a new file {@code summary.txt}.
+     *
+     * @param index the index in the command line arguments at which to start
+     *              looking for files to compare.
+     * @param args  the command line arguments with which {@link LogCompilation}
+     *              was originally invoked.
+     *
+     * @throws Exception in case any exceptions are thrown in the called
+     *         methods.
+     */
+    @SuppressWarnings("unchecked")
+    static void compareLogs(int index, String[] args) throws Exception {
+        HashMap<MethodBCIPair,MethodBCIPair> methods = new HashMap<>();
+        ArrayList<HashMap<MethodBCIPair,Object>> logs = new ArrayList<>();
+        PrintStream[] outs = new PrintStream[args.length - index];
+        PrintStream summary = new PrintStream(new FileOutputStream("summary.txt"));
+        int o = 0;
+        // Process all logs given on the command line: collect compilation
+        // data; in particular, method/bci pairs.
+        while (index < args.length) {
+            String basename = new File(args[index]).getName();
+            String outname = "sorted-" + basename;
+            System.out.println("Sorting " + basename + " to " + outname);
+            outs[o] = new PrintStream(new FileOutputStream(outname));
+            o++;
+            System.out.println("Parsing " + args[index]);
+            ArrayList<LogEvent> events = LogParser.parse(args[index], false);
+            HashMap<MethodBCIPair,Object> compiles = new HashMap<>();
+            logs.add(compiles);
+            for (LogEvent c : events) {
+                if (c instanceof Compilation) {
+                    Compilation comp = (Compilation) c;
+                    MethodBCIPair key = new MethodBCIPair(comp.getMethod(), comp.getBCI(),
+                                                          comp.getCompiler());
+                    MethodBCIPair e = methods.get(key);
+                    if (e == null) {
+                        methods.put(key, key);
+                    } else {
+                        key = e;
+                    }
+                    Object other = compiles.get(key);
+                    if (other == null) {
+                        compiles.put(key, comp);
+                    } else {
+                        if (!(other instanceof List)) {
+                            List<Object> l = new LinkedList<>();
+                            l.add(other);
+                            l.add(comp);
+                            compiles.put(key, l);
+                        } else {
+                            List<Object> l = (List<Object>) other;
+                            l.add(comp);
+                        }
+                    }
+                }
+            }
+            index++;
+        }
+
+        // Process the collected method/bci pairs and write the output.
+        for (MethodBCIPair pair : methods.keySet()) {
+            summary.print(pair + " ");
+            int base = -1;
+            String first = null;
+            boolean mismatch = false;
+            boolean different = false;
+            String[] output = new String[outs.length];
+            o = 0;
+            for (HashMap<MethodBCIPair,Object> set : logs) {
+                Object e = set.get(pair);
+                String thisone = null;
+                Compilation lastc = null;
+                int n;
+                if (e == null) {
+                    n = 0;
+                } else if (e instanceof Compilation) {
+                    n = 1;
+                    lastc = (Compilation) e;
+                } else {
+                    // Compare the last compilation that was done for this method
+                    n = ((List<Object>) e).size();
+                    lastc = (Compilation) ((List<Object>) e).get(n - 1);
+                }
+                if (lastc != null) {
+                    n = 1;
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    PrintStream ps = new PrintStream(baos);
+                    lastc.print(ps, false);
+                    ps.close();
+                    thisone = new String(baos.toByteArray());
+                }
+                if (base == -1) {
+                    base = n;
+                } else if (base != n) {
+                    mismatch = true;
+                }
+                output[o++] = thisone;
+                if (thisone != null) {
+                    if (first == null) {
+                        first = thisone;
+                    } else {
+                        if (!first.equals(thisone)) {
+                            different = true;
+                        }
+                    }
+                }
+                if (different) {
+                    summary.print(n + "d ");
+                } else {
+                    summary.print(n + " ");
+                }
+            }
+            if (mismatch) {
+                summary.print("mismatch");
+            }
+            summary.println();
+            if (different) {
+                for (int i = 0; i < outs.length; i++) {
+                    if (output[i] != null) {
+                        outs[i].println(output[i]);
+                    }
+                }
+            }
+        }
+        for (int i = 0; i < outs.length; i++) {
+            outs[i].close();
+        }
+        if (summary != System.out) {
+            summary.close();
+        }
+    }
+
+    /**
+     * Print the history of uncommon trap events.
+     */
+    public static void printTrapHistory(ArrayList<LogEvent> events, PrintStream out) {
+        // map method names to a list of log events
+        LinkedHashMap<String, ArrayList<LogEvent>> traps = new LinkedHashMap<>();
+        // map compilation IDs to compilations
+        HashMap<Integer, Compilation> comps = new HashMap<>();
+
+        // First, iterate over all logged events, collecting data about
+        // uncommon trap events.
+        for (LogEvent e : events) {
+            if (e instanceof NMethod) {
+                // skip these
+                continue;
+            }
+            if (e instanceof Compilation) {
+                Compilation c = (Compilation) e;
+                String name = c.getMethod().getFullName();
+                ArrayList<LogEvent> elist = traps.get(name);
+                if (elist != null && comps.get(c.getId()) == null) {
+                    comps.put(c.getId(), c);
+                    // If there were previous events for the method
+                    // then keep track of later compiles too.
+                    elist.add(c);
+                }
+                continue;
+            }
+            if (e instanceof BasicLogEvent) {
+                BasicLogEvent ble = (BasicLogEvent) e;
+                Compilation c = ble.getCompilation();
+                if (c == null) {
+                    if (!(ble instanceof NMethod)) {
+                        throw new InternalError("only nmethods should have a null compilation; here's a " + ble.getClass());
+                    }
+                    continue;
+                }
+                String name = c.getMethod().getFullName();
+                ArrayList<LogEvent> elist = traps.get(name);
+                if (elist == null) {
+                    elist = new ArrayList<LogEvent>();
+                    traps.put(name, elist);
+                }
+                int bleId = Integer.parseInt(ble.getId());
+                if (comps.get(bleId) == null) {
+                    comps.put(bleId, c);
+                    // Add the associated compile to the list.  It
+                    // will likely go at the end but we need to search
+                    // backwards for the proper insertion point.
+                    double start = c.getStart();
+                    int ipoint = 0;
+                    while (ipoint < elist.size() && elist.get(ipoint).getStart() < start) {
+                        ipoint++;
+                    }
+                    if (ipoint == elist.size()) {
+                        elist.add(c);
+                    } else {
+                        elist.add(ipoint, c);
+                    }
+                }
+                elist.add(ble);
+            }
+        }
+
+        // Second, iterate over collected traps and output information.
+        for (String c: traps.keySet()) {
+            ArrayList<LogEvent> elist = traps.get(c);
+            String name = ((Compilation) elist.get(0)).getMethod().getFullName();
+            System.out.println(name);
+            double start = 0;
+            for (LogEvent e: elist) {
+                if (start > e.getStart() && e.getStart() != 0) {
+                    throw new InternalError("wrong sorting order for traps");
+                }
+                start = e.getStart();
+                out.print(e.getStart() + ": ");
+                if (e instanceof Compilation) {
+                    ((Compilation) e).print(out, true, true, true);
+                } else {
+                    e.print(out, true);
+                }
+            }
+            out.println();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogEvent.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * The interface of an event from a HotSpot compilation log. Events can have a
+ * duration, e.g., a compiler {@link Phase} is an event, and so is an entire
+ * {@link Compilation}.
+ */
+public interface LogEvent {
+
+    /**
+     * The event's start time.
+     */
+    public double getStart();
+
+    /**
+     * The event's duration in milliseconds.
+     */
+    public double getElapsedTime();
+
+    /**
+     * The compilation during which this event was signalled.
+     */
+    public Compilation getCompilation();
+
+    /**
+     * Print the event to the given stream.
+     */
+    public void print(PrintStream stream, boolean printID);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogParser.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,1302 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ *
+ */
+
+/**
+ * A SAX based parser of LogCompilation output from HotSpot.  It takes a complete
+ */
+
+package com.sun.hotspot.tools.compiler;
+
+import java.io.FileReader;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A SAX parser for HotSpot compilation logs. The bulk of the parsing and event
+ * maintenance work is done in the {@link #startElement(String,String,String,Attributes)}
+ * and {@link #endElement(String,String,String)} methods.
+ */
+public class LogParser extends DefaultHandler implements ErrorHandler {
+
+    static final Pattern spacePattern = Pattern.compile(" ");
+
+    /**
+     * Map internal array type descriptors to Java names.
+     */
+    static final HashMap<String, String> type2printableMap;
+
+    /**
+     * Map Java primitive type names to internal type descriptors.
+     */
+    static final HashMap<String, String> type2vmtypeMap;
+
+    static {
+        type2printableMap = new HashMap<>();
+        type2printableMap.put("[I", "int[]");
+        type2printableMap.put("[C", "char[]");
+        type2printableMap.put("[Z", "boolean[]");
+        type2printableMap.put("[L", "Object[]");
+        type2printableMap.put("[B", "byte[]");
+
+        type2vmtypeMap = new HashMap<>();
+        type2vmtypeMap.put("void", "V");
+        type2vmtypeMap.put("boolean", "Z");
+        type2vmtypeMap.put("byte", "B");
+        type2vmtypeMap.put("char", "C");
+        type2vmtypeMap.put("short", "S");
+        type2vmtypeMap.put("int", "I");
+        type2vmtypeMap.put("long", "J");
+        type2vmtypeMap.put("float", "F");
+        type2vmtypeMap.put("double", "D");
+    }
+
+    static String[] bytecodes = new String[] {
+        "nop",
+        "aconst_null",
+        "iconst_m1",
+        "iconst_0",
+        "iconst_1",
+        "iconst_2",
+        "iconst_3",
+        "iconst_4",
+        "iconst_5",
+        "lconst_0",
+        "lconst_1",
+        "fconst_0",
+        "fconst_1",
+        "fconst_2",
+        "dconst_0",
+        "dconst_1",
+        "bipush",
+        "sipush",
+        "ldc",
+        "ldc_w",
+        "ldc2_w",
+        "iload",
+        "lload",
+        "fload",
+        "dload",
+        "aload",
+        "iload_0",
+        "iload_1",
+        "iload_2",
+        "iload_3",
+        "lload_0",
+        "lload_1",
+        "lload_2",
+        "lload_3",
+        "fload_0",
+        "fload_1",
+        "fload_2",
+        "fload_3",
+        "dload_0",
+        "dload_1",
+        "dload_2",
+        "dload_3",
+        "aload_0",
+        "aload_1",
+        "aload_2",
+        "aload_3",
+        "iaload",
+        "laload",
+        "faload",
+        "daload",
+        "aaload",
+        "baload",
+        "caload",
+        "saload",
+        "istore",
+        "lstore",
+        "fstore",
+        "dstore",
+        "astore",
+        "istore_0",
+        "istore_1",
+        "istore_2",
+        "istore_3",
+        "lstore_0",
+        "lstore_1",
+        "lstore_2",
+        "lstore_3",
+        "fstore_0",
+        "fstore_1",
+        "fstore_2",
+        "fstore_3",
+        "dstore_0",
+        "dstore_1",
+        "dstore_2",
+        "dstore_3",
+        "astore_0",
+        "astore_1",
+        "astore_2",
+        "astore_3",
+        "iastore",
+        "lastore",
+        "fastore",
+        "dastore",
+        "aastore",
+        "bastore",
+        "castore",
+        "sastore",
+        "pop",
+        "pop2",
+        "dup",
+        "dup_x1",
+        "dup_x2",
+        "dup2",
+        "dup2_x1",
+        "dup2_x2",
+        "swap",
+        "iadd",
+        "ladd",
+        "fadd",
+        "dadd",
+        "isub",
+        "lsub",
+        "fsub",
+        "dsub",
+        "imul",
+        "lmul",
+        "fmul",
+        "dmul",
+        "idiv",
+        "ldiv",
+        "fdiv",
+        "ddiv",
+        "irem",
+        "lrem",
+        "frem",
+        "drem",
+        "ineg",
+        "lneg",
+        "fneg",
+        "dneg",
+        "ishl",
+        "lshl",
+        "ishr",
+        "lshr",
+        "iushr",
+        "lushr",
+        "iand",
+        "land",
+        "ior",
+        "lor",
+        "ixor",
+        "lxor",
+        "iinc",
+        "i2l",
+        "i2f",
+        "i2d",
+        "l2i",
+        "l2f",
+        "l2d",
+        "f2i",
+        "f2l",
+        "f2d",
+        "d2i",
+        "d2l",
+        "d2f",
+        "i2b",
+        "i2c",
+        "i2s",
+        "lcmp",
+        "fcmpl",
+        "fcmpg",
+        "dcmpl",
+        "dcmpg",
+        "ifeq",
+        "ifne",
+        "iflt",
+        "ifge",
+        "ifgt",
+        "ifle",
+        "if_icmpeq",
+        "if_icmpne",
+        "if_icmplt",
+        "if_icmpge",
+        "if_icmpgt",
+        "if_icmple",
+        "if_acmpeq",
+        "if_acmpne",
+        "goto",
+        "jsr",
+        "ret",
+        "tableswitch",
+        "lookupswitch",
+        "ireturn",
+        "lreturn",
+        "freturn",
+        "dreturn",
+        "areturn",
+        "return",
+        "getstatic",
+        "putstatic",
+        "getfield",
+        "putfield",
+        "invokevirtual",
+        "invokespecial",
+        "invokestatic",
+        "invokeinterface",
+        "invokedynamic",
+        "new",
+        "newarray",
+        "anewarray",
+        "arraylength",
+        "athrow",
+        "checkcast",
+        "instanceof",
+        "monitorenter",
+        "monitorexit",
+        "wide",
+        "multianewarray",
+        "ifnull",
+        "ifnonnull",
+        "goto_w",
+        "jsr_w",
+        "breakpoint"
+    };
+
+    /**
+     * Sort log events by start time.
+     */
+    static Comparator<LogEvent> sortByStart = new Comparator<LogEvent>() {
+
+        public int compare(LogEvent a, LogEvent b) {
+            double difference = (a.getStart() - b.getStart());
+            if (difference < 0) {
+                return -1;
+            }
+            if (difference > 0) {
+                return 1;
+            }
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return 7;
+        }
+    };
+
+    /**
+     * Sort log events first by the name of the compiled method, then by start
+     * time. In case one of the events has no associated compilation (or the
+     * associated compilation has no method name), the event with a compilation
+     * and/or name is considered the larger one.
+     */
+    static Comparator<LogEvent> sortByNameAndStart = new Comparator<LogEvent>() {
+
+        public int compare(LogEvent a, LogEvent b) {
+            Compilation c1 = a.getCompilation();
+            Compilation c2 = b.getCompilation();
+            if (c1 != null && c1.getMethod() != null && c2 != null && c2.getMethod() != null) {
+                int result = c1.getMethod().toString().compareTo(c2.getMethod().toString());
+                if (result != 0) {
+                    return result;
+                }
+            } else if ((c1 == null || c1.getMethod() == null) && c2 != null && c2.getMethod() != null) {
+                return -1;
+            } else if ((c2 == null || c2.getMethod() == null) && c1 != null && c1.getMethod() != null) {
+                return 1;
+            }
+            return Double.compare(a.getStart(), b.getStart());
+        }
+
+        public boolean equals(Object other) {
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return 7;
+        }
+    };
+
+    /**
+     * Sort log events by duration.
+     */
+    static Comparator<LogEvent> sortByElapsed = new Comparator<LogEvent>() {
+
+        public int compare(LogEvent a, LogEvent b) {
+            double difference = (a.getElapsedTime() - b.getElapsedTime());
+            if (difference < 0) {
+                return -1;
+            }
+            if (difference > 0) {
+                return 1;
+            }
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return 7;
+        }
+    };
+
+    /**
+     * Shrink-wrapped representation of a JVMState (tailored to meet this
+     * tool's needs). It only records a method and bytecode instruction index.
+     */
+    class Jvms {
+        Jvms(Method method, int bci) {
+            this.method = method;
+            this.bci = bci;
+        }
+        final public Method method;
+        final public int bci;
+        final public String toString() {
+            return "@" + bci + " " + method;
+        }
+    }
+
+    /**
+     * Representation of a lock elimination. Locks, corresponding to
+     * synchronized blocks and method calls, may be eliminated if the object in
+     * question is guaranteed to be used thread-locally.
+     */
+    class LockElimination extends BasicLogEvent {
+
+        /**
+         * Track all locations from which this lock was eliminated.
+         */
+        ArrayList<Jvms> jvms = new ArrayList<>(1);
+
+        /**
+         * The kind of lock (coarsened, nested, non-escaping, unknown).
+         */
+        final String kind;
+
+        /**
+         * The lock class (unlock, lock, unknown).
+         */
+        final String classId;
+
+        /**
+         * The precise type of lock.
+         */
+        final String tagName;
+
+        LockElimination(String tagName, double start, String id, String kind, String classId) {
+            super(start, id);
+            this.kind = kind;
+            this.classId = classId;
+            this.tagName = tagName;
+        }
+
+        @Override
+        public void print(PrintStream stream, boolean printID) {
+            if (printID) {
+                stream.printf("%s ", getId());
+            }
+            stream.printf("%s %s %s  %.3f ", tagName, kind, classId, getStart());
+            stream.print(jvms.toString());
+            stream.print("\n");
+        }
+
+        void addJVMS(Method method, int bci) {
+            jvms.add(new Jvms(method, bci));
+        }
+
+    }
+
+    /**
+     * A list of log events. This is populated with the events found in the
+     * compilation log file during parsing.
+     */
+    private ArrayList<LogEvent> events = new ArrayList<>();
+
+    /**
+     * Map compilation log IDs to type names.
+     */
+    private HashMap<String, String> types = new HashMap<>();
+
+    /**
+     * Map compilation log IDs to methods.
+     */
+    private HashMap<String, Method> methods = new HashMap<>();
+
+    /**
+     * Map compilation IDs ({@see #makeId()}) to newly created nmethods.
+     */
+    private LinkedHashMap<String, NMethod> nmethods = new LinkedHashMap<>();
+
+    /**
+     * Map compilation task IDs {@see #makeId()}) to {@link Compilation}
+     * objects.
+     */
+    private HashMap<String, Compilation> compiles = new HashMap<>();
+
+    /**
+     * Track compilation failure reasons.
+     */
+    private String failureReason;
+
+    /**
+     * The current bytecode instruction index.
+     */
+    private int current_bci;
+
+    /**
+     * The current bytecode instruction.
+     */
+    private int current_bytecode;
+
+    /**
+     * A sequence of {@link CallSite}s representing a call stack. A scope
+     * typically holds several {@link CallSite}s that represent calls
+     * originating from that scope.
+     *
+     * New scopes are typically pushed when parse log events are encountered
+     * ({@see #startElement()}) and popped when parsing of a given Java method
+     * is done ({@see #endElement()}). Parsing events can be nested. Several
+     * other events add information to scopes ({@see #startElement()}).
+     */
+    private Deque<CallSite> scopes = new ArrayDeque<>();
+
+    /**
+     * The current compilation.
+     */
+    private Compilation compile;
+
+    /**
+     * The {@linkplain CallSite compilation scope} currently in focus.
+     */
+    private CallSite site;
+
+    /**
+     * The {@linkplain CallSite method handle call site} currently under
+     * observation.
+     */
+    private CallSite methodHandleSite;
+
+    /**
+     * Keep track of potentially nested compiler {@linkplain Phase phases}.
+     */
+    private Deque<Phase> phaseStack = new ArrayDeque<>();
+
+    /**
+     * The {@linkplain LockElimination lock elimination event} currently being
+     * processed.
+     */
+    private LockElimination currentLockElimination;
+
+    /**
+     * The {@linkplain UncommonTrapEvent uncommon trap event} currently being
+     * processed.
+     */
+    private UncommonTrapEvent currentTrap;
+
+    /**
+     * During the processing of a late inline event, this stack holds the
+     * {@link CallSite}s that represent the inlining event's call stack.
+     */
+    private Deque<CallSite> lateInlineScope;
+
+    /**
+     * Denote whether a late inlining event is currently being processed.
+     */
+    private boolean lateInlining;
+
+    /**
+     * A document locator to provide better error messages: this allows the
+     * tool to display in which line of the log file the problem occurred.
+     */
+    private Locator locator;
+
+    /**
+     * Callback for the SAX framework to set the document locator.
+     */
+    @Override
+    public void setDocumentLocator(Locator locator) {
+        this.locator = locator;
+    }
+
+    /**
+     * Report an internal error explicitly raised, i.e., not derived from an
+     * exception.
+     *
+     * @param msg The error message to report.
+     */
+    private void reportInternalError(String msg) {
+        reportInternalError(msg, null);
+    }
+
+    /**
+     * Report an internal error derived from an exception.
+     *
+     * @param msg The beginning of the error message to report. The message
+     * from the exception will be appended to this.
+     * @param e The exception that led to the internal error.
+     */
+    private void reportInternalError(String msg, Exception e) {
+        if (locator != null) {
+            msg += " at " + locator.getLineNumber() + ":" + locator.getColumnNumber();
+            if (e != null) {
+                msg += " - " + e.getMessage();
+            }
+        }
+        if (e != null) {
+            throw new Error(msg, e);
+        } else {
+            throw new Error(msg);
+        }
+    }
+
+    /**
+     * Parse a long hexadecimal address into a {@code long} value. As Java only
+     * supports positive {@code long} values, extra error handling and parsing
+     * logic is provided.
+     */
+    long parseLong(String l) {
+        try {
+            return Long.decode(l).longValue();
+        } catch (NumberFormatException nfe) {
+            int split = l.length() - 8;
+            String s1 = "0x" + l.substring(split);
+            String s2 = l.substring(0, split);
+            long v1 = Long.decode(s1).longValue() & 0xffffffffL;
+            long v2 = (Long.decode(s2).longValue() & 0xffffffffL) << 32;
+            if (!l.equals("0x" + Long.toHexString(v1 + v2))) {
+                System.out.println(l);
+                System.out.println(s1);
+                System.out.println(s2);
+                System.out.println(v1);
+                System.out.println(v2);
+                System.out.println(Long.toHexString(v1 + v2));
+                reportInternalError("bad conversion");
+            }
+            return v1 + v2;
+        }
+    }
+
+    /**
+     * Entry point for log file parsing with a file name.
+     *
+     * @param file The name of the log file to parse.
+     * @param cleanup Whether to perform bad XML cleanup during parsing (this
+     * is relevant for some log files generated by the 1.5 JVM).
+     * @return a list of {@link LogEvent} instances describing the events found
+     * in the log file.
+     */
+    public static ArrayList<LogEvent> parse(String file, boolean cleanup) throws Exception {
+        return parse(new FileReader(file), cleanup);
+    }
+
+    /**
+     * Entry point for log file parsing with a file reader.
+     * {@link #parse(String,boolean)}
+     */
+    public static ArrayList<LogEvent> parse(Reader reader, boolean cleanup) throws Exception {
+        // Create the XML input factory
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+
+        // Create the XML LogEvent reader
+        SAXParser p = factory.newSAXParser();
+
+        if (cleanup) {
+            // some versions of the log have slightly malformed XML, so clean it
+            // up before passing it to SAX
+            reader = new LogCleanupReader(reader);
+        }
+
+        LogParser log = new LogParser();
+        try {
+            p.parse(new InputSource(reader), log);
+        } catch (Throwable th) {
+            th.printStackTrace();
+            // Carry on with what we've got...
+        }
+
+        // Associate compilations with their NMethods and other kinds of events
+        for (LogEvent e : log.events) {
+            if (e instanceof BasicLogEvent) {
+                BasicLogEvent ble = (BasicLogEvent) e;
+                Compilation c = log.compiles.get(ble.getId());
+                if (c == null) {
+                    if (!(ble instanceof NMethod)) {
+                        throw new InternalError("only nmethods should have a null compilation, here's a " + ble.getClass());
+                    }
+                    continue;
+                }
+                ble.setCompilation(c);
+                if (ble instanceof NMethod) {
+                    c.setNMethod((NMethod) ble);
+                }
+            }
+        }
+
+        return log.events;
+    }
+
+    /**
+     * Retrieve a given attribute's value from a collection of XML tag
+     * attributes. Report an error if the requested attribute is not found.
+     *
+     * @param attr A collection of XML tag attributes.
+     * @param name The name of the attribute the value of which is to be found.
+     * @return The value of the requested attribute, or {@code null} if it was
+     * not found.
+     */
+    String search(Attributes attr, String name) {
+        String result = attr.getValue(name);
+        if (result != null) {
+            return result;
+        } else {
+            reportInternalError("can't find " + name);
+            return null;
+        }
+    }
+
+    /**
+     * Retrieve a given attribute's value from a collection of XML tag
+     * attributes. Return a default value if the requested attribute is not
+     * found.
+     *
+     * @param attr A collection of XML tag attributes.
+     * @param name The name of the attribute the value of which is to be found.
+     * @param defaultValue The default value to return if the attribute is not
+     * found.
+     * @return The value of the requested attribute, or the default value if it
+     * was not found.
+     */
+    String search(Attributes attr, String name, String defaultValue) {
+        String result = attr.getValue(name);
+        if (result != null) {
+            return result;
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Map a type ID from the compilation log to an actual type name. In case
+     * the type represents an internal array type descriptor, return a
+     * Java-level name. If the type ID cannot be mapped to a name, raise an
+     * error.
+     */
+    String type(String id) {
+        String result = types.get(id);
+        if (result == null) {
+            reportInternalError(id);
+        }
+        String remapped = type2printableMap.get(result);
+        if (remapped != null) {
+            return remapped;
+        }
+        return result;
+    }
+
+    /**
+     * Register a mapping from log file type ID to type name.
+     */
+    void type(String id, String name) {
+        assert type(id) == null;
+        types.put(id, name);
+    }
+
+    /**
+     * Map a log file type ID to an internal type declarator.
+     */
+    String sigtype(String id) {
+        String result = types.get(id);
+        String remapped = type2vmtypeMap.get(result);
+        if (remapped != null) {
+            return remapped;
+        }
+        if (result == null) {
+            reportInternalError(id);
+        }
+        if (result.charAt(0) == '[') {
+            return result;
+        }
+        return "L" + result + ";";
+    }
+
+    /**
+     * Retrieve a method based on the log file ID it was registered under.
+     * Raise an error if the ID does not map to a method.
+     */
+    Method method(String id) {
+        Method result = methods.get(id);
+        if (result == null) {
+            reportInternalError(id);
+        }
+        return result;
+    }
+
+    /**
+     * From a compilation ID and kind, assemble a compilation ID for inclusion
+     * in the output.
+     *
+     * @param atts A collection of XML attributes from which the required
+     * attributes are retrieved.
+     */
+    public String makeId(Attributes atts) {
+        String id = atts.getValue("compile_id");
+        String kind = atts.getValue("kind");
+        if (kind != null && kind.equals("osr")) {
+            id += "%";
+        }
+        return id;
+    }
+
+    /**
+     * Process the start of a compilation log XML element.<ul>
+     * <li><b>phase:</b> record the beginning of a compilation phase, pushing
+     * it on the {@linkplain #phaseStack phase stack} and collecting
+     * information about the compiler graph.</li>
+     * <li><b>phase_done:</b> record the end of a compilation phase, popping it
+     * off the {@linkplain #phaseStack phase stack} and collecting information
+     * about the compiler graph (number of nodes and live nodes).</li>
+     * <li><b>task:</b> register the start of a new compilation.</li>
+     * <li><b>type:</b> register a type.</li>
+     * <li><b>bc:</b> note the current bytecode index and instruction name,
+     * updating {@link #current_bci} and {@link #current_bytecode}.</li>
+     * <li><b>klass:</b> register a type (class).</li>
+     * <li><b>method:</b> register a Java method.</li>
+     * <li><b>call:</b> process a call, populating {@link #site} with the
+     * appropriate data.</li>
+     * <li><b>regalloc:</b> record the register allocator's trip count in the
+     * {@linkplain #compile current compilation}.</li>
+     * <li><b>inline_fail:</b> record the reason for a failed inline
+     * operation.</li>
+     * <li><b>inline_success:</b> record a successful inlining operation,
+     * noting the success reason in the {@linkplain #site call site}.</li>
+     * <li><b>failure:</b> note a compilation failure, storing the reason
+     * description in {@link #failureReason}.</li>
+     * <li><b>task_done:</b> register the end of a compilation, recording time
+     * stamp and success information.</li>
+     * <li><b>make_not_entrant:</b> deal with making a native method
+     * non-callable (e.g., during an OSR compilation, if there are still
+     * activations) or a zombie (when the method can be deleted).</li>
+     * <li><b>uncommon_trap:</b> process an uncommon trap, setting the
+     * {@link #currentTrap} field.</li>
+     * <li><b>eliminate_lock:</b> record the start of a lock elimination,
+     * setting the {@link #currentLockElimination} event.</li>
+     * <li><b>late_inline:</b> start processing a late inline decision:
+     * initialize the {@linkplain #lateInlineScope inline scope stack}, create
+     * an {@linkplain #site initial scope} with a bogus bytecode index and the
+     * right inline ID, and push the scope with the inline ID attached. Note
+     * that most of late inlining processing happens in
+     * {@link #endElement(String,String,String)}.</li>
+     * <li><b>jvms:</b> record a {@linkplain Jvms JVMState}. Depending on the
+     * context in which this event is encountered, this can mean adding
+     * information to the currently being processed trap, lock elimination, or
+     * inlining operation.</li>
+     * <li><b>inline_id:</b> set the inline ID in the
+     * {@linkplain #site current call site}.</li>
+     * <li><b>nmethod:</b> record the creation of a new {@link NMethod} and
+     * store it in the {@link #nmethods} map.</li>
+     * <li><b>parse:</b> begin parsing a Java method's bytecode and
+     * transforming it into an initial compiler IR graph.</li>
+     * <li><b>parse_done:</b> finish parsing a Java method's bytecode.</li>
+     * </ul>
+     */
+    @Override
+    public void startElement(String uri, String localName, String qname, Attributes atts) {
+        if (qname.equals("phase")) {
+            Phase p = new Phase(search(atts, "name"),
+                    Double.parseDouble(search(atts, "stamp")),
+                    Integer.parseInt(search(atts, "nodes", "0")),
+                    Integer.parseInt(search(atts, "live", "0")));
+            phaseStack.push(p);
+        } else if (qname.equals("phase_done")) {
+            Phase p = phaseStack.pop();
+            String phaseName = search(atts, "name", null);
+            if (phaseName != null && !p.getId().equals(phaseName)) {
+                System.out.println("phase: " + p.getId());
+                reportInternalError("phase name mismatch");
+            }
+            p.setEnd(Double.parseDouble(search(atts, "stamp")));
+            p.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
+            p.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
+            compile.getPhases().add(p);
+        } else if (qname.equals("task")) {
+            String id = makeId(atts);
+
+            // Create the new Compilation instance and populate it with readily
+            // available data.
+            compile = new Compilation(Integer.parseInt(search(atts, "compile_id", "-1")));
+            compile.setStart(Double.parseDouble(search(atts, "stamp")));
+            compile.setICount(search(atts, "count", "0"));
+            compile.setBCount(search(atts, "backedge_count", "0"));
+            compile.setBCI(Integer.parseInt(search(atts, "osr_bci", "-1")));
+            String compiler = atts.getValue("compiler");
+            if (compiler == null) {
+                compiler = "";
+            }
+            compile.setCompiler(compiler);
+
+            // Extract the name of the compiled method.
+            String[] parts = spacePattern.split(atts.getValue("method"));
+            String methodName = parts[0] + "::" + parts[1];
+
+            // Continue collecting compilation meta-data.
+            String kind = atts.getValue("compile_kind");
+            if (kind == null) {
+                kind = "normal";
+            }
+            if (kind.equals("osr")) {
+                compile.setOsr(true);
+            } else if (kind.equals("c2i")) {
+                compile.setSpecial("--- adapter " + methodName);
+            } else {
+                compile.setSpecial(compile.getId() + " " + methodName + " (0 bytes)");
+            }
+
+            // Build a dummy method to stuff in the Compilation at the
+            // beginning.
+            Method m = new Method();
+            m.setHolder(parts[0]);
+            m.setName(parts[1]);
+            m.setSignature(parts[2]);
+            m.setFlags("0");
+            m.setBytes(search(atts, "bytes", "unknown"));
+            compile.setMethod(m);
+            events.add(compile);
+            compiles.put(id, compile);
+            site = compile.getCall();
+        } else if (qname.equals("type")) {
+            type(search(atts, "id"), search(atts, "name"));
+        } else if (qname.equals("bc")) {
+            current_bci = Integer.parseInt(search(atts, "bci"));
+            current_bytecode = Integer.parseInt(search(atts, "code"));
+        } else if (qname.equals("klass")) {
+            type(search(atts, "id"), search(atts, "name"));
+        } else if (qname.equals("method")) {
+            String id = search(atts, "id");
+            Method m = new Method();
+            m.setHolder(type(search(atts, "holder")));
+            m.setName(search(atts, "name"));
+            m.setReturnType(type(search(atts, "return")));
+            String arguments = atts.getValue("arguments");;
+            if (arguments == null) {
+                m.setSignature("()" + sigtype(atts.getValue("return")));
+            } else {
+                String[] args = spacePattern.split(arguments);
+                StringBuilder sb = new StringBuilder("(");
+                for (int i = 0; i < args.length; i++) {
+                    sb.append(sigtype(args[i]));
+                }
+                sb.append(")");
+                sb.append(sigtype(atts.getValue("return")));
+                m.setSignature(sb.toString());
+            }
+
+            if (search(atts, "unloaded", "0").equals("0")) {
+               m.setBytes(search(atts, "bytes"));
+               m.setIICount(search(atts, "iicount"));
+               m.setFlags(search(atts, "flags"));
+            }
+            methods.put(id, m);
+        } else if (qname.equals("call")) {
+            if (methodHandleSite != null) {
+                methodHandleSite = null;
+            }
+            Method m = method(search(atts, "method"));
+            if (lateInlining && scopes.size() == 0) {
+                // re-attempting already seen call site (late inlining for MH invokes)
+                if (m != site.getMethod()) {
+                    if (current_bci != site.getBci()) {
+                        System.err.println(m + " bci: " + current_bci);
+                        System.err.println(site.getMethod() +  " bci: " + site.getBci());
+                        reportInternalError("bci mismatch after late inlining");
+                    }
+                    site.setMethod(m);
+                }
+            } else {
+                // We're dealing with a new call site; the called method is
+                // likely to be parsed next.
+                site = new CallSite(current_bci, m);
+            }
+            site.setCount(Integer.parseInt(search(atts, "count", "0")));
+            String receiver = atts.getValue("receiver");
+            if (receiver != null) {
+                site.setReceiver(type(receiver));
+                site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count")));
+            }
+            int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0"));
+            if (lateInlining && scopes.size() == 0) {
+                // The call was already added before this round of late
+                // inlining. Ignore.
+            } else if (methodHandle == 0) {
+                scopes.peek().add(site);
+            } else {
+                // method handle call site can be followed by another
+                // call (in case it is inlined). If that happens we
+                // discard the method handle call site. So we keep
+                // track of it but don't add it to the list yet.
+                methodHandleSite = site;
+            }
+        } else if (qname.equals("regalloc")) {
+            compile.setAttempts(Integer.parseInt(search(atts, "attempts")));
+        } else if (qname.equals("inline_fail")) {
+            if (methodHandleSite != null) {
+                scopes.peek().add(methodHandleSite);
+                methodHandleSite = null;
+            }
+            if (lateInlining && scopes.size() == 0) {
+                site.setReason("fail: " + search(atts, "reason"));
+                lateInlining = false;
+            } else {
+                scopes.peek().last().setReason("fail: " + search(atts, "reason"));
+            }
+        } else if (qname.equals("inline_success")) {
+            if (methodHandleSite != null) {
+                reportInternalError("method handle site should have been replaced");
+            }
+            site.setReason("succeed: " + search(atts, "reason"));
+        } else if (qname.equals("failure")) {
+            failureReason = search(atts, "reason");
+        } else if (qname.equals("task_done")) {
+            compile.setEnd(Double.parseDouble(search(atts, "stamp")));
+            if (Integer.parseInt(search(atts, "success")) == 0) {
+                compile.setFailureReason(failureReason);
+                failureReason = null;
+            }
+        } else if (qname.equals("make_not_entrant")) {
+            String id = makeId(atts);
+            NMethod nm = nmethods.get(id);
+            if (nm == null) reportInternalError("nm == null");
+            LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, "stamp")), id,
+                                                 atts.getValue("zombie") != null, nm);
+            events.add(e);
+        } else if (qname.equals("uncommon_trap")) {
+            String id = atts.getValue("compile_id");
+            if (id != null) {
+                id = makeId(atts);
+                currentTrap = new UncommonTrapEvent(Double.parseDouble(search(atts, "stamp")),
+                        id,
+                        atts.getValue("reason"),
+                        atts.getValue("action"),
+                        Integer.parseInt(search(atts, "count", "0")));
+                events.add(currentTrap);
+            } else {
+                if (atts.getValue("method") != null) {
+                    // These are messages from ciTypeFlow that don't
+                    // actually correspond to generated code.
+                    return;
+                }
+                try {
+                    UncommonTrap unc = new UncommonTrap(Integer.parseInt(search(atts, "bci")),
+                            search(atts, "reason"),
+                            search(atts, "action"),
+                            bytecodes[current_bytecode]);
+                    if (scopes.size() == 0) {
+                        // There may be a dangling site not yet in scopes after a late_inline
+                        if (site != null) {
+                            site.add(unc);
+                        } else {
+                            reportInternalError("scope underflow");
+                        }
+                    } else {
+                        scopes.peek().add(unc);
+                    }
+                } catch (Error e) {
+                    e.printStackTrace();
+                }
+            }
+        } else if (qname.startsWith("eliminate_lock")) {
+            String id = atts.getValue("compile_id");
+            if (id != null) {
+                id = makeId(atts);
+                String kind = atts.getValue("kind");
+                String classId = atts.getValue("class_id");
+                currentLockElimination = new LockElimination(qname, Double.parseDouble(search(atts, "stamp")), id, kind, classId);
+                events.add(currentLockElimination);
+            }
+        } else if (qname.equals("late_inline")) {
+            long inlineId = 0;
+            try {
+                inlineId = Long.parseLong(search(atts, "inline_id"));
+            } catch (InternalError ex) {
+                // Log files from older hotspots may lack inline_id,
+                // and zero is an acceptable substitute that allows processing to continue.
+            }
+            lateInlineScope = new ArrayDeque<>();
+            Method m = method(search(atts, "method"));
+            site = new CallSite(-999, m);
+            site.setInlineId(inlineId);
+            lateInlineScope.push(site);
+        } else if (qname.equals("jvms")) {
+            // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
+            if (currentTrap != null) {
+                String[] parts = spacePattern.split(atts.getValue("method"));
+                currentTrap.addMethodAndBCI(parts[0].replace('/', '.') + '.' + parts[1] + parts[2], Integer.parseInt(atts.getValue("bci")));
+            } else if (currentLockElimination != null) {
+                  currentLockElimination.addJVMS(method(atts.getValue("method")), Integer.parseInt(atts.getValue("bci")));
+            } else if (lateInlineScope != null) {
+                current_bci = Integer.parseInt(search(atts, "bci"));
+                Method m = method(search(atts, "method"));
+                site = new CallSite(current_bci, m);
+                lateInlineScope.push(site);
+            } else {
+                // Ignore <eliminate_allocation type='667'>,
+                //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
+            }
+        } else if (qname.equals("inline_id")) {
+            if (methodHandleSite != null) {
+                reportInternalError("method handle site should have been replaced");
+            }
+            long id = Long.parseLong(search(atts, "id"));
+            site.setInlineId(id);
+        } else if (qname.equals("nmethod")) {
+            String id = makeId(atts);
+            NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")),
+                    id,
+                    parseLong(atts.getValue("address")),
+                    parseLong(atts.getValue("size")));
+            nmethods.put(id, nm);
+            events.add(nm);
+        } else if (qname.equals("parse")) {
+            if (failureReason != null && scopes.size() == 0 && !lateInlining) {
+                // A compilation just failed, and we're back at a top
+                // compilation scope.
+                failureReason = null;
+                compile.reset();
+                site = compile.getCall();
+            }
+
+            // Error checking.
+            if (methodHandleSite != null) {
+                reportInternalError("method handle site should have been replaced");
+            }
+            Method m = method(search(atts, "method")); // this is the method being parsed
+            if (lateInlining && scopes.size() == 0) {
+                if (site.getMethod() != m) {
+                    reportInternalError("Unexpected method mismatch during late inlining (method at call site: " +
+                        site.getMethod() + ", method being parsed: " + m + ")");
+                }
+            }
+
+            if (scopes.size() == 0 && !lateInlining) {
+                // The method being parsed is actually the method being
+                // compiled; i.e., we're dealing with a compilation top scope,
+                // which we must consequently push to the scopes stack.
+                compile.setMethod(m);
+                scopes.push(site);
+            } else {
+                // The method being parsed is *not* the current compilation's
+                // top scope; i.e., we're dealing with an actual call site
+                // in the top scope or somewhere further down a call stack.
+                if (site.getMethod() == m) {
+                    // We're dealing with monomorphic inlining that didn't have
+                    // to be narrowed down, because the receiver was known
+                    // beforehand.
+                    scopes.push(site);
+                } else if (scopes.peek().getCalls().size() > 2 && m == scopes.peek().lastButOne().getMethod()) {
+                    // We're dealing with an at least bimorphic call site, and
+                    // the compiler has now decided to parse the last-but-one
+                    // method. The last one may already have been parsed for
+                    // inlining.
+                    scopes.push(scopes.peek().lastButOne());
+                } else {
+                    // The method has been narrowed down to the one we're now
+                    // going to parse, which is inlined here. It's monomorphic
+                    // inlining, but was not immediately clear as such.
+                    //
+                    // C1 prints multiple method tags during inlining when it
+                    // narrows the method being inlined. Example:
+                    //   ...
+                    //   <method id="813" holder="694" name="toString" return="695" flags="1" bytes="36" iicount="1"/>
+                    //   <call method="813" instr="invokevirtual"/>
+                    //   <inline_success reason="receiver is statically known"/>
+                    //   <method id="814" holder="792" name="toString" return="695" flags="1" bytes="5" iicount="3"/>
+                    //   <parse method="814">
+                    //   ...
+                    site.setMethod(m);
+                    scopes.push(site);
+                }
+            }
+        } else if (qname.equals("parse_done")) {
+            // Attach collected information about IR nodes to the current
+            // parsing scope before it's popped off the stack in endElement()
+            // (see where the parse tag is handled).
+            CallSite call = scopes.peek();
+            call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
+            call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
+            call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
+        }
+    }
+
+    /**
+     * Process the end of a compilation log XML element.<ul>
+     * <li><b>parse:</b> finish transforming a Java method's bytecode
+     * instructions to an initial compiler IR graph.</li>
+     * <li><b>uncommon_trap:</b> record the end of processing an uncommon trap,
+     * resetting {@link #currentTrap}.</li>
+     * <li><b>eliminate_lock:</b> record the end of a lock elimination,
+     * resetting {@link #currentLockElimination}.</li>
+     * <li><b>late_inline:</b> the closing tag for late_inline does not denote
+     * the end of a late inlining operation, but the end of the descriptive log
+     * data given at its beginning. That is, we're now in the position to
+     * assemble details about the inlining chain (bytecode instruction index in
+     * caller, called method). The {@link #lateInlining} flag is set to
+     * {@code true} here. (It will be reset when parsing the inlined methods is
+     * done; this happens for the successful case in this method as well, when
+     * {@code parse} elements are processed; and for inlining failures, in
+     * {@link #startElement(String,String,String,Attributes)}, when {@code inline_fail} elements are
+     * processed.)</li>
+     * <li><b>task:</b> perform cleanup at the end of a compilation. Note that
+     * the explicit {@code task_done} event is handled in
+     * {@link #startElement(String,String,String,Attributes)}.</li>
+     * </ul>
+     */
+    @Override
+    public void endElement(String uri, String localName, String qname) {
+        try {
+            if (qname.equals("parse")) {
+                // Finish dealing with the current call scope. If no more are
+                // left, no late inlining can be going on.
+                scopes.pop();
+                if (scopes.size() == 0) {
+                    lateInlining = false;
+                }
+            } else if (qname.equals("uncommon_trap")) {
+                currentTrap = null;
+            } else if (qname.startsWith("eliminate_lock")) {
+                currentLockElimination = null;
+            } else if (qname.equals("late_inline")) {
+                // Populate late inlining info.
+                if (scopes.size() != 0) {
+                    reportInternalError("scopes should be empty for late inline");
+                }
+                // late inline scopes are specified in reverse order:
+                // compiled method should be on top of stack.
+                CallSite caller = lateInlineScope.pop();
+                Method m = compile.getMethod();
+                if (!m.equals(caller.getMethod())) {
+                    reportInternalError(String.format("call site and late_inline info don't match:\n  method %s\n  caller method %s, bci %d", m, caller.getMethod(), current_bci));
+                }
+
+                // Walk down the inlining chain and assemble bci+callee info.
+                // This needs to be converted from caller+bci info contained in
+                // the late_inline data.
+                CallSite lateInlineSite = compile.getLateInlineCall();
+                ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<>();
+                do {
+                    current_bci = caller.getBci();
+                    // Next inlined call.
+                    caller = lateInlineScope.pop();
+                    CallSite callee = new CallSite(current_bci, caller.getMethod());
+                    callee.setInlineId(caller.getInlineId());
+                    thisCallScopes.addLast(callee);
+                    lateInlineSite.add(callee);
+                    lateInlineSite = callee;
+                } while (!lateInlineScope.isEmpty());
+
+                site = compile.getCall().findCallSite(thisCallScopes);
+                if (site == null) {
+                    // Call site could not be found - report the problem in detail.
+                    System.err.println("call scopes:");
+                    for (CallSite c : thisCallScopes) {
+                        System.err.println(c.getMethod() + " " + c.getBci() + " " + c.getInlineId());
+                    }
+                    CallSite c = thisCallScopes.getLast();
+                    if (c.getInlineId() != 0) {
+                        System.err.println("Looking for call site in entire tree:");
+                        ArrayDeque<CallSite> stack = compile.getCall().findCallSite2(c);
+                        for (CallSite c2 : stack) {
+                            System.err.println(c2.getMethod() + " " + c2.getBci() + " " + c2.getInlineId());
+                        }
+                    }
+                    System.err.println(caller.getMethod() + " bci: " + current_bci);
+                    reportInternalError("couldn't find call site");
+                }
+                lateInlining = true;
+
+                if (caller.getBci() != -999) {
+                    System.out.println(caller.getMethod());
+                    reportInternalError("broken late_inline info");
+                }
+                if (site.getMethod() != caller.getMethod()) {
+                    if (site.getInlineId() == caller.getInlineId()) {
+                        site.setMethod(caller.getMethod());
+                    } else {
+                        System.out.println(site.getMethod());
+                        System.out.println(caller.getMethod());
+                        reportInternalError("call site and late_inline info don't match");
+                    }
+                }
+                // late_inline is followed by parse with scopes.size() == 0,
+                // 'site' will be pushed to scopes.
+                lateInlineScope = null;
+            } else if (qname.equals("task")) {
+                types.clear();
+                methods.clear();
+                site = null;
+            }
+        } catch (Exception e) {
+            reportInternalError("exception while processing end element", e);
+        }
+    }
+
+    //
+    // Handlers for problems that occur in XML parsing itself.
+    //
+
+    @Override
+    public void warning(org.xml.sax.SAXParseException e) {
+        System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
+        e.printStackTrace();
+    }
+
+    @Override
+    public void error(org.xml.sax.SAXParseException e) {
+        System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
+        e.printStackTrace();
+    }
+
+    @Override
+    public void fatalError(org.xml.sax.SAXParseException e) {
+        System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
+        e.printStackTrace();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * In a compilation log, represent the event of making a given compiled method
+ * not-entrant, e.g., during an OSR compilation.
+ */
+class MakeNotEntrantEvent extends BasicLogEvent {
+
+    /**
+     * Denote whether the method is marked as a zombie, i.e., no further
+     * activations exist.
+     */
+    private final boolean zombie;
+
+    /**
+     * The method in question.
+     */
+    private NMethod nmethod;
+
+    MakeNotEntrantEvent(double s, String i, boolean z, NMethod nm) {
+        super(s, i);
+        zombie = z;
+        nmethod = nm;
+    }
+
+    public NMethod getNMethod() {
+        return nmethod;
+    }
+
+    public void print(PrintStream stream, boolean printID) {
+        if (isZombie()) {
+            stream.printf("%s make_zombie\n", getId());
+        } else {
+            stream.printf("%s make_not_entrant\n", getId());
+        }
+    }
+
+    public boolean isZombie() {
+        return zombie;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/Method.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.util.Arrays;
+
+import static com.sun.hotspot.tools.compiler.Constants.*;
+
+/**
+ * Representation of a Java method in a compilation log.
+ */
+public class Method {
+
+    /**
+     * The name of the class holding the method.
+     */
+    private String holder;
+
+    /**
+     * The method's name.
+     */
+    private String name;
+
+    /**
+     * The return type of the method, as a fully qualified (source-level) class
+     * or primitive type name.
+     */
+    private String returnType;
+
+    /**
+     * The method's signature, in internal form.
+     */
+    private String signature;
+
+    /**
+     * The length of the method's byte code.
+     */
+    private String bytes;
+
+    /**
+     * The number of times this method was invoked in the interpreter.
+     */
+    private String iicount;
+
+    /**
+     * The method's flags, in the form of a {@code String} representing the
+     * {@code int} encoding them.
+     */
+    private String flags;
+
+    /**
+     * Decode the {@link flags} numerical string to a format for console
+     * output. The result does not honour all possible flags but includes
+     * information about OSR compilation.
+     *
+     * @param osr_bci the byte code index at which an OSR compilation takes
+     * place, or -1 if the compilation is not an OSR one.
+     */
+    String decodeFlags(int osr_bci) {
+        int f = Integer.parseInt(getFlags());
+        char[] c = new char[4];
+        Arrays.fill(c, ' ');
+        if (osr_bci >= 0) {
+            c[0] = '%';
+        }
+        if ((f & JVM_ACC_SYNCHRONIZED) != 0) {
+            c[1] = 's';
+        }
+        return new String(c);
+    }
+
+    /**
+     * Format this method for console output.
+     *
+     * @param osr_bci the byte code index at which OSR takes place, or -1 if no
+     * OSR compilation is going on.
+     */
+    String format(int osr_bci) {
+        if (osr_bci >= 0) {
+            return getHolder() + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
+        } else {
+            return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
+    }
+
+    public String getFullName() {
+        return getHolder().replace('/', '.') + "." + getName() + signature;
+    }
+
+    public String getHolder() {
+        return holder;
+    }
+
+    public void setHolder(String holder) {
+        this.holder = holder;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getReturnType() {
+        return returnType;
+    }
+
+    public void setReturnType(String returnType) {
+        this.returnType = returnType;
+    }
+
+    public String getSignature() {
+        return signature;
+    }
+
+    public void setSignature(String signature) {
+        this.signature = signature.replace('/', '.');
+    }
+
+    public String getArguments() {
+        return signature.substring(0, signature.indexOf(')') + 1);
+    }
+
+    public String getBytes() {
+        return bytes;
+    }
+
+    public void setBytes(String bytes) {
+        this.bytes = bytes;
+    }
+
+    public String getIICount() {
+        return iicount;
+    }
+
+    public void setIICount(String iicount) {
+        this.iicount = iicount;
+    }
+
+    public String getFlags() {
+        return flags;
+    }
+
+    public void setFlags(String flags) {
+        this.flags = flags;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof Method) {
+            Method other = (Method) o;
+            return holder.equals(other.holder) && name.equals(other.name) && signature.equals(other.signature);
+        }
+        return false;
+    }
+
+    public int hashCode() {
+        return holder.hashCode() ^ name.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/NMethod.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * A compilation log event that is signalled whenever a new nmethod (a native
+ * method, a compilation result) is created.
+ */
+public class NMethod extends BasicLogEvent {
+
+    /**
+     * The nmethod's starting address in memory.
+     */
+    private long address;
+
+    /**
+     * The nmethod's size in bytes.
+     */
+    private long size;
+
+    NMethod(double s, String i, long a, long sz) {
+        super(s, i);
+        address = a;
+        size = sz;
+    }
+
+    public void print(PrintStream out, boolean printID) {
+        // XXX Currently we do nothing
+        // throw new InternalError();
+    }
+
+    public long getAddress() {
+        return address;
+    }
+
+    public void setAddress(long address) {
+        this.address = address;
+    }
+
+    public long getSize() {
+        return size;
+    }
+
+    public void setSize(long size) {
+        this.size = size;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/Phase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * Representation of a compilation phase as a log event.
+ */
+public class Phase extends BasicLogEvent {
+
+    /**
+     * The number of nodes in the compilation at the beginning of this phase.
+     */
+    private final int startNodes;
+
+    /**
+     * The number of nodes in the compilation at the end of this phase.
+     */
+    private int endNodes;
+
+    /**
+     * The number of live nodes in the compilation at the beginning of this
+     * phase.
+     */
+    private final int startLiveNodes;
+
+    /**
+     * The number of live nodes in the compilation at the end of this phase.
+     */
+    private int endLiveNodes;
+
+    Phase(String n, double s, int nodes, int live) {
+        super(s, n);
+        startNodes = nodes;
+        startLiveNodes = live;
+    }
+
+    int getNodes() {
+        return getEndNodes() - getStartNodes();
+    }
+
+    void setEndNodes(int n) {
+        endNodes = n;
+    }
+
+    public String getName() {
+        return getId();
+    }
+
+    public int getStartNodes() {
+        return startNodes;
+    }
+
+    public int getEndNodes() {
+        return endNodes;
+    }
+
+    /**
+     * The number of live nodes added by this phase.
+     */
+    int getAddedLiveNodes() {
+        return getEndLiveNodes() - getStartLiveNodes();
+    }
+
+    void setEndLiveNodes(int n) {
+        endLiveNodes = n;
+    }
+
+    public int getStartLiveNodes() {
+        return startLiveNodes;
+    }
+
+    public int getEndLiveNodes() {
+        return endLiveNodes;
+    }
+
+    @Override
+    public void print(PrintStream stream, boolean printID) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/UncommonTrap.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * An instance of this class represents an uncommon trap associated with a
+ * given bytecode instruction. An uncommon trap is described in terms of its
+ * reason and action to be taken. An instance of this class is always relative
+ * to a specific method and only contains the relevant bytecode instruction
+ * index.
+ */
+class UncommonTrap {
+
+    private int bci;
+    private String reason;
+    private String action;
+    private String bytecode;
+
+    public UncommonTrap(int b, String r, String a, String bc) {
+        bci = b;
+        reason = r;
+        action = a;
+        bytecode = bc;
+    }
+
+    public int getBCI() {
+        return bci;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public String getBytecode() {
+        return bytecode;
+    }
+
+    void emit(PrintStream stream, int indent) {
+        for (int i = 0; i < indent; i++) {
+            stream.print(' ');
+        }
+    }
+
+    public void print(PrintStream stream, int indent) {
+        emit(stream, indent);
+        stream.println(this);
+    }
+
+    public String toString() {
+        return "@ " + bci  + " " + getBytecode() + " uncommon trap " + getReason() + " " + getAction();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009, 2015, 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 com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents an uncommon trap encountered during a compilation.
+ */
+class UncommonTrapEvent extends BasicLogEvent {
+
+    private final String reason;
+    private final String action;
+
+    /**
+     * Denote how many times this trap has been encountered.
+     */
+    private int count;
+
+    /**
+     * The name of the bytecode instruction at which the trap occurred.
+     */
+    private String bytecode;
+
+    private List<String> jvmsMethods = new ArrayList<>();
+
+    private List<Integer> jvmsBCIs = new ArrayList<>();
+
+    UncommonTrapEvent(double s, String i, String r, String a, int c) {
+        super(s, i);
+        reason = r;
+        action = a;
+        count = c;
+    }
+
+    public void updateCount(UncommonTrapEvent trap) {
+        setCount(Math.max(getCount(), trap.getCount()));
+    }
+
+    public void print(PrintStream stream, boolean printID) {
+        if (printID) {
+            stream.print(getId() + " ");
+        }
+        stream.printf("uncommon trap %s %s %s\n", bytecode, getReason(), getAction());
+        int indent = 2;
+        for (int j = 0; j < jvmsMethods.size(); j++) {
+            for (int i = 0; i < indent; i++) {
+                stream.print(' ');
+            }
+            stream.println("@ " + jvmsBCIs.get(j) + " " + jvmsMethods.get(j));
+            indent += 2;
+        }
+    }
+
+
+    public String getReason() {
+        return reason;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    /**
+     * Set the compilation for this event. This involves identifying the call
+     * site to which this uncommon trap event belongs. In addition to setting
+     * the {@link #compilation} link, this method will consequently also set
+     * the {@link #bytecode} field.
+     */
+    public void setCompilation(Compilation compilation) {
+        super.setCompilation(compilation);
+        // Attempt to associate a bytecode with with this trap
+        CallSite site = compilation.getCall();
+        int i = 0;
+        try {
+            List<UncommonTrap> traps = site.getTraps();
+            while (i + 1 < jvmsMethods.size()) {
+                if (!jvmsMethods.get(i).equals(site.getMethod().getFullName())) {
+                    throw new InternalError(jvmsMethods.get(i) + " != " + site.getMethod().getFullName());
+                }
+                CallSite result = null;
+                for (CallSite call : site.getCalls()) {
+                    if (call.getBci() == jvmsBCIs.get(i) &&
+                        call.getMethod().getFullName().equals(jvmsMethods.get(i + 1)) &&
+                        call.getReceiver() == null) {
+                        result = call;
+                        i++;
+                        break;
+                    }
+                }
+                if (result == null) {
+                    throw new InternalError("couldn't find call site");
+                }
+                site = result;
+                traps = site.getTraps();
+            }
+            for (UncommonTrap trap : traps) {
+                if (trap.getBCI() == jvmsBCIs.get(i) &&
+                    trap.getReason().equals(getReason()) &&
+                    trap.getAction().equals(getAction())) {
+                    bytecode = trap.getBytecode();
+                    return;
+                }
+            }
+            throw new InternalError("couldn't find bytecode");
+        } catch (Exception e) {
+            bytecode = "<unknown>";
+        }
+    }
+
+    public void addMethodAndBCI(String method, int bci) {
+        jvmsMethods.add(0, method);
+        jvmsBCIs.add(0, bci);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/g1/test_g1HeapVerifier.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1HeapVerifier.hpp"
+#include "logging/logConfiguration.hpp"
+#include "unittest.hpp"
+
+TEST(G1HeapVerifier, parse) {
+  G1HeapVerifier verifier(NULL);
+
+  LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(gc, verify));
+
+  // Default is to verify everything.
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyAll));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyYoungOnly));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyInitialMark));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyMixed));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyRemark));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyCleanup));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyFull));
+
+  // Setting one will disable all other.
+  verifier.parse_verification_type("full");
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyAll));
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyYoungOnly));
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyInitialMark));
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyMixed));
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyRemark));
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyCleanup));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyFull));
+
+  // Verify case sensitivity.
+  verifier.parse_verification_type("YOUNG-ONLY");
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyYoungOnly));
+  verifier.parse_verification_type("young-only");
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyYoungOnly));
+
+  // Verify perfect match
+  verifier.parse_verification_type("mixedgc");
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyMixed));
+  verifier.parse_verification_type("mixe");
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyMixed));
+  verifier.parse_verification_type("mixed");
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyMixed));
+
+  // Verify the last three
+  verifier.parse_verification_type("initial-mark");
+  verifier.parse_verification_type("remark");
+  verifier.parse_verification_type("cleanup");
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyRemark));
+  ASSERT_TRUE(verifier.should_verify(G1HeapVerifier::G1VerifyCleanup));
+
+  // Enabling all is not the same as G1VerifyAll
+  ASSERT_FALSE(verifier.should_verify(G1HeapVerifier::G1VerifyAll));
+}
--- a/test/hotspot/gtest/logging/test_logMessageTest.cpp	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logMessageTest.cpp	Thu Dec 07 11:54:55 2017 +0000
@@ -27,6 +27,7 @@
 #include "logTestUtils.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
+#include "memory/allocation.inline.hpp"
 #include "unittest.hpp"
 #include "utilities/globalDefinitions.hpp"
 
--- a/test/hotspot/jtreg/Makefile	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/Makefile	Thu Dec 07 11:54:55 2017 +0000
@@ -62,8 +62,12 @@
   endif
 endif
 
+ifndef CONCURRENCY_FACTOR
+  CONCURRENCY_FACTOR = 1
+endif
+
 # Concurrency based on min(cores / 2, 12)
-CONCURRENCY := $(shell expr $(NUM_CORES) / 2)
+CONCURRENCY := $(shell awk 'BEGIN { printf "%.0f", $(NUM_CORES) / 2 * $(CONCURRENCY_FACTOR) }')
 ifeq ($(CONCURRENCY), 0)
   CONCURRENCY := 1
 else ifeq ($(shell expr $(CONCURRENCY) \> 12), 1)
--- a/test/hotspot/jtreg/ProblemList.txt	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/ProblemList.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -65,6 +65,7 @@
 gc/survivorAlignment/TestPromotionToSurvivor.java 8129886 generic-all
 gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
 gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
+gc/g1/TestVerifyGCType.java 8193067 generic-all
 gc/stress/gclocker/TestGCLockerWithG1.java 8179226 generic-all
 gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java 8177765 generic-all
 
@@ -76,6 +77,7 @@
 # This test is disabled since it will stress NMT and timeout during normal testing
 runtime/NMT/MallocStressTest.java 8166548 generic-all
 runtime/SharedArchiveFile/DefaultUseWithClient.java 8154204 generic-all
+runtime/AppCDS/UseAppCDS.java 8165603 windows-all
 
 #############################################################################
 
@@ -84,12 +86,7 @@
 serviceability/jdwp/AllModulesCommandTest.java 8170541 generic-all
 serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
 serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java 8173936 generic-all
-serviceability/sa/JhsdbThreadInfoTest.java 8184042 macosx-all
-serviceability/sa/TestInstanceKlassSize.java 8184042 macosx-all
-serviceability/sa/TestInstanceKlassSizeForInterface.java 8184042 macosx-all
-serviceability/sa/TestPrintMdo.java 8184042 macosx-all
 serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
-serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java 8184042 macosx-all
 #############################################################################
 
 # :hotspot_misc
--- a/test/hotspot/jtreg/TEST.ROOT	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/TEST.ROOT	Thu Dec 07 11:54:55 2017 +0000
@@ -53,6 +53,7 @@
     vm.rtm.os \
     vm.aot \
     vm.cds \
+    vm.cds.custom.loaders \
     vm.graal.enabled \
     docker.support
 
--- a/test/hotspot/jtreg/TEST.groups	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/TEST.groups	Thu Dec 07 11:54:55 2017 +0000
@@ -189,12 +189,27 @@
  -runtime/Unsafe/RangeCheck.java \
  -runtime/containers/ \
   sanity/ \
-  testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java
+  testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java \
+ -:hotspot_tier1_runtime_appcds_exclude
 
 hotspot_cds = \
   runtime/SharedArchiveFile/ \
   runtime/CompressedOops/
 
+# AppCDS
+# If modifying AppCDS it is also recommended to run the open hotspot_cds group
+hotspot_appcds = \
+  runtime/appcds/
+
+# A subset of AppCDS tests to be run in JPRT push
+hotspot_tier1_runtime_appcds = \
+  runtime/appcds/HelloTest.java \
+  runtime/appcds/sharedStrings/SharedStringsBasic.java \
+  runtime/appcds/ClassLoaderTest.java
+
+hotspot_tier1_runtime_appcds_exclude = \
+  runtime/appcds/ \
+  -:hotspot_tier1_runtime_appcds
 
 hotspot_tier1_serviceability = \
   serviceability/dcmd/compiler \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/TestSplitIfPinnedCMove.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. 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.
+ */
+
+/**
+ * @test
+ * @bug 8191153
+ * @summary too strong assert from 8186125
+ *
+ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestSplitIfPinnedCMove::not_inlined -XX:CompileOnly=TestSplitIfPinnedCMove::test TestSplitIfPinnedCMove
+ *
+ */
+
+public class TestSplitIfPinnedCMove {
+    static void not_inlined() {}
+
+    static class A {
+        A(int f) {
+            this.f = f;
+        }
+        int f;
+    }
+
+    static int test(int i1, int i3, A a1, A a2) {
+        // loops to trigger more loop optimization passes
+        int res = 0;
+        for (int i = 0; i < 2; i++) {
+            for (int j = 0; j < 2; j++) {
+                for (int k = 0; k < 2; k++) {
+                    res++;
+                }
+            }
+        }
+        // null check a1 and a2
+        res += a1.f + a2.f;
+
+        boolean f2 = false;
+        if (i1 > 0) {
+            not_inlined();
+            f2 = true;
+        }
+
+        // Should become CMoveP and be pinned here
+        res += (i3 > 0 ? a1 : a2).f;
+
+        // f2 should be split through phi with above if
+        if (f2) {
+            not_inlined();
+            res += 42;
+        }
+
+        // Another use for i3 > 0
+        if (i3 > 0) {
+            res++;
+        }
+        return res;
+    }
+
+    public static void main(String[] args) {
+        A a = new A(42);
+        for (int i = 0; i < 20_000; i++) {
+                test((i % 2) == 0 ? 0 : 1, (i % 2) == 0 ? 0 : 1, a, a);
+        }
+    }
+}
--- a/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/UseCountedLoopSafepointsTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -61,7 +61,8 @@
         OutputAnalyzer oa;
         try {
             oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.",
-                    "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", "-XX:+WhiteBoxAPI",
+                                             "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints",
+                                             "-XX:LoopStripMiningIter=" + (enabled ? "1" : "0"), "-XX:+WhiteBoxAPI",
                     "-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0",
                     "-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod",
                     UseCountedLoopSafepoints.class.getName());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/profiling/TestTypeProfiling.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+ /**
+  * @test
+  * @bug 8189439
+  * @summary Parameters type profiling is not performed from aarch64 interpreter
+  * @requires vm.flavor == "server" & vm.compMode == "Xmixed" & !vm.emulatedClient & !vm.graal.enabled
+  * @library /test/lib /
+  * @build sun.hotspot.WhiteBox
+  * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
+  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+  *                   -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
+  *                   -server -XX:-TieredCompilation -XX:TypeProfileLevel=020
+  *                    compiler.profiling.TestTypeProfiling
+  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+  *                   -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
+  *                   -server -XX:-TieredCompilation -XX:TypeProfileLevel=200
+  *                    compiler.profiling.TestTypeProfiling
+  */
+
+package compiler.profiling;
+
+import jdk.test.lib.Platform;
+import sun.hotspot.WhiteBox;
+import compiler.whitebox.CompilerWhiteBoxTest;
+import java.lang.reflect.Method;
+
+public class TestTypeProfiling {
+
+    public static int[] mParamTypeCheck(Object in) {
+        try {
+            return (int[]) in;
+        } catch (ClassCastException cce) {
+            return null;
+        }
+    }
+
+    static Object x2(Object src) {
+        return src;
+    }
+
+    public static int[] mRetTypeCheck(Object in) {
+        try {
+            Object out = x2(in);
+            return (int[]) out;
+        } catch (ClassCastException cce) {
+            return null;
+        }
+    }
+
+    private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+    private static final int TIERED_STOP_AT_LEVEL = WHITE_BOX.getIntxVMFlag("TieredStopAtLevel").intValue();
+
+    static boolean deoptimize(Method method, Object src_obj) throws Exception {
+        for (int i = 0; i < 10; i++) {
+            method.invoke(null, src_obj);
+            if (!WHITE_BOX.isMethodCompiled(method)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static public void main(String[] args) throws Exception {
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
+        }
+        // Only execute if C2 is available
+        if (TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) {
+            throw new RuntimeException("please enable C2");
+        }
+
+        Method method;
+        if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 20) {
+            method = TestTypeProfiling.class.getMethod("mRetTypeCheck", Object.class);
+        } else
+        if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 200) {
+            method = TestTypeProfiling.class.getMethod("mParamTypeCheck", Object.class);
+        } else {
+            throw new RuntimeException("please setup method return/params type profilation: -XX:TypeProfileLevel=020/200");
+        }
+
+        int[] src = new int[10];
+        Object src_obj = new Object();
+
+        // Warm up & make sure we collect type profiling
+        for (int i = 0; i < 20000; i++) {
+            mParamTypeCheck(src);
+            mRetTypeCheck(src);
+        }
+
+        // And make sure the method is compiled by C2
+        WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
+        if (!WHITE_BOX.isMethodCompiled(method)) {
+            throw new RuntimeException(method.getName() + " is not compiled");
+        }
+
+        // should deoptimize for speculative type check
+        if (!deoptimize(method, src_obj)) {
+            throw new RuntimeException(method.getName() + " is not deoptimized");
+        }
+
+        // compile again
+        WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
+        if (!WHITE_BOX.isMethodCompiled(method)) {
+            throw new RuntimeException(method.getName() + " is not recompiled");
+        }
+
+        // should deoptimize for actual type check
+        if (!deoptimize(method, src_obj)) {
+            throw new RuntimeException(method.getName() + " is not deoptimized (should deoptimize for actual type check)");
+        }
+
+        // compile once again
+        WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
+        if (!WHITE_BOX.isMethodCompiled(method)) {
+            throw new RuntimeException(method.getName() + " is not recompiled");
+        }
+
+        // this time new parameter type should not force deoptimization
+        if (deoptimize(method, src_obj)) {
+            throw new RuntimeException(method.getName() + " is deoptimized again");
+        }
+    }
+}
--- a/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,7 +24,8 @@
 
 /* @test
  * @bug 8167409
- * @run main/othervm/native -Xcomp compiler.runtime.criticalnatives.argumentcorruption.CheckLongArgs
+ * @requires os.arch != "aarch64"
+ * @run main/othervm/native -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.argumentcorruption.CheckLongArgs
  */
 package compiler.runtime.criticalnatives.argumentcorruption;
 public class CheckLongArgs {
--- a/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,7 +24,8 @@
 
 /* @test
  * @bug 8167408
- * @run main/othervm/native -Xcomp compiler.runtime.criticalnatives.lookup.LookUp
+ * @requires os.arch != "aarch64"
+ * @run main/othervm/native -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.lookup.LookUp
  */
 package compiler.runtime.criticalnatives.lookup;
 public class LookUp {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/unsafe/TestLoopUnswitching.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. 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.
+ */
+
+/**
+ * @test
+ * @bug 8191887
+ * @summary loop cloning misses support for Opaque4 node
+ * @modules java.base/jdk.internal.misc:+open
+ *
+ * @run main/othervm -XX:-BackgroundCompilation TestLoopUnswitching
+ *
+ */
+
+import jdk.internal.misc.Unsafe;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+public class TestLoopUnswitching {
+
+    static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe();
+    static final long F_OFFSET;
+
+    static class A {
+        int f;
+        A(int f) {
+            this.f = f;
+        }
+    }
+
+    static {
+        try {
+            Field fField = A.class.getDeclaredField("f");
+            F_OFFSET = UNSAFE.objectFieldOffset(fField);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static int test1(A[] arr, boolean flag1, boolean flag2) {
+        int res = 0;
+        for (int i = 0; i < 10; i++) {
+            A a = arr[i];
+            if (flag1) { // triggers unswitching
+                res += UNSAFE.getInt(a, F_OFFSET);
+            }
+            if (flag2) {
+                // Opaque4 node here is in the loop but If is out of the loop
+                res += UNSAFE.getInt(a, F_OFFSET);
+                break;
+            }
+            res += UNSAFE.getInt(a, F_OFFSET);
+        }
+        return res;
+    }
+
+    static int test2(A[] arr, boolean flag1, boolean flag2) {
+        int res = 0;
+        for (int i = 0; i < 10; i++) {
+            A a = arr[i];
+            if (flag1) { // triggers unswitching
+                res += UNSAFE.getInt(a, F_OFFSET);
+            }
+            if (flag2) {
+                // Opaque4 node here is out of the loop but Bool is in the the loop
+                res += UNSAFE.getInt(a, F_OFFSET);
+                break;
+            }
+            res += a.f;
+        }
+        return res;
+    }
+
+    static public void main(String[] args) {
+        A[] arr = new A[1000];
+        Arrays.fill(arr, new A(0x42));
+        for (int i = 0; i < 20000; i++) {
+            test1(arr, (i%2) == 0, (i%2) == 0);
+            test2(arr, (i%2) == 0, (i%2) == 0);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* @test TestAllocateHeapAt.java
+ * @key gc
+ * @summary Test to check allocation of Java Heap with AllocateHeapAt option
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ */
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class TestAllocateHeapAt {
+  public static void main(String args[]) throws Exception {
+    ArrayList<String> vmOpts = new ArrayList();
+
+    String testVmOptsStr = System.getProperty("test.java.opts");
+    if (!testVmOptsStr.isEmpty()) {
+      String[] testVmOpts = testVmOptsStr.split(" ");
+      Collections.addAll(vmOpts, testVmOpts);
+    }
+    String test_dir = System.getProperty("test.dir", ".");
+    Collections.addAll(vmOpts, new String[] {"-XX:AllocateHeapAt=" + test_dir,
+                                             "-Xlog:gc+heap=info",
+                                             "-Xmx32m",
+                                             "-Xms32m",
+                                             "-version"});
+
+    System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java"));
+    for (int i = 0; i < vmOpts.size(); i += 1) {
+      System.out.print(" " + vmOpts.get(i));
+    }
+    System.out.println();
+
+    ProcessBuilder pb =
+      ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    System.out.println("Output:\n" + output.getOutput());
+
+    output.shouldContain("Successfully allocated Java heap at location");
+    output.shouldHaveExitValue(0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* @test TestAllocateHeapAtError.java
+ * @key gc
+ * @summary Test to check correct handling of non-existent directory passed to AllocateHeapAt option
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ */
+
+import java.io.File;
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.UUID;
+
+public class TestAllocateHeapAtError {
+  public static void main(String args[]) throws Exception {
+    ArrayList<String> vmOpts = new ArrayList();
+
+    String testVmOptsStr = System.getProperty("test.java.opts");
+    if (!testVmOptsStr.isEmpty()) {
+      String[] testVmOpts = testVmOptsStr.split(" ");
+      Collections.addAll(vmOpts, testVmOpts);
+    }
+    String test_dir = System.getProperty("test.dir", ".");
+
+    File f = null;
+    do {
+      f = new File(test_dir, UUID.randomUUID().toString());
+    } while(f.exists());
+
+    Collections.addAll(vmOpts, new String[] {"-XX:AllocateHeapAt=" + f.getName(),
+                                             "-Xlog:gc+heap=info",
+                                             "-Xmx32m",
+                                             "-Xms32m",
+                                             "-version"});
+
+    System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java"));
+    for (int i = 0; i < vmOpts.size(); i += 1) {
+      System.out.print(" " + vmOpts.get(i));
+    }
+    System.out.println();
+
+    ProcessBuilder pb =
+      ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    System.out.println("Output:\n" + output.getOutput());
+
+    output.shouldContain("Could not create file for Heap");
+    output.shouldContain("Error occurred during initialization of VM");
+    output.shouldNotHaveExitValue(0);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* @test TestAllocateHeapAtMultiple.java
+ * @key gc
+ * @summary Test to check allocation of Java Heap with AllocateHeapAt option. Has multiple sub-tests to cover different code paths.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @requires vm.bits == "64"
+ */
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class TestAllocateHeapAtMultiple {
+  public static void main(String args[]) throws Exception {
+    ArrayList<String> vmOpts = new ArrayList();
+    String[] testVmOpts = null;
+
+    String test_dir = System.getProperty("test.dir", ".");
+
+    String testVmOptsStr = System.getProperty("test.java.opts");
+    if (!testVmOptsStr.isEmpty()) {
+      testVmOpts = testVmOptsStr.split(" ");
+    }
+
+    // Extra options for each of the sub-tests
+    String[] extraOptsList = new String[] {
+      "-Xmx32m -Xms32m -XX:+UseCompressedOops",     // 1. With compressedoops enabled.
+      "-Xmx32m -Xms32m -XX:-UseCompressedOops",     // 2. With compressedoops disabled.
+      "-Xmx32m -Xms32m -XX:HeapBaseMinAddress=3g",  // 3. With user specified HeapBaseMinAddress.
+      "-Xmx4g -Xms4g",                              // 4. With larger heap size (UnscaledNarrowOop not possible).
+      "-Xmx4g -Xms4g -XX:+UseLargePages",           // 5. Set UseLargePages.
+      "-Xmx4g -Xms4g -XX:+UseNUMA"                  // 6. Set UseNUMA.
+    };
+
+    for(String extraOpts : extraOptsList) {
+      vmOpts.clear();
+      if(testVmOpts != null) {
+        Collections.addAll(vmOpts, testVmOpts);
+      }
+      // Add extra options specific to the sub-test.
+      String[] extraOptsArray = extraOpts.split(" ");
+      if(extraOptsArray != null) {
+        Collections.addAll(vmOpts, extraOptsArray);
+      }
+      // Add common options
+      Collections.addAll(vmOpts, new String[] {"-XX:AllocateHeapAt=" + test_dir,
+                                               "-Xlog:gc+heap=info",
+                                               "-version"});
+
+      System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java"));
+      for (int i = 0; i < vmOpts.size(); i += 1) {
+        System.out.print(" " + vmOpts.get(i));
+      }
+      System.out.println();
+
+      ProcessBuilder pb =
+        ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
+      OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+      System.out.println("Output:\n" + output.getOutput());
+
+      output.shouldContain("Successfully allocated Java heap at location");
+      output.shouldHaveExitValue(0);
+    }
+  }
+}
--- a/test/hotspot/jtreg/gc/TestFullGCALot.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/gc/TestFullGCALot.java	Thu Dec 07 11:54:55 2017 +0000
@@ -24,7 +24,7 @@
 /*
  * @test TestFullGCALot
  * @key gc
- * @bug 4187687
+ * @bug 4187687 8187819
  * @summary Ensure no access violation when using FullGCALot
  * @requires vm.debug
  * @run main/othervm -XX:NewSize=10m -XX:+FullGCALot -XX:FullGCALotInterval=120 TestFullGCALot
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/TestGenerationPerfCounter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import static jdk.test.lib.Asserts.*;
+import gc.testlibrary.PerfCounter;
+import gc.testlibrary.PerfCounters;
+
+
+/* @test TestGenerationPerfCounter
+ * @bug 8080345
+ * @requires vm.gc=="null"
+ * @library /test/lib /
+ * @summary Tests that the sun.gc.policy.generations returns 2 for all GCs.
+ * @modules java.base/jdk.internal.misc
+ *          java.compiler
+ *          java.management/sun.management
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @run main/othervm -XX:+UsePerfData -XX:+UseSerialGC TestGenerationPerfCounter
+ * @run main/othervm -XX:+UsePerfData -XX:+UseParallelGC TestGenerationPerfCounter
+ * @run main/othervm -XX:+UsePerfData -XX:+UseG1GC TestGenerationPerfCounter
+ * @run main/othervm -XX:+UsePerfData -XX:+UseConcMarkSweepGC TestGenerationPerfCounter
+ */
+public class TestGenerationPerfCounter {
+    public static void main(String[] args) throws Exception {
+        long numGenerations =
+            PerfCounters.findByName("sun.gc.policy.generations").longValue();
+        assertEQ(numGenerations, 2L);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/TestMemoryMXBeansAndPoolsPresence.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import java.lang.management.*;
+import static jdk.test.lib.Asserts.*;
+import java.util.stream.*;
+
+/* @test TestMemoryMXBeansAndPoolsPresence
+ * @bug 8191564
+ * @summary Tests that GarbageCollectorMXBeans and GC MemoryPools are created.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @requires vm.gc == null
+ * @run main/othervm -XX:+UseG1GC TestMemoryMXBeansAndPoolsPresence G1
+ * @run main/othervm -XX:+UseConcMarkSweepGC TestMemoryMXBeansAndPoolsPresence CMS
+ * @run main/othervm -XX:+UseParallelGC TestMemoryMXBeansAndPoolsPresence Parallel
+ * @run main/othervm -XX:+UseSerialGC TestMemoryMXBeansAndPoolsPresence Serial
+ */
+
+class GCBeanDescription {
+    public String name;
+    public String[] poolNames;
+
+    public GCBeanDescription(String name, String[] poolNames) {
+        this.name = name;
+        this.poolNames = poolNames;
+    }
+}
+
+public class TestMemoryMXBeansAndPoolsPresence {
+    public static void test(GCBeanDescription... expectedBeans) {
+        List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();
+
+        List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
+        assertEQ(expectedBeans.length, gcBeans.size());
+
+        for (GCBeanDescription desc : expectedBeans) {
+            List<GarbageCollectorMXBean> beans = gcBeans.stream()
+                                                        .filter(b -> b.getName().equals(desc.name))
+                                                        .collect(Collectors.toList());
+            assertEQ(beans.size(), 1);
+
+            GarbageCollectorMXBean bean = beans.get(0);
+            assertEQ(desc.name, bean.getName());
+
+            String[] pools = bean.getMemoryPoolNames();
+            assertEQ(desc.poolNames.length, pools.length);
+            for (int i = 0; i < desc.poolNames.length; i++) {
+                assertEQ(desc.poolNames[i], pools[i]);
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        switch (args[0]) {
+            case "G1":
+                test(new GCBeanDescription("G1 Young Generation", new String[] {"G1 Eden Space", "G1 Survivor Space"}),
+                     new GCBeanDescription("G1 Old Generation",   new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}));
+                break;
+            case "CMS":
+                test(new GCBeanDescription("ParNew",              new String[] {"Par Eden Space", "Par Survivor Space"}),
+                     new GCBeanDescription("ConcurrentMarkSweep", new String[] {"Par Eden Space", "Par Survivor Space", "CMS Old Gen"}));
+                break;
+            case "Parallel":
+                test(new GCBeanDescription("PS Scavenge",         new String[] {"PS Eden Space", "PS Survivor Space"}),
+                     new GCBeanDescription("PS MarkSweep",        new String[] {"PS Eden Space", "PS Survivor Space", "PS Old Gen"}));
+                break;
+            case "Serial":
+                test(new GCBeanDescription("Copy",              new String[] {"Eden Space", "Survivor Space"}),
+                     new GCBeanDescription("MarkSweepCompact",  new String[] {"Eden Space", "Survivor Space", "Tenured Gen"}));
+                break;
+            default:
+                assertTrue(false);
+                break;
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/g1/TestInvalidateArrayCopy.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test TestInvalidateArrayCopy
+ * @bug 8182050
+ * @summary Check that benign (0-sized) out of heap bounds card table invalidations do not assert.
+ * @requires vm.gc.G1
+ * @requires vm.debug
+ * @key gc
+ * @run main/othervm -XX:NewSize=1M -Xlog:gc -XX:MaxNewSize=1m -XX:-UseTLAB -XX:OldSize=63M -XX:MaxHeapSize=64M TestInvalidateArrayCopy
+ */
+
+// The test allocates zero-sized arrays of j.l.O and tries to arraycopy random data into it so
+// that the asserting post barrier calls are executed. It assumes that G1 allocates eden regions
+// at the top of the heap for this problem to occur.
+public class TestInvalidateArrayCopy {
+
+    static final int NumIterations = 1000000;
+
+    // "Random" source data to "copy" into the target.
+    static Object[] sourceArray = new Object[10];
+
+    public static void main(String[] args) {
+        for (int i = 0; i < NumIterations; i++) {
+            Object[] x = new Object[0];
+            // Make sure that the compiler can't optimize out the above allocations.
+            if (i % (NumIterations / 10) == 0) {
+                System.out.println(x);
+            }
+            System.arraycopy(sourceArray, 0, x, 0, Math.min(x.length, sourceArray.length));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/g1/TestVerifyGCType.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test TestVerifyGCType
+ * @summary Test the VerifyGCType flag to ensure basic functionality.
+ * @key gc
+ * @requires vm.gc.G1
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver TestVerifyGCType
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import sun.hotspot.WhiteBox;
+
+public class TestVerifyGCType {
+    public static final String VERIFY_TAG    = "[gc,verify]";
+    public static final String VERIFY_BEFORE = "Verifying Before GC";
+    public static final String VERIFY_DURING = "Verifying During GC";
+    public static final String VERIFY_AFTER  = "Verifying After GC";
+
+    public static void main(String args[]) throws Exception {
+        testAllVerificationEnabled();
+        testAllExplicitlyEnabled();
+        testFullAndRemark();
+        testConcurrentMark();
+        testBadVerificationType();
+        testUnsupportedCollector();
+    }
+
+    private static void testAllVerificationEnabled() throws Exception {
+        // Test with all verification enabled
+        OutputAnalyzer output = testWithVerificationType(new String[0]);
+        output.shouldHaveExitValue(0);
+
+        verifyCollection("Pause Young", true, false, true, output.getStdout());
+        verifyCollection("Pause Initial Mark", true, false, true, output.getStdout());
+        verifyCollection("Pause Mixed", true, false, true, output.getStdout());
+        verifyCollection("Pause Remark", false, true, false, output.getStdout());
+        verifyCollection("Pause Cleanup", false, true, false, output.getStdout());
+        verifyCollection("Pause Full", true, true, true, output.getStdout());
+    }
+
+    private static void testAllExplicitlyEnabled() throws Exception {
+        OutputAnalyzer output;
+        // Test with all explicitly enabled
+        output = testWithVerificationType(new String[] {
+                "young-only", "initial-mark", "mixed", "remark", "cleanup", "full"});
+        output.shouldHaveExitValue(0);
+
+        verifyCollection("Pause Young", true, false, true, output.getStdout());
+        verifyCollection("Pause Initial Mark", true, false, true, output.getStdout());
+        verifyCollection("Pause Mixed", true, false, true, output.getStdout());
+        verifyCollection("Pause Remark", false, true, false, output.getStdout());
+        verifyCollection("Pause Cleanup", false, true, false, output.getStdout());
+        verifyCollection("Pause Full", true, true, true, output.getStdout());
+    }
+
+    private static void testFullAndRemark() throws Exception {
+        OutputAnalyzer output;
+        // Test with full and remark
+        output = testWithVerificationType(new String[] {"remark", "full"});
+        output.shouldHaveExitValue(0);
+
+        verifyCollection("Pause Young", false, false, false, output.getStdout());
+        verifyCollection("Pause Initial Mark", false, false, false, output.getStdout());
+        verifyCollection("Pause Mixed", false, false, false, output.getStdout());
+        verifyCollection("Pause Remark", false, true, false, output.getStdout());
+        verifyCollection("Pause Cleanup", false, false, false, output.getStdout());
+        verifyCollection("Pause Full", true, true, true, output.getStdout());
+    }
+
+    private static void testConcurrentMark() throws Exception {
+        OutputAnalyzer output;
+        // Test with full and remark
+        output = testWithVerificationType(new String[] {"initial-mark", "cleanup", "remark"});
+        output.shouldHaveExitValue(0);
+
+        verifyCollection("Pause Young", false, false, false, output.getStdout());
+        verifyCollection("Pause Initial Mark", true, false, true, output.getStdout());
+        verifyCollection("Pause Mixed", false, false, false, output.getStdout());
+        verifyCollection("Pause Remark", false, true, false, output.getStdout());
+        verifyCollection("Pause Cleanup", false, true, false, output.getStdout());
+        verifyCollection("Pause Full", false, false, false, output.getStdout());
+    }
+
+    private static void testBadVerificationType() throws Exception {
+        OutputAnalyzer output;
+        // Test bad type
+        output = testWithVerificationType(new String[] {"old"});
+        output.shouldHaveExitValue(0);
+
+        output.shouldMatch("VerifyGCType: '.*' is unknown. Available types are: young-only, initial-mark, mixed, remark, cleanup and full");
+        verifyCollection("Pause Young", true, false, true, output.getStdout());
+        verifyCollection("Pause Initial Mark", true, false, true, output.getStdout());
+        verifyCollection("Pause Mixed", true, false, true, output.getStdout());
+        verifyCollection("Pause Remark", false, true, false, output.getStdout());
+        verifyCollection("Pause Cleanup", false, true, false, output.getStdout());
+        verifyCollection("Pause Full", true, true, true, output.getStdout());
+    }
+
+    private static void testUnsupportedCollector() throws Exception {
+        OutputAnalyzer output;
+        // Test bad gc
+        output = testWithBadGC();
+        output.shouldHaveExitValue(0);
+        output.shouldMatch("VerifyGCType is not supported by this collector.");
+    }
+
+    private static OutputAnalyzer testWithVerificationType(String[] types) throws Exception {
+        ArrayList<String> basicOpts = new ArrayList<>();
+        Collections.addAll(basicOpts, new String[] {
+                                       "-Xbootclasspath/a:.",
+                                       "-XX:+UnlockDiagnosticVMOptions",
+                                       "-XX:+UseG1GC",
+                                       "-XX:+WhiteBoxAPI",
+                                       "-Xlog:gc,gc+start,gc+verify=info",
+                                       "-Xms16m",
+                                       "-Xmx16m",
+                                       "-XX:+VerifyBeforeGC",
+                                       "-XX:+VerifyAfterGC",
+                                       "-XX:+VerifyDuringGC"});
+
+        for(String verifyType : types) {
+            basicOpts.add("-XX:VerifyGCType="+verifyType);
+        }
+
+        basicOpts.add(TriggerGCs.class.getName());
+
+        ProcessBuilder procBuilder =  ProcessTools.createJavaProcessBuilder(basicOpts.toArray(
+                                                                            new String[basicOpts.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        return analyzer;
+    }
+
+    private static OutputAnalyzer testWithBadGC() throws Exception {
+        ProcessBuilder procBuilder =  ProcessTools.createJavaProcessBuilder(new String[] {
+                "-XX:+UseParallelGC",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:VerifyGCType=full",
+                "-version"});
+
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        return analyzer;
+    }
+
+    private static void verifyCollection(String name, boolean expectBefore, boolean expectDuring, boolean expectAfter, String data) {
+        CollectionInfo ci = CollectionInfo.parseFirst(name, data);
+        Asserts.assertTrue(ci != null, "Expected GC not found: " + name + "\n" + data);
+
+        // Verify Before
+        verifyType(ci, expectBefore, VERIFY_BEFORE);
+        // Verify During
+        verifyType(ci, expectDuring, VERIFY_DURING);
+        // Verify After
+        verifyType(ci, expectAfter, VERIFY_AFTER);
+    }
+
+    private static void verifyType(CollectionInfo ci, boolean shouldExist, String pattern) {
+        if (shouldExist) {
+            Asserts.assertTrue(ci.containsVerification(pattern), "Missing expected verification for: " + ci.getName());
+        } else {
+            Asserts.assertFalse(ci.containsVerification(pattern), "Found unexpected verification for: " + ci.getName());
+        }
+    }
+
+    public static class CollectionInfo {
+        String name;
+        ArrayList<String> verification;
+        public CollectionInfo(String name) {
+            this.name = name;
+            this.verification = new ArrayList<>();
+            System.out.println("Created CollectionInfo: " + name);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void addVerification(String verify) {
+            System.out.println("Adding: " + verify);
+            verification.add(verify);
+        }
+
+        public boolean containsVerification(String contains) {
+            for (String entry : verification) {
+                if (entry.contains(contains)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        static CollectionInfo parseFirst(String name, String data) {
+            CollectionInfo result = null;
+            int firstIndex = data.indexOf(name);
+            if (firstIndex == -1) {
+                return result;
+            }
+            int nextIndex = data.indexOf(name, firstIndex + 1);
+            if (nextIndex == -1) {
+                return result;
+            }
+            // Found an entry for this name
+            result = new CollectionInfo(name);
+            String collectionData = data.substring(firstIndex, nextIndex + name.length());
+            for (String line : collectionData.split(System.getProperty("line.separator"))) {
+                if (line.contains(VERIFY_TAG)) {
+                    result.addVerification(line);
+                }
+            }
+            return result;
+        }
+    }
+
+    public static class TriggerGCs {
+        public static void main(String args[]) throws Exception {
+            WhiteBox wb = WhiteBox.getWhiteBox();
+            // Allocate some memory that can be turned into garbage.
+            Object[] used = alloc1M();
+
+            // Trigger the different GCs using the WhiteBox API.
+            wb.fullGC();  // full
+
+            // Memory have been promoted to old by full GC. Free
+            // some memory to be reclaimed by concurrent cycle.
+            partialFree(used);
+            wb.g1StartConcMarkCycle(); // initial-mark, remark and cleanup
+
+            // Sleep to make sure concurrent cycle is done
+            while (wb.g1InConcurrentMark()) {
+                Thread.sleep(1000);
+            }
+
+            // Trigger two young GCs, first will be young-only, second will be mixed.
+            wb.youngGC(); // young-only
+            wb.youngGC(); // mixed
+        }
+
+        private static Object[] alloc1M() {
+            Object[] ret = new Object[1024];
+            // Alloc 1024 1k byte arrays (~1M)
+            for (int i = 0; i < ret.length; i++) {
+                ret[i] = new byte[1024];
+            }
+            return ret;
+        }
+
+        private static void partialFree(Object[] array) {
+            // Free every other element
+            for (int i = 0; i < array.length; i+=2) {
+                array[i] = null;
+            }
+        }
+    }
+}
--- a/test/hotspot/jtreg/gc/metaspace/PerfCounter.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.
- */
-
-import sun.jvmstat.monitor.Monitor;
-
-/**
- * Represents a performance counter in the JVM.
- *
- * See http://openjdk.java.net/groups/hotspot/docs/Serviceability.html#bjvmstat
- * for more details about performance counters.
- */
-public class PerfCounter {
-    private final Monitor monitor;
-    private final String name;
-
-    PerfCounter(Monitor monitor, String name) {
-        this.monitor = monitor;
-        this.name = name;
-    }
-
-    /**
-     * Returns the value of this performance counter as a long.
-     *
-     * @return The long value of this performance counter
-     * @throws RuntimeException If the value of the performance counter isn't a long
-     */
-    public long longValue() {
-        Object value = monitor.getValue();
-        if (value instanceof Long) {
-            return ((Long) value).longValue();
-        }
-        throw new RuntimeException("Expected " + monitor.getName() + " to have a long value");
-    }
-
-    /**
-     * Returns the name of the performance counter.
-     *
-     * @return The name of the performance counter.
-     */
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-}
--- a/test/hotspot/jtreg/gc/metaspace/PerfCounters.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, 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.
- */
-
-import sun.jvmstat.monitor.Monitor;
-import sun.jvmstat.monitor.MonitorException;
-import sun.jvmstat.monitor.MonitoredHost;
-import sun.jvmstat.monitor.MonitoredVm;
-import sun.jvmstat.monitor.VmIdentifier;
-import jdk.test.lib.process.ProcessTools;
-
-/**
- * PerfCounters can be used to get a performance counter from the currently
- * executing VM.
- *
- * Throws a runtime exception if an error occurs while communicating with the
- * currently executing VM.
- */
-public class PerfCounters {
-    private final static MonitoredVm vm;
-
-    static {
-        try {
-            String pid = Long.toString(ProcessTools.getProcessId());
-            VmIdentifier vmId = new VmIdentifier(pid);
-            MonitoredHost host = MonitoredHost.getMonitoredHost(vmId);
-            vm = host.getMonitoredVm(vmId);
-        } catch (Exception e) {
-            throw new RuntimeException("Could not connect to the VM");
-        }
-    }
-
-    /**
-     * Returns the performance counter with the given name.
-     *
-     * @param name The name of the performance counter.
-     * @throws IllegalArgumentException If no counter with the given name exists.
-     * @throws MonitorException If an error occurs while communicating with the VM.
-     * @return The performance counter with the given name.
-     */
-    public static PerfCounter findByName(String name)
-        throws MonitorException, IllegalArgumentException {
-        Monitor m = vm.findByName(name);
-        if (m == null) {
-            throw new IllegalArgumentException("Did not find a performance counter with name " + name);
-        }
-        return new PerfCounter(m, name);
-    }
-}
--- a/test/hotspot/jtreg/gc/metaspace/TestMetaspacePerfCounters.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/gc/metaspace/TestMetaspacePerfCounters.java	Thu Dec 07 11:54:55 2017 +0000
@@ -32,11 +32,13 @@
 import sun.management.ManagementFactoryHelper;
 
 import static jdk.test.lib.Asserts.*;
+import gc.testlibrary.PerfCounter;
+import gc.testlibrary.PerfCounters;
 
 /* @test TestMetaspacePerfCounters
  * @bug 8014659
  * @requires vm.gc=="null"
- * @library /test/lib
+ * @library /test/lib /
  * @summary Tests that performance counters for metaspace and compressed class
  *          space exists and works.
  * @modules java.base/jdk.internal.misc
--- a/test/hotspot/jtreg/gc/metaspace/TestPerfCountersAndMemoryPools.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/gc/metaspace/TestPerfCountersAndMemoryPools.java	Thu Dec 07 11:54:55 2017 +0000
@@ -26,10 +26,12 @@
 
 import jdk.test.lib.Platform;
 import static jdk.test.lib.Asserts.*;
+import gc.testlibrary.PerfCounter;
+import gc.testlibrary.PerfCounters;
 
 /* @test TestPerfCountersAndMemoryPools
  * @bug 8023476
- * @library /test/lib
+ * @library /test/lib /
  * @requires vm.gc.Serial
  * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace
  *          report the same data.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithAllocateHeapAt.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithAllocateHeapAt
+ * @key gc
+ * @key stress
+ * @requires vm.gc.G1
+ * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @summary Stress Java heap allocation with AllocateHeapAt flag using GC basher.
+ * @run main/othervm/timeout=500 -Xlog:gc*=info -Xmx256m -server -XX:+UseG1GC -XX:AllocateHeapAt=. TestGCBasherWithAllocateHeapAt 120000
+ */
+public class TestGCBasherWithAllocateHeapAt {
+    public static void main(String[] args) throws IOException {
+        TestGCBasher.main(args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/testlibrary/PerfCounter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, 2015, 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 gc.testlibrary;
+
+import sun.jvmstat.monitor.Monitor;
+
+/**
+ * Represents a performance counter in the JVM.
+ *
+ * See http://openjdk.java.net/groups/hotspot/docs/Serviceability.html#bjvmstat
+ * for more details about performance counters.
+ */
+public class PerfCounter {
+    private final Monitor monitor;
+    private final String name;
+
+    PerfCounter(Monitor monitor, String name) {
+        this.monitor = monitor;
+        this.name = name;
+    }
+
+    /**
+     * Returns the value of this performance counter as a long.
+     *
+     * @return The long value of this performance counter
+     * @throws RuntimeException If the value of the performance counter isn't a long
+     */
+    public long longValue() {
+        Object value = monitor.getValue();
+        if (value instanceof Long) {
+            return ((Long) value).longValue();
+        }
+        throw new RuntimeException("Expected " + monitor.getName() + " to have a long value");
+    }
+
+    /**
+     * Returns the name of the performance counter.
+     *
+     * @return The name of the performance counter.
+     */
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/testlibrary/PerfCounters.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, 2016, 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 gc.testlibrary;
+
+import sun.jvmstat.monitor.Monitor;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredVm;
+import sun.jvmstat.monitor.VmIdentifier;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * PerfCounters can be used to get a performance counter from the currently
+ * executing VM.
+ *
+ * Throws a runtime exception if an error occurs while communicating with the
+ * currently executing VM.
+ */
+public class PerfCounters {
+    private final static MonitoredVm vm;
+
+    static {
+        try {
+            String pid = Long.toString(ProcessTools.getProcessId());
+            VmIdentifier vmId = new VmIdentifier(pid);
+            MonitoredHost host = MonitoredHost.getMonitoredHost(vmId);
+            vm = host.getMonitoredVm(vmId);
+        } catch (Exception e) {
+            throw new RuntimeException("Could not connect to the VM");
+        }
+    }
+
+    /**
+     * Returns the performance counter with the given name.
+     *
+     * @param name The name of the performance counter.
+     * @throws IllegalArgumentException If no counter with the given name exists.
+     * @throws MonitorException If an error occurs while communicating with the VM.
+     * @return The performance counter with the given name.
+     */
+    public static PerfCounter findByName(String name)
+        throws MonitorException, IllegalArgumentException {
+        Monitor m = vm.findByName(name);
+        if (m == null) {
+            throw new IllegalArgumentException("Did not find a performance counter with name " + name);
+        }
+        return new PerfCounter(m, name);
+    }
+}
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -46,6 +46,11 @@
         {"MinRAMFraction",            "2"},
         {"InitialRAMFraction",        "64"},
         {"AssumeMP",                  "false"},
+        {"UseMembar",                 "true"},
+        {"FastTLABRefill",            "false"},
+        {"DeferPollingPageLoopCount", "-1"},
+        {"SafepointSpinBeforeYield",  "2000"},
+        {"DeferThrSuspendLoopCount",  "4000"},
 
         // deprecated alias flags (see also aliased_jvm_flags):
         {"DefaultMaxRAMFraction", "4"},
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @requires (vm.debug == true)
  * @bug 6888954
  * @bug 8015884
  * @summary Exercise HotSpot error handling code by invoking java with
@@ -39,6 +40,7 @@
 public class ErrorHandler {
 
     public static OutputAnalyzer runTest(int testcase) throws Exception {
+        // The -XX:ErrorHandlerTest=N option requires debug bits.
         return new OutputAnalyzer(
             ProcessTools.createJavaProcessBuilder(
             "-XX:-TransmitErrorReport", "-XX:-CreateCoredumpOnCrash", "-XX:ErrorHandlerTest=" + testcase)
@@ -46,10 +48,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        // Test is only applicable for debug builds
-        if (!Platform.isDebugBuild()) {
-            return;
-        }
         // Keep this in sync with hotspot/src/share/vm/utilities/debug.cpp
         int i = 1;
         String[] strings = {
@@ -69,6 +67,10 @@
         String[] patterns = {
             "(SIGILL|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=",
             "(SIGBUS|SIGSEGV|SIGILL|EXCEPTION_ACCESS_VIOLATION).* at pc="
+            // -XX:ErrorHandlerTest=14 is tested by SafeFetchInErrorHandlingTest.java
+            // -XX:ErrorHandlerTest=15 is tested by SecondaryErrorTest.java
+            // -XX:ErrorHandlerTest=16 is tested by ThreadsListHandleInErrorHandlingTest.java
+            // -XX:ErrorHandlerTest=17 is tested by NestedThreadsListHandleInErrorHandlingTest.java
         };
 
         for (String s : strings) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.ProcessTools;
+
+/*
+ * @test
+ * @requires (vm.debug == true)
+ * @bug 8167108
+ * @summary Nested ThreadsListHandle info should be in error handling output.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableThreadSMRStatistics NestedThreadsListHandleInErrorHandlingTest
+ */
+
+/*
+ * This test was created using SafeFetchInErrorHandlingTest.java
+ * as a guide.
+ */
+public class NestedThreadsListHandleInErrorHandlingTest {
+  public static void main(String[] args) throws Exception {
+
+    // The -XX:ErrorHandlerTest=N option requires debug bits.
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+UnlockDiagnosticVMOptions",
+        "-Xmx100M",
+        "-XX:ErrorHandlerTest=17",
+        "-XX:-CreateCoredumpOnCrash",
+        "-version");
+
+    OutputAnalyzer output_detail = new OutputAnalyzer(pb.start());
+
+    // We should have crashed with a specific fatal error:
+    output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*");
+    System.out.println("Found fatal error header.");
+    output_detail.shouldMatch("# +fatal error: Force crash with a nested ThreadsListHandle.");
+    System.out.println("Found specific fatal error.");
+
+    // Extract hs_err_pid file.
+    String hs_err_file = output_detail.firstMatch("# *(\\S*hs_err_pid\\d+\\.log)", 1);
+    if (hs_err_file == null) {
+        throw new RuntimeException("Did not find hs_err_pid file in output.\n");
+    }
+
+    File f = new File(hs_err_file);
+    if (!f.exists()) {
+        throw new RuntimeException("hs_err_pid file missing at "
+                                   + f.getAbsolutePath() + ".\n");
+    }
+
+    System.out.println("Found hs_err_pid file. Scanning...");
+
+    FileInputStream fis = new FileInputStream(f);
+    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
+    String line = null;
+
+    Pattern [] pattern = new Pattern[] {
+        // The "Current thread" line should show a hazard ptr and
+        // a nested hazard ptr:
+        Pattern.compile("Current thread .* _threads_hazard_ptr=0x[0-9A-Fa-f][0-9A-Fa-f]*, _nested_threads_hazard_ptr_cnt=1, _nested_threads_hazard_ptrs=0x.*"),
+        // We should have a section of Threads class SMR info:
+        Pattern.compile("Threads class SMR info:"),
+        // We should have one nested ThreadsListHandle:
+        Pattern.compile(".*, _smr_nested_thread_list_max=1"),
+        // The current thread (marked with '=>') in the threads list
+        // should show a hazard ptr:
+        Pattern.compile("=>.* JavaThread \"main\" .*_threads_hazard_ptr=0x[0-9A-Fa-f][0-9A-Fa-f]*, _nested_threads_hazard_ptr_cnt=1, _nested_threads_hazard_ptrs=0x.*"),
+    };
+    int currentPattern = 0;
+
+    String lastLine = null;
+    while ((line = br.readLine()) != null) {
+        if (currentPattern < pattern.length) {
+            if (pattern[currentPattern].matcher(line).matches()) {
+                System.out.println("Found: " + line + ".");
+                currentPattern++;
+            }
+        }
+        lastLine = line;
+    }
+    br.close();
+
+    if (currentPattern < pattern.length) {
+        throw new RuntimeException("hs_err_pid file incomplete (first missing pattern: " +  currentPattern + ")");
+    }
+
+    if (!lastLine.equals("END.")) {
+        throw new RuntimeException("hs-err file incomplete (missing END marker.)");
+    } else {
+        System.out.println("End marker found.");
+    }
+
+    System.out.println("Done scanning hs_err_pid_file.");
+    System.out.println("PASSED.");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.ProcessTools;
+
+/*
+ * @test
+ * @requires (vm.debug == true)
+ * @bug 8167108
+ * @summary ThreadsListHandle info should be in error handling output.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableThreadSMRStatistics ThreadsListHandleInErrorHandlingTest
+ */
+
+/*
+ * This test was created using SafeFetchInErrorHandlingTest.java
+ * as a guide.
+ */
+public class ThreadsListHandleInErrorHandlingTest {
+  public static void main(String[] args) throws Exception {
+
+    // The -XX:ErrorHandlerTest=N option requires debug bits.
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+UnlockDiagnosticVMOptions",
+        "-Xmx100M",
+        "-XX:ErrorHandlerTest=16",
+        "-XX:-CreateCoredumpOnCrash",
+        "-version");
+
+    OutputAnalyzer output_detail = new OutputAnalyzer(pb.start());
+
+    // We should have crashed with a specific fatal error:
+    output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*");
+    System.out.println("Found fatal error header.");
+    output_detail.shouldMatch("# +fatal error: Force crash with an active ThreadsListHandle.");
+    System.out.println("Found specific fatal error.");
+
+    // Extract hs_err_pid file.
+    String hs_err_file = output_detail.firstMatch("# *(\\S*hs_err_pid\\d+\\.log)", 1);
+    if (hs_err_file == null) {
+        throw new RuntimeException("Did not find hs_err_pid file in output.\n");
+    }
+
+    File f = new File(hs_err_file);
+    if (!f.exists()) {
+        throw new RuntimeException("hs_err_pid file missing at "
+                                   + f.getAbsolutePath() + ".\n");
+    }
+
+    System.out.println("Found hs_err_pid file. Scanning...");
+
+    FileInputStream fis = new FileInputStream(f);
+    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
+    String line = null;
+
+    Pattern [] pattern = new Pattern[] {
+        // The "Current thread" line should show a hazard ptr:
+        Pattern.compile("Current thread .* _threads_hazard_ptr=0x.*"),
+        // We should have a section of Threads class SMR info:
+        Pattern.compile("Threads class SMR info:"),
+        // The current thread (marked with '=>') in the threads list
+        // should show a hazard ptr:
+        Pattern.compile("=>.* JavaThread \"main\" .*_threads_hazard_ptr=0x.*"),
+    };
+    int currentPattern = 0;
+
+    String lastLine = null;
+    while ((line = br.readLine()) != null) {
+        if (currentPattern < pattern.length) {
+            if (pattern[currentPattern].matcher(line).matches()) {
+                System.out.println("Found: " + line + ".");
+                currentPattern++;
+            }
+        }
+        lastLine = line;
+    }
+    br.close();
+
+    if (currentPattern < pattern.length) {
+        throw new RuntimeException("hs_err_pid file incomplete (first missing pattern: " +  currentPattern + ")");
+    }
+
+    if (!lastLine.equals("END.")) {
+        throw new RuntimeException("hs-err file incomplete (missing END marker.)");
+    } else {
+        System.out.println("End marker found.");
+    }
+
+    System.out.println("Done scanning hs_err_pid_file.");
+    System.out.println("PASSED.");
+  }
+}
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/BootAppendTests.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/BootAppendTests.java	Thu Dec 07 11:54:55 2017 +0000
@@ -86,6 +86,9 @@
 
         logTestCase("5");
         testBootAppendClass();
+
+        logTestCase("6");
+        testBootAppendExtraDir();
     }
 
     private static void logTestCase(String msg) {
@@ -241,4 +244,28 @@
             }
         }
     }
+
+    // Test #6: This is similar to Test #5. During runtime, an extra dir
+    //          is appended to the bootclasspath. It should not invalidate
+    //          the shared archive.
+    public static void testBootAppendExtraDir() throws Exception {
+        for (String mode : modes) {
+            CDSOptions opts = (new CDSOptions())
+                .setXShareMode(mode).setUseVersion(false)
+                .addPrefix("-Xbootclasspath/a:" + bootAppendJar + File.pathSeparator + appJar,
+                           "-showversion", "--limit-modules=java.base", "-cp", appJar)
+                .addSuffix("-Xlog:class+load=info",
+                           APP_CLASS, BOOT_APPEND_CLASS_NAME);
+
+            OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+            CDSTestUtils.checkExec(out, opts, "[class,load] nonjdk.myPackage.MyClass");
+
+            // If CDS is enabled, the nonjdk.myPackage.MyClass should be loaded
+            // from the shared archive.
+            if (mode.equals("on")) {
+                CDSTestUtils.checkExec(out, opts,
+                    "[class,load] nonjdk.myPackage.MyClass source: shared objects file");
+            }
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/CountStackFramesAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.countStackFrames() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug CountStackFramesAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class CountStackFramesAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 1000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        CountStackFramesAtExit threads[] = new CountStackFramesAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new CountStackFramesAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out of
+                // the exitSyncObj.await() call and the countStackFrames()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    try {
+                        threads[i].countStackFrames();
+                    } catch (IllegalThreadStateException itse) {
+                        // ignore because we expect it
+                    }
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.countStackFrames() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.countStackFrames()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.countStackFrames() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].countStackFrames();
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/InterruptAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.interrupt() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug InterruptAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class InterruptAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 1000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        InterruptAtExit threads[] = new InterruptAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new InterruptAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // The first interrupt() call will break the
+                // worker out of the exitSyncObj.await() call
+                // and the rest will come in during thread exit.
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].interrupt();
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.interrupt() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.interrupt()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.interrupt() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].interrupt();
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/IsInterruptedAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.isInterrupted() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug IsInterruptedAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class IsInterruptedAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 2000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        IsInterruptedAtExit threads[] = new IsInterruptedAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new IsInterruptedAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out of
+                // the exitSyncObj.await() call and the isInterrupted()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].isInterrupted();
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.isInterrupted() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.isInterrupted()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.isInterrupted() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].isInterrupted();
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/ResumeAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.resume() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug ResumeAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class ResumeAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 2000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        ResumeAtExit threads[] = new ResumeAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new ResumeAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out
+                // of the exitSyncObj.await() call and the resume()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].resume();
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.resume() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.resume()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.resume() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].resume();
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/SetNameAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.setName() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug SetNameAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class SetNameAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 1000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        SetNameAtExit threads[] = new SetNameAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new SetNameAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out
+                // of the exitSyncObj.await() call and the setName()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].setName("T" + i + "-" + late_count);
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.setName() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.setName()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.setName() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].setName("T" + i + "-done");
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/SetPriorityAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.setPriority() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug SetPriorityAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class SetPriorityAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 2000;
+
+    final static int MIN = java.lang.Thread.MIN_PRIORITY;
+    final static int NORM = java.lang.Thread.NORM_PRIORITY;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        SetPriorityAtExit threads[] = new SetPriorityAtExit[N_THREADS];
+
+        int prio = MIN;
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new SetPriorityAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out of
+                // the exitSyncObj.await() call and the setPriority()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].setPriority(prio);
+                    if (prio == MIN) {
+                        prio = NORM;
+                    } else {
+                        prio = MIN;
+                    }
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.setPriority() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.setPriority()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.setPriority() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].setPriority(prio);
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/StopAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.stop() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug StopAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class StopAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 1000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        try {
+            // Tell main thread we have started.
+            startSyncObj.countDown();
+            try {
+                // Wait for main thread to interrupt us so we
+                // can race to exit.
+                exitSyncObj.await();
+            } catch (InterruptedException e) {
+                // ignore because we expect one
+            }
+        } catch (ThreadDeath td) {
+            // ignore because we're testing Thread.stop() which throws it
+        } catch (NoClassDefFoundError ncdfe) {
+            // ignore because we're testing Thread.stop() which can cause it
+        }
+    }
+
+    public static void main(String[] args) {
+        StopAtExit threads[] = new StopAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new StopAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out
+                // of the exitSyncObj.await() call and the stop()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].stop();
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.stop() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            } catch (NoClassDefFoundError ncdfe) {
+                // Ignore because we're testing Thread.stop() which can
+                // cause it. Yes, a NoClassDefFoundError that happens
+                // in a worker thread can subsequently be seen in the
+                // main thread.
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.stop()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.stop() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].stop();
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/SuspendAtExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * @test
+ * @bug 8167108
+ * @summary Stress test java.lang.Thread.suspend() at thread exit.
+ * @run main/othervm -Xlog:thread+smr=debug SuspendAtExit
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class SuspendAtExit extends Thread {
+    final static int N_THREADS = 32;
+    final static int N_LATE_CALLS = 10000;
+
+    public CountDownLatch exitSyncObj = new CountDownLatch(1);
+    public CountDownLatch startSyncObj = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        // Tell main thread we have started.
+        startSyncObj.countDown();
+        try {
+            // Wait for main thread to interrupt us so we
+            // can race to exit.
+            exitSyncObj.await();
+        } catch (InterruptedException e) {
+            // ignore because we expect one
+        }
+    }
+
+    public static void main(String[] args) {
+        SuspendAtExit threads[] = new SuspendAtExit[N_THREADS];
+
+        for (int i = 0; i < N_THREADS; i++ ) {
+            threads[i] = new SuspendAtExit();
+            int late_count = 1;
+            threads[i].start();
+            try {
+                // Wait for the worker thread to get going.
+                threads[i].startSyncObj.await();
+
+                // This interrupt() call will break the worker out
+                // of the exitSyncObj.await() call and the suspend()
+                // calls will come in during thread exit.
+                threads[i].interrupt();
+                for (; late_count <= N_LATE_CALLS; late_count++) {
+                    threads[i].suspend();
+
+                    if (!threads[i].isAlive()) {
+                        // Done with Thread.suspend() calls since
+                        // thread is not alive.
+                        break;
+                    }
+                    threads[i].resume();
+                }
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+
+            System.out.println("INFO: thread #" + i + ": made " + late_count +
+                               " late calls to java.lang.Thread.suspend()");
+            System.out.println("INFO: thread #" + i + ": N_LATE_CALLS==" +
+                               N_LATE_CALLS + " value is " +
+                               ((late_count >= N_LATE_CALLS) ? "NOT " : "") +
+                               "large enough to cause a Thread.suspend() " +
+                               "call after thread exit.");
+
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                throw new Error("Unexpected: " + e);
+            }
+            threads[i].suspend();
+            threads[i].resume();
+            if (threads[i].isAlive()) {
+                throw new Error("Expected !Thread.isAlive() after thread #" +
+                                i + " has been join()'ed");
+            }
+        }
+
+        String cmd = System.getProperty("sun.java.command");
+        if (cmd != null && !cmd.startsWith("com.sun.javatest.regtest.agent.MainWrapper")) {
+            // Exit with success in a non-JavaTest environment:
+            System.exit(0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Thread/TestThreadDumpSMRInfo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test
+ * @bug     8167108
+ * @summary Checks whether jstack reports a "Threads class SMR info" section.
+ *
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableThreadSMRStatistics TestThreadDumpSMRInfo
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.JDKToolFinder;
+
+public class TestThreadDumpSMRInfo {
+    // jstack tends to be closely bound to the VM that we are running
+    // so use getTestJDKTool() instead of getCompileJDKTool() or even
+    // getJDKTool() which can fall back to "compile.jdk".
+    final static String JSTACK = JDKToolFinder.getTestJDKTool("jstack");
+    final static String PID = "" + ProcessHandle.current().pid();
+
+    // Here's a sample "Threads class SMR info" section:
+    //
+    // Threads class SMR info:
+    // _smr_java_thread_list=0x0000000000ce8da0, length=23, elements={
+    // 0x000000000043a800, 0x0000000000aee800, 0x0000000000b06800, 0x0000000000b26000,
+    // 0x0000000000b28800, 0x0000000000b2b000, 0x0000000000b2e000, 0x0000000000b30000,
+    // 0x0000000000b32800, 0x0000000000b35000, 0x0000000000b3f000, 0x0000000000b41800,
+    // 0x0000000000b44000, 0x0000000000b46800, 0x0000000000b48800, 0x0000000000b53000,
+    // 0x0000000000b55800, 0x0000000000b57800, 0x0000000000b5a000, 0x0000000000b5c800,
+    // 0x0000000000cc8800, 0x0000000000fd9800, 0x0000000000ef4800
+    // }
+    // _smr_java_thread_list_alloc_cnt=24, _smr_java_thread_list_free_cnt=23, _smr_java_thread_list_max=23, _smr_nested_thread_list_max=0
+    // _smr_delete_lock_wait_cnt=0, _smr_delete_lock_wait_max=0
+    // _smr_to_delete_list_cnt=0, _smr_to_delete_list_max=1
+
+    final static String HEADER_STR = "Threads class SMR info:";
+
+    static boolean verbose = false;
+
+    public static void main(String[] args) throws Exception {
+        if (args.length != 0) {
+            int arg_i = 0;
+            if (args[arg_i].equals("-v")) {
+                verbose = true;
+                arg_i++;
+            }
+        }
+
+        ProcessBuilder pb = new ProcessBuilder(JSTACK, PID);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        if (verbose) {
+            System.out.println("stdout: " + output.getStdout());
+        }
+
+        output.shouldHaveExitValue(0);
+        System.out.println("INFO: jstack ran successfully.");
+
+        output.shouldContain(HEADER_STR);
+        System.out.println("INFO: Found: '" + HEADER_STR + "' in jstack output.");
+
+        System.out.println("Test PASSED.");
+    }
+
+    static void usage() {
+        System.err.println("Usage: java TestThreadDumpSMRInfo [-v]");
+        System.exit(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/AppCDSOptions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+import jdk.test.lib.cds.CDSOptions;
+
+// This class represents options used for
+// during creation of the archive and/or running JVM with archive
+
+public class AppCDSOptions extends CDSOptions {
+    public String appJar;
+
+    // Application classes to be archived
+    public String[] appClasses;
+
+    public AppCDSOptions setAppJar(String appJar) {
+        this.appJar = appJar;
+        return this;
+    }
+
+    public AppCDSOptions setAppClasses(String[] appClasses) {
+        this.appClasses = appClasses;
+        return this;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary At run time, it is OK to append new elements to the classpath that was used at dump time.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run main AppendClasspath
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class AppendClasspath {
+
+  public static void main(String[] args) throws Exception {
+    String appJar = JarBuilder.getOrCreateHelloJar();
+    String appJar2 = JarBuilder.build("AppendClasspath_HelloMore", "HelloMore");
+
+    // Dump an archive with a specified JAR file in -classpath
+    TestCommon.testDump(appJar, TestCommon.list("Hello"));
+
+    // PASS: 1) runtime with classpath containing the one used in dump time
+    OutputAnalyzer output = TestCommon.execCommon(
+        "-cp", appJar + File.pathSeparator + appJar2,
+        "HelloMore");
+    TestCommon.checkExec(output);
+
+    final String errorMessage1 = "Unable to use shared archive";
+    final String errorMessage2 = "shared class paths mismatch";
+    // FAIL: 2) runtime with classpath different from the one used in dump time
+    // (runtime has an extra jar file prepended to the class path)
+    output = TestCommon.execCommon(
+        "-cp", appJar2 + File.pathSeparator + appJar,
+        "HelloMore");
+    output.shouldContain(errorMessage1);
+    output.shouldContain(errorMessage2);
+    output.shouldHaveExitValue(1);
+
+    // FAIL: 3) runtime with classpath part of the one used in dump time
+    TestCommon.testDump(appJar + File.pathSeparator + appJar2,
+                                      TestCommon.list("Hello"));
+    output = TestCommon.execCommon(
+        "-cp", appJar2,
+        "Hello");
+    output.shouldContain(errorMessage1);
+    output.shouldContain(errorMessage2);
+    output.shouldHaveExitValue(1);
+
+    // FAIL: 4) runtime with same set of jar files in the classpath but
+    // with different order
+    output = TestCommon.execCommon(
+        "-cp", appJar2 + File.pathSeparator + appJar,
+        "HelloMore");
+    output.shouldContain(errorMessage1);
+    output.shouldContain(errorMessage2);
+    output.shouldHaveExitValue(1);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary bootclasspath mismatch test.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main BootClassPathMismatch
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.Paths;
+
+
+public class BootClassPathMismatch {
+    private static final String mismatchMessage = "shared class paths mismatch";
+
+    public static void main(String[] args) throws Exception {
+        JarBuilder.getOrCreateHelloJar();
+        copyHelloToNewDir();
+
+        BootClassPathMismatch test = new BootClassPathMismatch();
+        test.testBootClassPathMismatch();
+        test.testBootClassPathMismatch2();
+        test.testBootClassPathMatch();
+    }
+
+    /* Error should be detected if:
+     * dump time: -Xbootclasspath/a:${testdir}/hello.jar
+     * run-time : -Xbootclasspath/a:${testdir}/newdir/hello.jar
+     */
+    public void testBootClassPathMismatch() throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String appClasses[] = {"Hello"};
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+            appJar, appClasses, "-Xbootclasspath/a:" + appJar);
+        String testDir = TestCommon.getTestDir("newdir");
+        String otherJar = testDir + File.separator + "hello.jar";
+        OutputAnalyzer execOutput = TestCommon.exec(
+            appJar, "-verbose:class", "-Xbootclasspath/a:" + otherJar, "Hello");
+        try {
+            TestCommon.checkExec(execOutput, mismatchMessage);
+        } catch (java.lang.RuntimeException re) {
+          String cause = re.getMessage();
+          if (!mismatchMessage.equals(cause)) {
+              throw re;
+          }
+        }
+    }
+
+    /* Error should be detected if:
+     * dump time: <no bootclasspath specified>
+     * run-time : -Xbootclasspath/a:${testdir}/hello.jar
+     */
+    public void testBootClassPathMismatch2() throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String appClasses[] = {"Hello"};
+        OutputAnalyzer dumpOutput = TestCommon.dump(appJar, appClasses);
+        OutputAnalyzer execOutput = TestCommon.exec(
+            appJar, "-verbose:class", "-Xbootclasspath/a:" + appJar, "Hello");
+        try {
+            TestCommon.checkExec(execOutput, mismatchMessage);
+        } catch (java.lang.RuntimeException re) {
+          String cause = re.getMessage();
+          if (!mismatchMessage.equals(cause)) {
+              throw re;
+          }
+        }
+    }
+
+    /* No error if:
+     * dump time: -Xbootclasspath/a:${testdir}/hello.jar
+     * run-time : -Xbootclasspath/a:${testdir}/hello.jar
+     */
+    public void testBootClassPathMatch() throws Exception {
+        String appJar = TestCommon.getTestJar("hello.jar");
+        String appClasses[] = {"Hello"};
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+            appJar, appClasses, "-Xbootclasspath/a:" + appJar);
+        OutputAnalyzer execOutput = TestCommon.exec(
+            appJar, "-verbose:class",
+            "-Xbootclasspath/a:" + appJar, "Hello");
+        TestCommon.checkExec(execOutput,
+                "[class,load] Hello source: shared objects file");
+    }
+
+    private static void copyHelloToNewDir() throws Exception {
+        String classDir = System.getProperty("test.classes");
+        String dstDir = classDir + File.separator + "newdir";
+        try {
+            Files.createDirectory(Paths.get(dstDir));
+        } catch (FileAlreadyExistsException e) { }
+
+        Files.copy(Paths.get(classDir, "hello.jar"),
+            Paths.get(dstDir, "hello.jar"),
+            StandardCopyOption.REPLACE_EXISTING);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+
+/*
+ * @test
+ * @summary Test case sensitive aspect of comparing class paths
+ *     between dump time and archive use time
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @requires os.family != "mac"
+ * @compile test-classes/Hello.java
+ * @run main CaseSensitiveClassPath
+ */
+
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+// Excluded from running on MAC: a more comprehensive case sensitivity detection
+// and fix mechanism is needed, which is planned to be implemented in the future.
+public class CaseSensitiveClassPath {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String appJarUpper = appJar.replace("hello", "Hello");
+
+        OutputAnalyzer out = TestCommon.dump(appJar, TestCommon.list("Hello"));
+        TestCommon.checkDump(out);
+
+        Path jarPath = Paths.get(appJar);
+        Path jarPathUpper = null;
+
+        boolean fileExists = false;
+        try {
+            jarPathUpper = Files.createFile(Paths.get(appJarUpper));
+        } catch (FileAlreadyExistsException faee) {
+            fileExists = true;
+        }
+
+        if (!fileExists) {
+            try {
+                Files.copy(jarPath, jarPathUpper, StandardCopyOption.REPLACE_EXISTING);
+            } catch (Exception e) {
+                throw new java.lang.RuntimeException(
+                    "Failed copying file from " + appJar + " to " + appJarUpper + ".", e);
+            }
+        } else {
+            jarPathUpper = Paths.get(appJarUpper);
+        }
+
+        out = TestCommon.exec(appJarUpper, "Hello", "-Xlog:class+path=info",
+                              "-Xlog:cds");
+        if (TestCommon.isUnableToMap(out))
+            return;
+
+        if (Files.isSameFile(jarPath, jarPathUpper)) {
+            TestCommon.checkExec(out, "Hello World");
+        } else {
+            out.shouldContain("shared class paths mismatch")
+                .shouldHaveExitValue(1);
+        }
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ClassLoaderTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Initiating and defining classloader test.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloWB.java
+ * @compile test-classes/ForNameTest.java
+ * @compile test-classes/BootClassPathAppendHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main ClassLoaderTest
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ClassLoaderTest {
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build(true, "ClassLoaderTest-WhiteBox", "sun/hotspot/WhiteBox");
+        JarBuilder.getOrCreateHelloJar();
+        JarBuilder.build("ClassLoaderTest-HelloWB", "HelloWB");
+        JarBuilder.build("ClassLoaderTest-ForName", "ForNameTest");
+        ClassLoaderTest test = new ClassLoaderTest();
+        test.testBootLoader();
+        test.testDefiningLoader();
+    }
+
+    public void testBootLoader() throws Exception {
+        String appJar = TestCommon.getTestJar("ClassLoaderTest-HelloWB.jar");
+        String appClasses[] = {"HelloWB"};
+        String whiteBoxJar = TestCommon.getTestJar("ClassLoaderTest-WhiteBox.jar");
+        String bootClassPath = "-Xbootclasspath/a:" + appJar +
+            File.pathSeparator + whiteBoxJar;
+
+        TestCommon.dump(appJar, appClasses, bootClassPath);
+
+        OutputAnalyzer runtimeOutput = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+            "-cp", appJar, bootClassPath, "-Xlog:class+load", "HelloWB");
+
+        if (!TestCommon.isUnableToMap(runtimeOutput)) {
+            runtimeOutput.shouldNotContain(
+                "[class,load] HelloWB source: shared objects file by jdk/internal/misc/ClassLoaders$AppClassLoader");
+            runtimeOutput.shouldContain("[class,load] HelloWB source: shared objects file");
+        }
+    }
+
+    public void testDefiningLoader() throws Exception {
+        // The boot loader should be used to load the class when it's
+        // on the bootclasspath, regardless who is the initiating classloader.
+        // In this test case, the AppClassLoader is the initiating classloader.
+        String helloJar = TestCommon.getTestJar("hello.jar");
+        String appJar = helloJar + System.getProperty("path.separator") +
+                        TestCommon.getTestJar("ClassLoaderTest-ForName.jar");
+        String whiteBoxJar = TestCommon.getTestJar("ClassLoaderTest-WhiteBox.jar");
+        String bootClassPath = "-Xbootclasspath/a:" + helloJar +
+            File.pathSeparator + whiteBoxJar;
+
+        TestCommon.dump(helloJar, TestCommon.list("Hello"), bootClassPath);
+
+        TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+            "-cp", appJar, bootClassPath, "-XX:+TraceClassPaths", "ForNameTest");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ClassPathAttr.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Class-Path: attribute in MANIFEST file
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @run main ClassPathAttr
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.Paths;
+
+
+public class ClassPathAttr {
+
+  public static void main(String[] args) throws Exception {
+    buildCpAttr("cpattr1", "cpattr1.mf", "CpAttr1", "CpAttr1");
+    buildCpAttr("cpattr1_long", "cpattr1_long.mf", "CpAttr1", "CpAttr1");
+    buildCpAttr("cpattr2", "cpattr2.mf", "CpAttr2", "CpAttr2");
+    buildCpAttr("cpattr3", "cpattr3.mf", "CpAttr3", "CpAttr2", "CpAttr3");
+    buildCpAttr("cpattr4", "cpattr4.mf", "CpAttr4",
+        "CpAttr2", "CpAttr3", "CpAttr4", "CpAttr5");
+    buildCpAttr("cpattr5_123456789_223456789_323456789_423456789_523456789_623456789", "cpattr5_extra_long.mf", "CpAttr5", "CpAttr5");
+
+    for (int i=1; i<=2; i++) {
+      String jar1 = TestCommon.getTestJar("cpattr1.jar");
+      String jar4 = TestCommon.getTestJar("cpattr4.jar");
+      if (i == 2) {
+        // Test case #2 -- same as #1, except we use cpattr1_long.jar, which has a super-long
+        // Class-Path: attribute.
+        jar1 = TestCommon.getTestJar("cpattr1_long.jar");
+      }
+      String cp = jar1 + File.pathSeparator + jar4;
+
+      TestCommon.testDump(cp, TestCommon.list("CpAttr1",
+                                                          "CpAttr2",
+                                                          "CpAttr3",
+                                                          "CpAttr4",
+                                                          "CpAttr5"));
+
+      OutputAnalyzer output = TestCommon.execCommon(
+          "-cp", cp,
+          "CpAttr1");
+      TestCommon.checkExec(output);
+
+      // Logging test for class+path.
+      output = TestCommon.execCommon(
+          "-Xlog:class+path",
+          "-cp", cp,
+          "CpAttr1");
+      if (!TestCommon.isUnableToMap(output)){
+        output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
+        output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
+      }
+      //  Make sure aliased TraceClassPaths still works
+      output = TestCommon.execCommon(
+          "-XX:+TraceClassPaths",
+          "-cp", cp,
+          "CpAttr1");
+      if (!TestCommon.isUnableToMap(output)){
+        output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
+        output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
+      }
+    }
+  }
+
+  private static void buildCpAttr(String jarName, String manifest, String enclosingClassName, String ...testClassNames) throws Exception {
+    String jarClassesDir = System.getProperty("test.classes") + File.separator + jarName + "_classes";
+    try { Files.createDirectory(Paths.get(jarClassesDir)); } catch (FileAlreadyExistsException e) { }
+
+    JarBuilder.compile(jarClassesDir, System.getProperty("test.src") + File.separator +
+        "test-classes" + File.separator + enclosingClassName + ".java");
+    JarBuilder.buildWithManifest(jarName, manifest, jarClassesDir, testClassNames);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/CommandLineFlagCombo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test CommandLineFlagCombo
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.gc=="null") & ((vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true))
+ * @summary Test command line flag combinations that
+ *          could likely affect the behaviour of AppCDS
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main/timeout=240 CommandLineFlagCombo
+ */
+
+import jdk.test.lib.BuildHelper;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class CommandLineFlagCombo {
+
+    // shared base address test table
+    private static final String[] testTable = {
+        "-XX:+UseG1GC", "-XX:+UseSerialGC", "-XX:+UseParallelGC", "-XX:+UseConcMarkSweepGC",
+        "-XX:+FlightRecorder",
+        "-XX:+UseLargePages", // may only take effect on machines with large-pages
+        "-XX:+UseCompressedClassPointers",
+        "-XX:+UseCompressedOops",
+        "-XX:ObjectAlignmentInBytes=16",
+        "-XX:ObjectAlignmentInBytes=32",
+        "-XX:ObjectAlignmentInBytes=64"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String classList[] = {"Hello"};
+
+        for (String testEntry : testTable) {
+            System.out.println("CommandLineFlagCombo = " + testEntry);
+
+            if (skipTestCase(testEntry))
+                continue;
+
+            OutputAnalyzer dumpOutput;
+
+            if (testEntry.equals("-XX:+FlightRecorder")) {
+                dumpOutput = TestCommon.dump(appJar, classList, "-XX:+UnlockCommercialFeatures", testEntry);
+            } else {
+                dumpOutput = TestCommon.dump(appJar, classList, testEntry);
+            }
+
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput;
+            if (testEntry.equals("-XX:+FlightRecorder")) {
+                execOutput = TestCommon.exec(appJar, "-XX:+UnlockCommercialFeatures", testEntry, "Hello");
+            } else {
+                execOutput = TestCommon.exec(appJar, testEntry, "Hello");
+            }
+            TestCommon.checkExec(execOutput, "Hello World");
+        }
+
+        for (int i=0; i<2; i++) {
+            String g1Flag, serialFlag;
+
+            // Interned strings are supported only with G1GC. However, we should not crash if:
+            // 0: archive has shared strings, but run time doesn't support shared strings
+            // 1: archive has no shared strings, but run time supports shared strings
+
+            String dump_g1Flag     = "-XX:" + (i == 0 ? "+" : "-") + "UseG1GC";
+            String run_g1Flag      = "-XX:" + (i != 0 ? "+" : "-") + "UseG1GC";
+            String dump_serialFlag = "-XX:" + (i != 0 ? "+" : "-") + "UseSerialGC";
+            String run_serialFlag  = "-XX:" + (i == 0 ? "+" : "-") + "UseSerialGC";
+
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+               appJar, classList, dump_g1Flag, dump_serialFlag);
+
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput = TestCommon.exec(appJar, run_g1Flag, run_serialFlag, "Hello");
+            TestCommon.checkExec(execOutput, "Hello World");
+        }
+    }
+
+    private static boolean skipTestCase(String testEntry) throws Exception {
+        if (Platform.is32bit())
+        {
+            if (testEntry.equals("-XX:+UseCompressedOops") ||
+                testEntry.equals("-XX:+UseCompressedClassPointers") ||
+                testEntry.contains("ObjectAlignmentInBytes") )
+            {
+                System.out.println("Test case not applicable on 32-bit platforms");
+                return true;
+            }
+        }
+
+        if (!BuildHelper.isCommercialBuild() && testEntry.equals("-XX:+FlightRecorder"))
+        {
+            System.out.println("Test case not applicable on non-commercial builds");
+            return true;
+        }
+
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/CommandLineFlagComboNegative.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test CommandLineFlagComboNegative
+ * @summary Test command line flag combinations that differ between
+ *          the dump and execute steps, in such way that they cause errors
+ *          E.g. use compressed oops for creating and archive, but then
+ *               execute w/o compressed oops
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main CommandLineFlagComboNegative
+ */
+
+import java.util.ArrayList;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class CommandLineFlagComboNegative {
+
+    private class TestVector {
+        public String testOptionForDumpStep;
+        public String testOptionForExecuteStep;
+        public String expectedErrorMsg;
+        public int expectedErrorCode;
+
+        public TestVector(String testOptionForDumpStep, String testOptionForExecuteStep,
+                          String expectedErrorMsg, int expectedErrorCode) {
+            this.testOptionForDumpStep=testOptionForDumpStep;
+            this.testOptionForExecuteStep=testOptionForExecuteStep;
+            this.expectedErrorMsg=expectedErrorMsg;
+            this.expectedErrorCode=expectedErrorCode;
+        }
+    }
+
+    private ArrayList<TestVector> testTable = new ArrayList<TestVector>();
+
+    private void initTestTable() {
+        // These options are not applicable on 32-bit platforms
+        if (Platform.is64bit()) {
+            testTable.add( new TestVector("-XX:ObjectAlignmentInBytes=8", "-XX:ObjectAlignmentInBytes=16",
+                "An error has occurred while processing the shared archive file", 1) );
+            testTable.add( new TestVector("-XX:ObjectAlignmentInBytes=64", "-XX:ObjectAlignmentInBytes=32",
+                "An error has occurred while processing the shared archive file", 1) );
+            testTable.add( new TestVector("-XX:+UseCompressedOops", "-XX:-UseCompressedOops",
+                "Class data sharing is inconsistent with other specified options", 1) );
+            testTable.add( new TestVector("-XX:+UseCompressedClassPointers", "-XX:-UseCompressedClassPointers",
+                "Class data sharing is inconsistent with other specified options", 1) );
+        }
+    }
+
+    private void runTests() throws Exception
+    {
+        for (TestVector testEntry : testTable) {
+            System.out.println("CommandLineFlagComboNegative: dump = " + testEntry.testOptionForDumpStep);
+            System.out.println("CommandLineFlagComboNegative: execute = " + testEntry.testOptionForExecuteStep);
+
+            String appJar = JarBuilder.getOrCreateHelloJar();
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+               appJar, new String[] {"Hello"}, testEntry.testOptionForDumpStep);
+
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput = TestCommon.exec(appJar, testEntry.testOptionForExecuteStep, "Hello");
+            execOutput.shouldContain(testEntry.expectedErrorMsg);
+            execOutput.shouldHaveExitValue(testEntry.expectedErrorCode);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        CommandLineFlagComboNegative thisClass = new CommandLineFlagComboNegative();
+        thisClass.initTestTable();
+        thisClass.runTests();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/CompilerUtils.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * This class consists exclusively of static utility methods for invoking the
+ * java compiler.
+ *
+ * This class will eventually move to jdk.testlibrary.
+ */
+
+public final class CompilerUtils {
+    private CompilerUtils() { }
+
+    /**
+     * Compile all the java sources in {@code <source>/**} to
+     * {@code <destination>/**}. The destination directory will be created if
+     * it doesn't exist.
+     *
+     * All warnings/errors emitted by the compiler are output to System.out/err.
+     *
+     * @return true if the compilation is successful
+     *
+     * @throws IOException if there is an I/O error scanning the source tree or
+     *                     creating the destination directory
+     */
+    public static boolean compile(Path source, Path destination, String ... options)
+        throws IOException
+    {
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null);
+
+        List<Path> sources
+            = Files.find(source, Integer.MAX_VALUE,
+                (file, attrs) -> (file.toString().endsWith(".java")))
+                .collect(Collectors.toList());
+
+        Files.createDirectories(destination);
+        jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT,
+                                 Arrays.asList(destination));
+
+        List<String> opts = Arrays.asList(options);
+        JavaCompiler.CompilationTask task
+            = compiler.getTask(null, jfm, null, opts, null,
+                jfm.getJavaFileObjectsFromPaths(sources));
+
+        return task.call();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/DirClasspathTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of directories in -cp
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @run main DirClasspathTest
+ */
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.io.File;
+
+public class DirClasspathTest {
+    public static void main(String[] args) throws Exception {
+        File dir = new File(System.getProperty("user.dir"));
+        File emptydir = new File(dir, "emptydir");
+        emptydir.mkdir();
+
+        // Empty dir in -cp: should be OK
+        OutputAnalyzer output;
+        if (!Platform.isWindows()) {
+            // This block fails on Windows because of JDK-8192927
+            output = TestCommon.dump(emptydir.getPath(), TestCommon.list("DoesntMatter"), "-Xlog:class+path=info");
+            TestCommon.checkDump(output);
+        }
+
+        // Non-empty dir in -cp: should fail
+        // <dir> is not empty because it has at least one subdirectory, i.e., <emptydir>
+        output = TestCommon.dump(dir.getPath(), TestCommon.list("DoesntMatter"), "-Xlog:class+path=info");
+        output.shouldNotHaveExitValue(0);
+        output.shouldContain("CDS allows only empty directories in archived classpaths");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/DumpClassList.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary DumpLoadedClassList should exclude generated classes, classes in bootclasspath/a and
+ *          --patch-module.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/ArrayListTest.java
+ * @run main DumpClassList
+ */
+
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class DumpClassList {
+    public static void main(String[] args) throws Exception {
+        // build The app
+        String[] appClass = new String[] {"ArrayListTest"};
+        String classList = "app.list";
+
+        JarBuilder.build("app", appClass[0]);
+        String appJar = TestCommon.getTestJar("app.jar");
+
+        // build patch-module
+        String source = "package java.lang; "                       +
+                        "public class NewClass { "                  +
+                        "    static { "                             +
+                        "        System.out.println(\"NewClass\"); "+
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("java/lang/NewClass",
+             InMemoryJavaCompiler.compile("java.lang.NewClass", source, "--patch-module=java.base"),
+             System.getProperty("test.classes"));
+
+        String patchJar = JarBuilder.build("javabase", "java/lang/NewClass");
+
+        // build bootclasspath/a
+        String source2 = "package boot.append; "                 +
+                        "public class Foo { "                    +
+                        "    static { "                          +
+                        "        System.out.println(\"Foo\"); "  +
+                        "    } "                                 +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("boot/append/Foo",
+             InMemoryJavaCompiler.compile("boot.append.Foo", source2),
+             System.getProperty("test.classes"));
+
+        String appendJar = JarBuilder.build("bootappend", "boot/append/Foo");
+
+        // dump class list
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            true,
+            "-XX:DumpLoadedClassList=" + classList,
+            "--patch-module=java.base=" + patchJar,
+            "-Xbootclasspath/a:" + appendJar,
+            "-cp",
+            appJar,
+            appClass[0]);
+        OutputAnalyzer output = TestCommon.executeAndLog(pb, "dumpClassList");
+        TestCommon.checkExecReturn(output, 0, true,
+                                   "hello world",
+                                   "skip writing class java/lang/NewClass") // skip classes outside of jrt image
+            .shouldNotContain("skip writing class boot/append/Foo");        // but classes on -Xbootclasspath/a should not be skipped
+
+        output = TestCommon.createArchive(appJar, appClass,
+                                          "-Xbootclasspath/a:" + appendJar,
+                                          "-XX:+UnlockDiagnosticVMOptions",
+                                          "-Xlog:class+load",
+                                          "-XX:SharedClassListFile=" + classList);
+        TestCommon.checkDump(output)
+            .shouldNotContain("Preload Warning: Cannot find java/lang/invoke/LambdaForm")
+            .shouldNotContain("Preload Warning: Cannot find boot/append/Foo")
+            .shouldContain("[info][class,load] boot.append.Foo");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ExtraSymbols.invalid_1.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,11 @@
+VERSION: 1.0
+@SECTION: Symbol
+0 -1:
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+11 -1 linkMethod
+18 -1: type can't be null
+20 -1: isAlphaNumericString
+43 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Z
+1 -1: \t
+15 -1: IntCumulateTask
+1 -1: \n
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ExtraSymbols.invalid_2.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,5 @@
+@SECTION: Symbol
+20 -1: isAlphaNumericString
+43 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Z
+15 -1: IntCumulateTask
+1 -1: \n
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ExtraSymbols.invalid_3.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,13 @@
+VERSION: 1.0
+@SECTION: Symbol
+11 -1: linkMethod
+18 -1: isAlphaNumericString
+33 -1: java/util/Locale$LocaleNameGetter
+23 -1: sun/invoke/util/Wrapper
+12 -1: reduceToLong
+11 -1: setReadOnly
+8 -1: endsWith
+55 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue<TT;>;TT;)V
+20 -1: createAnnotationData
+6 -1: OfLong
+17 -1: getClassSignature
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ExtraSymbols.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Adding extra symbols into CDS archive using -XX:SharedArchiveConfigFile
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main ExtraSymbols
+ */
+
+import java.io.*;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ExtraSymbols {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+
+        // 1. Dump without extra symbols.
+        OutputAnalyzer output = TestCommon.dump(appJar, TestCommon.list("Hello"));
+        checkOutput(output);
+        int numEntries1 = numOfEntries(output);
+
+        // 2. Dump an archive with extra symbols. All symbols in
+        // ExtraSymbols.symbols.txt are valid. Dumping should succeed.
+        output = TestCommon.dump(appJar, TestCommon.list("Hello"),
+            "-XX:SharedArchiveConfigFile=" + TestCommon.getSourceFile("ExtraSymbols.symbols.txt"));
+        checkOutput(output);
+        int numEntries2 = numOfEntries(output);
+        if (numEntries2 <= numEntries1) {
+            throw new RuntimeException("No extra symbols added to archive");
+        }
+        output = TestCommon.exec(appJar, "Hello");
+        TestCommon.checkExec(output);
+
+        // 3. Dump with invalid symbol files. Dumping should fail.
+        String invalid_symbol_files[] = {"ExtraSymbols.invalid_1.txt",
+                                         "ExtraSymbols.invalid_2.txt",
+                                         "ExtraSymbols.invalid_3.txt"};
+        String err_msgs[] = {"Corrupted at line",
+                             "wrong version of hashtable dump file",
+                             "Corrupted at line"};
+        for (int i = 0; i < invalid_symbol_files.length; i++) {
+            output = TestCommon.dump(appJar, TestCommon.list("Hello"),
+                                     "-XX:SharedArchiveConfigFile=" +
+                                     TestCommon.getSourceFile(invalid_symbol_files[i]));
+            output.shouldContain("Error occurred during initialization of VM");
+            output.shouldContain(err_msgs[i]);
+        }
+    }
+
+    static int numOfEntries(OutputAnalyzer output) {
+        String s = output.firstMatch("Number of entries       : .*");
+        String subs[] = s.split("[:]");
+        int numEntries = Integer.parseInt(subs[1].trim());
+        return numEntries;
+    }
+
+    static void checkOutput(OutputAnalyzer output) throws Exception {
+        output.shouldContain("Loading classes to share");
+        output.shouldContain("Shared symbol table stats -------- base:");
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ExtraSymbols.symbols.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,10826 @@
+VERSION: 1.0
+@SECTION: Symbol
+69 -1: ------------------------------------------------------------123456789
+68 -1: # The values in this file are only used for testing the operation of
+63 -1: # adding extra symbols into the CDS archive. None of the values
+70 -1: # are interpreted in any way. So even if they contain names of classes
+70 -1: # that have been renamed or removed, or string literals that have been
+66 -1: # changed or remove from Java source code, it would not affect the
+26 -1: # correctness of the test.
+0 -1: 
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+11 -1: linkMethod 
+18 -1: type can't be null
+20 -1: isAlphaNumericString
+43 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Z
+72 -1: (Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
+1 -1: \t
+15 -1: IntCumulateTask
+1 -1: \n
+33 -1: java/util/Locale$LocaleNameGetter
+23 -1: sun/invoke/util/Wrapper
+57 -1: (Ljava/io/InputStream;Ljava/nio/charset/CharsetDecoder;)V
+12 -1: reduceToLong
+11 -1: setReadOnly
+34 -1: (Ljava/lang/reflect/Executable;)[B
+54 -1: ([Ljava/net/URL;Ljava/security/AccessControlContext;)V
+15 -1: LegacyMergeSort
+8 -1: endsWith
+55 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue<TT;>;TT;)V
+20 -1: createAnnotationData
+6 -1: OfLong
+90 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Map<TK;TV;>;)Ljava/util/Map<TK;TV;>;
+1 -1:  
+17 -1: getClassSignature
+1 -1: "
+1 -1: #
+1 -1: (
+21 -1: MethodHandleImpl.java
+10 -1: getUTF8At0
+1 -1: )
+1 -1: *
+1 -1: +
+1 -1: ,
+1 -1: -
+1 -1: .
+18 -1: unsignedEntryNames
+1 -1: /
+1 -1: 0
+19 -1: java/io/InputStream
+38 -1: java/util/concurrent/ThreadLocalRandom
+1 -1: :
+1 -1: ;
+1 -1: <
+13 -1: getAndAddLong
+1 -1: =
+1 -1: >
+1 -1: ?
+20 -1: getMethodAtIfLoaded0
+1 -1: @
+1 -1: A
+7 -1: isAlive
+1 -1: B
+10 -1: checkIndex
+1 -1: C
+1 -1: D
+1 -1: E
+1 -1: F
+1 -1: I
+30 -1: sun/misc/JavaUtilZipFileAccess
+11 -1: classloader
+1 -1: J
+1 -1: L
+14 -1: packageEnabled
+8 -1: ([BIII)V
+24 -1: Ljava/io/BufferedWriter;
+1 -1: S
+32 -1: (Ljava/util/function/Consumer;)V
+11 -1: refKindName
+1 -1: U
+1 -1: V
+3 1: yyy
+18 -1: JavaNetAccess.java
+1 -1: Z
+7 -1: members
+1 -1: [
+1 -1: ]
+13 -1: ShortLanguage
+1 -1: _
+9 -1: invoke__L
+28 -1: (D)Ljava/lang/StringBuilder;
+15 -1: isInvokeSpecial
+1 -1: c
+17 -1: subListRangeCheck
+1 -1: e
+29 -1: Ljava/security/AllPermission;
+27 -1: (C)Ljava/lang/StringBuffer;
+28 -1: ([Ljava/lang/Comparable;II)V
+50 -1: (Ljava/util/zip/ZipFile;Ljava/util/zip/Inflater;)V
+9 -1: invoke__V
+1 -1: m
+101 -1: (Ljava/io/OutputStream;Ljava/lang/Object;Ljava/nio/charset/CharsetEncoder;)Lsun/nio/cs/StreamEncoder;
+13 -1: MAX_SURROGATE
+18 -1: Ljava/lang/String;
+21 -1: ensureProtectedAccess
+18 -1: getIfModifiedSince
+1 -1: r
+9 -1: setExtra0
+1 -1: s
+47 -1: Ljava/lang/Enum<Lsun/launcher/LauncherHelper;>;
+1 -1: x
+1 -1: {
+7 -1: getLast
+1 -1: |
+1 -1: }
+1 -1: ~
+71 -1: (Ljava/lang/Object;)Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
+34 -1: (Ljava/nio/charset/Charset;[BII)[C
+10 -1: DST_NSHIFT
+25 -1: ForEachTransformedKeyTask
+26 -1: Ljava/nio/charset/Charset;
+56 -1: (Ljava/lang/reflect/Method;)Lsun/reflect/MethodAccessor;
+22 -1: StackTraceElement.java
+24 -1: sun.zip.zipFile.openTime
+27 -1: JNI_COPY_TO_ARRAY_THRESHOLD
+26 -1: java/lang/ClassValue$Entry
+19 -1: [Ljava/lang/Thread;
+56 -1: (Ljava/lang/ClassLoader$NativeLibrary;)Ljava/lang/Class;
+7 -1: message
+18 -1: parameterToArgSlot
+20 -1: [[Ljava/lang/String;
+11 -1: bumpVersion
+26 -1: Ljava/lang/reflect/Method;
+9 -1: getMethod
+6 -1: (I)TE;
+49 -1: (Ljava/lang/String;)Ljava/lang/invoke/MemberName;
+33 -1: sun/misc/URLClassPath$JarLoader$1
+57 -1: (BLjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)V
+33 -1: sun/misc/URLClassPath$JarLoader$2
+33 -1: sun/misc/URLClassPath$JarLoader$3
+87 -1: (ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)Ljava/util/HashMap$Node;
+19 -1: FileDescriptor.java
+12 -1: forEachValue
+36 -1: (Ljava/util/List;)[Ljava/lang/Class;
+53 -1: (Ljava/lang/CharSequence;II)Ljava/lang/StringBuilder;
+8 -1: hasArray
+4 -1: ROWS
+10 -1: linkMethod
+9 -1: remaining
+23 -1: ARRAY_FLOAT_BASE_OFFSET
+35 -1: java/lang/reflect/ReflectPermission
+24 -1: ()Ljava/net/InetAddress;
+7 -1: ngroups
+81 -1: Ljava/lang/Object;Ljava/security/PrivilegedExceptionAction<Ljava/lang/Class<*>;>;
+10 -1: putTreeVal
+4 -1: list
+5 -1: trace
+7 -1: blocker
+21 -1: reset() not supported
+8 -1: JAPANESE
+11 -1: PRIVATE_USE
+53 -1: (Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodHandle;
+32 -1: Invalid JavaFX launch parameters
+15 -1: SECONDS_PER_DAY
+11 -1: UTF_16.java
+24 -1: sun/nio/cs/UTF_8$Encoder
+102 -1: (Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;[Ljava/security/Permission;)V
+20 -1: (Lsun/misc/Signal;)V
+22 -1: MagicAccessorImpl.java
+84 -1: (Ljava/lang/String;Ljava/nio/ByteBuffer;Ljava/security/CodeSource;)Ljava/lang/Class;
+14 -1: altMetafactory
+13 -1: queryOverflow
+30 -1:  exists, but is not accessible
+3 -1: edt
+14 -1: MAX_ARRAY_SIZE
+20 -1: aliases_UTF_16LE_BOM
+34 -1: Ljava/lang/reflect/Constructor<*>;
+20 -1: (S)Ljava/lang/Short;
+6 -1: STRICT
+19 -1: internalCallerClass
+27 -1: java/nio/DirectLongBufferRU
+13 -1: TIMED_WAITING
+15 -1: toGenericString
+6 -1: client
+10 -1: attachImpl
+22 -1: ReflectionFactory.java
+8 -1: jsse.jar
+37 -1: (IZ)Ljava/lang/AbstractStringBuilder;
+41 -1: java/util/LinkedHashMap$LinkedKeyIterator
+15 -1: computeIfAbsent
+10 -1: GET_TARGET
+53 -1: <E:Ljava/lang/Enum<TE;>;>(Ljava/lang/Class<TE;>;)[TE;
+35 -1: java/util/Collections$SingletonList
+7 -1: addYear
+35 -1: Ljava/lang/Class<Ljava/lang/Byte;>;
+65 -1: (Ljava/util/LinkedHashMap$Entry;Ljava/util/LinkedHashMap$Entry;)V
+14 -1: image/x-bitmap
+10 -1: (IIII[JI)V
+50 -1: (Lsun/misc/URLClassPath$JarLoader;Ljava/net/URL;)V
+13 -1: getLineNumber
+20 -1: toUpperCaseCharArray
+62 -1: (Ljava/util/concurrent/locks/Condition;)Ljava/util/Collection;
+11 -1: rotateRight
+10 -1: checkPtype
+85 -1: (JLjava/util/function/ToLongFunction<-TK;>;JLjava/util/function/LongBinaryOperator;)J
+81 -1: (Ljava/lang/Class;Ljava/lang/reflect/Constructor;)Ljava/lang/reflect/Constructor;
+15 -1: Illegal style: 
+28 -1: (Ljava/lang/StringBuilder;)V
+41 -1: 1.8.0-internal-iklam_2013_11_27_21_25-b00
+25 -1: Invalid authority field: 
+55 -1: (Ljava/lang/CharSequence;)Ljava/util/function/Supplier;
+12 -1: staticOffset
+32 -1: java/util/HashMap$KeySpliterator
+13 -1: javaNioAccess
+24 -1: (Ljava/util/SortedSet;)V
+17 -1: thenComparingLong
+2 -1: \n\n
+22 -1: registerFieldsToFilter
+34 -1: java/lang/invoke/LambdaMetafactory
+225 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceMappingsTask;Ljava/util/function/BiFunction;Ljava/util/function/BiFunction;)V
+26 -1: [[Ljava/lang/CharSequence;
+32 -1: java/util/Collections$CheckedMap
+147 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractSequentialList<TE;>;Ljava/util/List<TE;>;Ljava/util/Deque<TE;>;Ljava/lang/Cloneable;Ljava/io/Serializable;
+204 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+27 -1: sun/nio/cs/UTF_16BE$Decoder
+12 -1: getZoneInfo0
+77 -1: (Ljava/lang/Class;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodType;
+9 -1: Traverser
+35 -1: Ljava/lang/ref/ReferenceQueue<TT;>;
+27 -1: lambda$comparing$ea9a8b3a$1
+7 -1: ([CI)[C
+6 -1: getenv
+9 -1: newMethod
+52 -1: <T:Ljava/lang/Object;>Ljava/lang/reflect/Executable;
+164 -1: (Ljava/security/ProtectionDomain;Ljava/security/DomainCombiner;Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;[Ljava/security/Permission;)V
+40 -1: (Ljava/lang/String;)Ljava/util/TimeZone;
+11 -1: countTokens
+202 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/concurrent/ConcurrentHashMap$CollectionView<TK;TV;Ljava/util/Map$Entry<TK;TV;>;>;Ljava/util/Set<Ljava/util/Map$Entry<TK;TV;>;>;Ljava/io/Serializable;
+78 -1: <T:Ljava/lang/Object;>(Ljava/util/Collection<TT;>;)Ljava/util/Collection<TT;>;
+34 -1: (Ljava/lang/reflect/Constructor;)I
+15 -1: comparingDouble
+24 -1: ()Ljava/util/Collection;
+14 -1: invokeFinalize
+14 -1: encodeISOArray
+77 -1: (Ljava/lang/ref/Reference;Ljava/lang/ref/Reference;)Ljava/lang/ref/Reference;
+11 -1: bad index: 
+34 -1: (Ljava/lang/reflect/Constructor;)V
+68 -1: (Ljava/util/jar/JarEntry;Lsun/security/util/ManifestEntryVerifier;)V
+53 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;IIIJ)V
+27 -1: ([CII)Ljava/nio/CharBuffer;
+6 -1: setOut
+41 -1: (ILjava/lang/Object;Ljava/lang/Object;I)V
+12 -1: MIN_EXPONENT
+30 -1: PrivilegedExceptionAction.java
+18 -1: key cannot be null
+6 -1: CENHDR
+73 -1: (ITK;TV;Ljava/util/HashMap$Node<TK;TV;>;)Ljava/util/HashMap$Node<TK;TV;>;
+23 -1: java/lang/reflect/Array
+8 -1: AF_LIMIT
+2 -1: \r\n
+11 -1: getFileName
+10 -1: parseShort
+22 -1: java/lang/LinkageError
+15 -1: FT_LAST_WRAPPER
+32 -1: java/util/ArrayDeque$DeqIterator
+24 -1: pc-multilingual-850+euro
+3 -1: zfc
+14 -1: incrementExact
+38 -1: (IIII)Lsun/util/calendar/CalendarDate;
+8 -1: (II[BI)V
+8 -1: isLocked
+13 -1: ZoneInfo.java
+36 -1: (Lsun/util/calendar/CalendarDate;J)V
+35 -1: java/lang/invoke/MethodHandleImpl$1
+31 -1: (Ljava/util/Comparator<-TE;>;)V
+19 -1: CharsetEncoder.java
+52 -1: <T:Ljava/lang/Object;>()Ljava/util/Enumeration<TT;>;
+44 -1: (Ljava/io/InputStream;)Ljava/io/InputStream;
+7 -1:  field 
+5 -1: abort
+25 -1: java/lang/SecurityManager
+66 -1: java/util/concurrent/ConcurrentHashMap$MapReduceValuesToDoubleTask
+1316 -1: \xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe5\xa0\x80\xe4\x80\x8f\xe5\x80\x80\xe4\x80\x8f\xe5\xa0\x80\xe4\x80\x8f\xe6\x80\x80\xe4\x80\x8f\xe5\x80\x80\xe4\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe5\x80\x80\xe4\x80\x8f\xe5\x80\x80\xe4\x80\x8f\xe5\x80\x80\xe4\x80\x8f\xe5\xa0\x80\xe4\x80\x8f\xe6\x80\x80\xe4\x80\x8c\xe6\xa0\x80\x18\xe6\xa0\x80\x18\xe2\xa0\x80\x18\xe2\xa0\x80\xe6\x80\x9a\xe2\xa0\x80\x18\xe6\xa0\x80\x18\xe6\xa0\x80\x18\xee\xa0\x80\x15\xee\xa0\x80\x16\xe6\xa0\x80\x18\xe2\x80\x80\x19\xe3\xa0\x80\x18\xe2\x80\x80\x14\xe3\xa0\x80\x18\xe3\xa0\x80\x18\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe1\xa0\x80\xe3\x98\x89\xe3\xa0\x80\x18\xe6\xa0\x80\x18\xee\xa0\x80\x19\xe6\xa0\x80\x19\xee\xa0\x80\x19\xe6\xa0\x80\x18\xe6\xa0\x80\x18\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xc2\x82\xe7\xbf\xa1\xee\xa0\x80\x15\xe6\xa0\x80\x18\xee\xa0\x80\x16\xe6\xa0\x80\x1b\xe6\xa0\x80\xe5\x80\x97\xe6\xa0\x80\x1b\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xc2\x81\xe7\xbf\xa2\xee\xa0\x80\x15\xe6\xa0\x80\x19\xee\xa0\x80\x16\xe6\xa0\x80\x19\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe5\x80\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe4\xa0\x80\xe1\x80\x8f\xe3\xa0\x80\x0c\xe6\xa0\x80\x18\xe2\xa0\x80\xe6\x80\x9a\xe2\xa0\x80\xe6\x80\x9a\xe2\xa0\x80\xe6\x80\x9a\xe2\xa0\x80\xe6\x80\x9a\xe6\xa0\x80\x1c\xe6\xa0\x80\x18\xe6\xa0\x80\x1b\xe6\xa0\x80\x1c\xc0\x80\xe7\x80\x85\xee\xa0\x80\x1d\xe6\xa0\x80\x19\xe4\xa0\x80\xe1\x80\x90\xe6\xa0\x80\x1c\xe6\xa0\x80\x1b\xe2\xa0\x80\x1c\xe2\xa0\x80\x19\xe1\xa0\x80\xd8\x8b\xe1\xa0\x80\xd8\x8b\xe6\xa0\x80\x1b\xdf\xbd\xe7\x80\x82\xe6\xa0\x80\x18\xe6\xa0\x80\x18\xe6\xa0\x80\x1b\xe1\xa0\x80\xd4\x8b\xc0\x80\xe7\x80\x85\xee\xa0\x80\x1e\xe6\xa0\x80\xe0\xa0\x8b\xe6\xa0\x80\xe0\xa0\x8b\xe6\xa0\x80\xe0\xa0\x8b\xe6\xa0\x80\x18\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xe6\xa0\x80\x19\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xc2\x82\xe7\x80\x81\xdf\xbd\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xe6\xa0\x80\x19\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xc2\x81\xe7\x80\x82\xd8\x9d\xe7\x80\x82
+6 -1: (J[I)I
+162 -1: (Ljava/util/List<Ljava/util/Locale$LanguageRange;>;Ljava/util/Collection<Ljava/util/Locale;>;Ljava/util/Locale$FilteringMode;)Ljava/util/List<Ljava/util/Locale;>;
+21 -1: getQualifiedFieldName
+46 -1: Ljava/util/Set<Ljava/util/Map$Entry<TK;TV;>;>;
+47 -1: (Ljava/util/Collection;Ljava/util/Collection;)Z
+10 -1: getRuntime
+30 -1: threadLocalRandomSecondarySeed
+18 -1: (Ljava/io/File;I)J
+10 -1: methodName
+34 -1: sun/reflect/generics/tree/TypeTree
+35 -1: (Ljava/io/File;)[Ljava/lang/String;
+31 -1: java/util/Collections$EmptyList
+15 -1: LF_INVINTERFACE
+9 -1: notifyAll
+18 -1: (Ljava/io/File;I)V
+94 -1: (Ljava/lang/String;[BIILjava/security/ProtectionDomain;Ljava/lang/String;)Ljava/lang/Class<*>;
+45 -1: (Ljava/lang/String;)Ljava/net/ContentHandler;
+3 -1: enc
+3 -1: end
+18 -1: (Ljava/io/File;I)Z
+47 -1: (Ljava/lang/Object;Ljava/lang/reflect/Method;)V
+76 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
+19 -1: getURLStreamHandler
+46 -1: (Ljava/lang/ClassLoader;Ljava/lang/Class<*>;)V
+17 -1: COMPILE_THRESHOLD
+15 -1: charset is null
+7 -1: ibm-912
+10 -1: basicTypes
+7 -1: ibm-914
+78 -1: (Ljava/lang/Class;Ljava/lang/ref/SoftReference;Ljava/lang/ref/SoftReference;)Z
+7 -1: ibm-915
+12 -1: JarFileEntry
+12 -1: setThreshold
+22 -1: (ILjava/lang/Object;)V
+55 -1: <T::Lsun/reflect/generics/tree/Tree;>Ljava/lang/Object;
+16 -1: Unknown signal: 
+3 -1: zip
+13 -1: CR_UNMAPPABLE
+19 -1: getClassAtIfLoaded0
+21 -1: WindowsClientCounters
+29 -1: Ljava/lang/invoke/MethodType;
+91 -1: <E:Ljava/lang/Object;>Ljava/util/Collections$UnmodifiableList<TE;>;Ljava/util/RandomAccess;
+23 -1: StackOverflowError.java
+13 -1: Launcher.java
+9 -1: Signature
+7 -1: ibm-920
+153 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>([Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;ILjava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;)V
+13 -1: setExtensions
+26 -1: [Ljava/lang/ref/Reference;
+7 -1: ibm-923
+12 -1: BMH.reinvoke
+34 -1: java/lang/IllegalArgumentException
+53 -1: (Ljava/lang/String;)Ljava/lang/NumberFormatException;
+5 -1: .dirs
+13 -1: finishToArray
+22 -1: (ZI)Ljava/lang/String;
+84 -1: (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/RuntimeException;
+15 -1: charsetProvider
+24 -1: ()Ljava/lang/Class<TT;>;
+10 -1: wordsInUse
+26 -1: (Ljava/io/ExpiringCache;)I
+53 -1: ()Ljava/util/Iterator<Ljava/util/Map$Entry<TK;TV;>;>;
+25 -1: com/sun/management/GcInfo
+26 -1: getCompatibilityExtensions
+69 -1: (Ljava/lang/ref/ReferenceQueue;Ljava/util/concurrent/ConcurrentMap;)V
+15 -1: getConstantPool
+24 -1: [[Ljava/lang/Comparable;
+26 -1: (Ljava/io/ExpiringCache;)V
+8 -1: getTable
+53 -1: sun/reflect/generics/repository/ConstructorRepository
+5 -1: range
+36 -1: (Ljava/lang/String;)Ljava/lang/Byte;
+72 -1: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)V
+60 -1: <T:Ljava/lang/Object;>([TT;TT;Ljava/util/Comparator<-TT;>;)I
+20 -1: (Ljava/nio/Bits$1;)V
+30 -1: ()Ljava/util/Spliterator<TK;>;
+6 -1: ([BB)I
+53 -1: (Ljava/lang/ref/Finalizer;Lsun/misc/JavaLangAccess;)V
+11 -1: memberTypes
+45 -1: (ILjava/lang/String;)Ljava/lang/StringBuffer;
+12 -1: OTHER_SYMBOL
+65 -1: (Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+43 -1: (Ljava/util/Set;)[Ljava/lang/reflect/Field;
+30 -1: (Ljava/lang/ref/Reference$1;)V
+18 -1: GREGORIAN_INSTANCE
+31 -1: Ljava/lang/FunctionalInterface;
+57 -1: (Ljava/lang/Error;Ljava/lang/Exception;)Ljava/lang/Error;
+54 -1: ([Ljava/lang/reflect/Field;)[Ljava/lang/reflect/Field;
+14 -1: not an array: 
+6 -1: ([BB)V
+9 -1: ISO8859_1
+8 -1: addTrans
+27 -1: getFunctionalInterfaceClass
+29 -1: lambda$comparingInt$7b0bb60$1
+8 -1: TreeNode
+138 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/Dictionary<TK;TV;>;Ljava/util/Map<TK;TV;>;Ljava/lang/Cloneable;Ljava/io/Serializable;
+3 -1: era
+22 -1: fakeMethodHandleInvoke
+9 -1: addToList
+39 -1: (Ljava/lang/Class;[Ljava/lang/String;)V
+17 -1: launchApplication
+21 -1: randomNumberGenerator
+51 -1: Ljava/lang/ThreadLocal<Ljava/lang/ThreadLocal<*>;>;
+35 -1: java/io/ObjectOutputStream$PutField
+42 -1: (ILjava/util/function/IntBinaryOperator;)I
+3 -1: err
+13 -1: cachedDecoder
+32 -1: sun/util/calendar/ZoneInfoFile$1
+23 -1: doIntersectionPrivilege
+19 -1: cspc850multilingual
+56 -1: Ljava/util/Map<Ljava/lang/Class<*>;[Ljava/lang/String;>;
+11 -1: loader_data
+27 -1: (Ljava/util/jar/Manifest;)V
+5 -1: files
+90 -1: Ljava/util/concurrent/ConcurrentMap<Ljava/lang/String;Lsun/util/calendar/CalendarSystem;>;
+36 -1: [[Ljava/lang/invoke/LambdaForm$Name;
+5 -1: lines
+55 -1: (Lsun/misc/URLClassPath$JarLoader;)Lsun/misc/MetaIndex;
+9 -1: ansi-1251
+15 -1: refKindIsMethod
+29 -1: java/lang/reflect/Constructor
+3 -1: est
+19 -1: Lsun/misc/Launcher;
+109 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedExceptionAction<TT;>;Ljava/security/AccessControlContext;)TT;
+10 -1: getOffsets
+9 -1: removeAll
+23 -1: java/util/regex/Matcher
+8 -1: sumCount
+7 -1: implies
+10 -1: MAIN_CLASS
+75 -1: (Ljava/util/List<Lsun/launcher/LauncherHelper$StdArg;>;)[Ljava/lang/String;
+11 -1: getISO3Code
+4 -1: high
+53 -1: (TK;Ljava/util/function/BiFunction<-TK;-TV;+TV;>;)TV;
+17 -1: setNormalizedDate
+23 -1: AbstractRepository.java
+28 -1: java/util/LinkedList$ListItr
+8 -1: isFrozen
+38 -1: (Ljava/lang/String;Z)Ljava/lang/Class;
+16 -1: ReflectUtil.java
+30 -1: ()Ljava/util/stream/IntStream;
+57 -1: (Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;
+11 -1: getResource
+16 -1: ThreadDeath.java
+24 -1: unmodifiableNavigableSet
+59 -1: (Ljava/lang/String;)Ljava/util/Enumeration<Ljava/net/URL;>;
+24 -1: java.security.auth.debug
+58 -1: (Ljava/io/FileInputStream;)Ljava/nio/channels/FileChannel;
+25 -1: ()Ljava/util/Enumeration;
+11 -1: getInstance
+6 -1: MONDAY
+15 -1: jdkMinorVersion
+16 -1: newThreadWithAcc
+6 -1: CENHOW
+32 -1:     Max. Heap Size (Estimated): 
+61 -1: (Ljava/lang/invoke/MethodType;Z)Ljava/lang/invoke/LambdaForm;
+11 -1: windows-932
+7 -1: Index: 
+11 -1: composeList
+6 -1: utf-16
+6 -1: ibm437
+10 -1: getJarFile
+8 -1: , rem = 
+13 -1: multiNewArray
+14 -1: getDefaultPort
+39 -1: Ljava/security/cert/CertificateFactory;
+10 -1: L_RESERVED
+19 -1: getMethodAtIfLoaded
+8 -1: needCast
+8 -1: IS_FIELD
+15 -1: ClassValue.java
+31 -1: ()Ljava/util/function/Supplier;
+125 -1: (Ljava/lang/Class<*>;)Ljava/util/Map<Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;Ljava/lang/annotation/Annotation;>;
+34 -1: lambda$comparingByValue$827a17d5$1
+4 -1: NONE
+21 -1: java/nio/DoubleBuffer
+33 -1: ()Lsun/reflect/LangReflectAccess;
+26 -1: invalid compression method
+6 -1: (TK;)Z
+16 -1: FT_UNCHECKED_REF
+14 -1: getGenericType
+17 -1: pathSeparatorChar
+8 -1: writeUTF
+8 -1: NO_PROXY
+188 -1: (Ljava/lang/String;Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;Ljava/util/Map<Ljava/lang/String;Ljava/nio/charset/Charset;>;)V
+13 -1: finalRefCount
+12 -1: NF_checkCast
+6 -1: utf-32
+26 -1: (Ljava/util/ArrayDeque;I)Z
+19 -1: prefetchWriteStatic
+14 -1: computeInvoker
+5 -1:  cap=
+19 -1: generateCertificate
+15 -1: methodModifiers
+3 -1: exc
+27 -1: ()Lsun/misc/JavaLangAccess;
+5 -1: State
+14 -1: NullComparator
+10 -1: getClassAt
+15 -1: printProperties
+110 -1: (Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;IILjava/lang/String;[B[B)Ljava/lang/reflect/Constructor;
+40 -1: (Ljava/util/List<*>;Ljava/util/Random;)V
+63 -1: ()[Ljava/lang/reflect/TypeVariable<Ljava/lang/reflect/Method;>;
+28 -1: (I)Ljava/lang/StringBuilder;
+48 -1: ([DIILjava/util/function/DoubleBinaryOperator;)V
+3 -1: exp
+11 -1: interpret_L
+17 -1: Serializable.java
+8 -1: FJDouble
+12 -1: HashMap.java
+9 -1: sys_paths
+17 -1: getMainAttributes
+14 -1: asDoubleBuffer
+10 -1: buildNames
+26 -1: TOPLEVEL_WINDOW_PERMISSION
+4 -1: Type
+31 -1: (Ljava/util/Collection<+TE;>;)V
+64 -1: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class<*>;
+100 -1: <E:Ljava/lang/Object;>(Ljava/util/Collection<TE;>;Ljava/lang/Class<TE;>;)Ljava/util/Collection<TE;>;
+10 -1: checkError
+31 -1: (Ljava/util/Collection<+TE;>;)Z
+31 -1: java/lang/NoSuchMethodException
+6 -1: attach
+87 -1: (BLjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+9 -1: writeChar
+44 -1: java/util/ArraysParallelSortHelpers$FJObject
+34 -1: (Ljava/lang/Class;Ljava/io/File;)Z
+21 -1: java/util/zip/ZipFile
+5 -1: dirty
+6 -1: (JIZ)V
+12 -1: leftoverChar
+39 -1:  is being loaded in another classloader
+10 -1: writeBytes
+6 -1: unlink
+41 -1: (TT;Ljava/lang/ref/ReferenceQueue<TT;>;)V
+21 -1: getBootstrapResources
+95 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/io/Serializable;
+10 -1: PathStatus
+25 -1: java/io/InputStreamReader
+15 -1: ISO_8859-9:1989
+37 -1: java/lang/ExceptionInInitializerError
+14 -1: exceptionTypes
+19 -1: BufferedReader.java
+34 -1: Could not create SecurityManager: 
+13 -1: definePackage
+12 -1: getAndAddInt
+50 -1: (Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;
+30 -1: (Ljava/lang/SecurityManager;)V
+12 -1: fxLaunchName
+22 -1: BINARYSEARCH_THRESHOLD
+29 -1: JVMTI_THREAD_STATE_TERMINATED
+9 -1: fullFence
+60 -1: (Ljava/lang/String;Z)Ljava/util/Enumeration<Ljava/net/URL;>;
+29 -1: java/lang/Thread$WeakClassKey
+47 -1: (Ljava/nio/charset/Charset;Ljava/lang/String;)V
+8 -1: (TV;)TV;
+60 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Object;I)V
+47 -1: java/security/cert/CertificateEncodingException
+12 -1: BA_DIRECTORY
+53 -1: (Ljava/lang/Class;ZLjava/lang/Class;)Ljava/util/List;
+9 -1: checkRead
+6 -1: <init>
+4 -1: args
+17 -1: genericMethodType
+10 -1: writeFloat
+26 -1: Can't handle static method
+49 -1: (Ljava/lang/String;)Ljava/lang/invoke/MethodType;
+22 -1: MapReduceKeysToIntTask
+17 -1: jvm_micro_version
+29 -1: (Ljava/util/Map<+TK;+TV;>;Z)V
+40 -1: ([Ljava/lang/Object;Ljava/lang/Object;)I
+7 -1: vmindex
+22 -1: maybeCompileToBytecode
+89 -1: Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl;
+11 -1: getLauncher
+17 -1: jvm_major_version
+36 -1: ([IIII)Ljava/util/Spliterator$OfInt;
+40 -1: ([Ljava/lang/Object;Ljava/lang/Object;)V
+33 -1: IllegalMonitorStateException.java
+73 -1: ([ILjava/util/function/IntUnaryOperator;)Ljava/util/function/IntConsumer;
+39 -1: (Ljava/lang/String;)Ljava/lang/Package;
+29 -1: java/lang/CharacterDataLatin1
+52 -1: (Ljava/lang/annotation/Annotation;)Ljava/lang/Class;
+49 -1: (Ljava/lang/CharSequence;II)Ljava/nio/CharBuffer;
+53 -1: (Ljava/lang/Object;)Ljava/nio/charset/CharsetDecoder;
+22 -1: Ljava/net/FileNameMap;
+16 -1: isAnonymousClass
+4 -1: item
+7 -1: compute
+12 -1: user.country
+22 -1: malformed context url:
+16 -1: jvm_build_number
+69 -1: (Ljava/lang/ThreadLocal;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+17 -1: getDirectionality
+4 -1: save
+8 -1: UNMARKED
+58 -1: (Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V
+12 -1: searchFields
+9 -1: frequency
+23 -1: getLocalizedInputStream
+2 -1:   
+126 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Class<*>;)Ljava/util/List<Ljava/lang/invoke/MemberName;>;
+39 -1: (Ljava/lang/String;Z)Ljava/lang/String;
+7 -1: setZone
+2 -1:  "
+9 -1: checkRef(
+11 -1: loadFromXML
+49 -1: (Ljava/util/jar/JarFile;Ljava/util/Enumeration;)V
+68 -1: (IILsun/util/calendar/CalendarDate;)Lsun/util/calendar/CalendarDate;
+2 -1:  (
+54 -1: (Ljava/util/TimeZone;)Lsun/util/calendar/CalendarDate;
+6 -1: rewind
+13 -1: getAndSetLong
+30 -1: java/lang/invoke/MethodHandles
+11 -1: ListPattern
+97 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractList<TE;>;Ljava/util/RandomAccess;Ljava/io/Serializable;
+25 -1: (Ljava/io/InputStream;I)V
+9 -1: setMethod
+10 -1: H_REG_NAME
+39 -1: ([Ljava/lang/Object;)Ljava/lang/Object;
+16 -1: AbstractMap.java
+68 -1: Ljava/util/Hashtable<Ljava/lang/String;Ljava/net/URLStreamHandler;>;
+58 -1: (Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Process;
+23 -1: getFileSystemAttributes
+12 -1: toSurrogates
+2 -1: !/
+5 -1: empty
+24 -1: isUnicodeIdentifierStart
+35 -1: sun/nio/cs/StandardCharsets$Classes
+27 -1: [Ljava/security/Permission;
+13 -1: getDefinition
+11 -1: permission=
+42 -1: (ILjava/lang/String;)Ljava/nio/ByteBuffer;
+69 -1: (Ljava/util/List<Ljava/lang/Class<*>;>;)Ljava/lang/invoke/MethodType;
+3 1: zzz
+17 -1: hasLongPrimitives
+2 -1: !=
+13 -1: getInterfaces
+2 -1: " 
+11 -1: noInflation
+14 -1: aliases_UTF_16
+2 -1: ")
+17 -1: ()Ljava/util/Map;
+55 -1: ()Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;
+6 -1: charAt
+12 -1: getStringAt0
+10 -1: superClone
+28 -1: Ljava/util/AbstractSet<TK;>;
+40 -1: java/lang/ref/Reference$ReferenceHandler
+22 -1: NaturalOrderComparator
+9 -1: markValue
+9 -1: getRegion
+26 -1: null permissions parameter
+17 -1: Ljava/util/Stack;
+14 -1: codebase=<URL>
+36 -1: (Ljava/util/List;)Ljava/lang/Object;
+17 -1: setJavaLangAccess
+16 -1: hasQueuedThreads
+5 -1: (CC)I
+8 -1: toString
+5 -1: (CC)J
+11 -1: permissions
+10 -1: getHeaders
+27 -1: java/io/BufferedInputStream
+21 -1: unicodelittleunmarked
+51 -1: (Ljava/net/URLClassLoader;Ljava/util/Enumeration;)V
+14 -1: generateMethod
+11 -1: skipForward
+55 -1: java/util/concurrent/ConcurrentHashMap$ForEachEntryTask
+5 -1: (CC)Z
+15 -1: getURLClassPath
+84 -1: Ljava/lang/invoke/MethodType$ConcurrentWeakInternSet<Ljava/lang/invoke/MethodType;>;
+23 -1: primitiveParameterCount
+8 -1: security
+14 -1: aliases_UTF_32
+22 -1: ()Ljava/util/Set<TK;>;
+9 -1: listFiles
+15 -1: insertElementAt
+42 -1: Ljava/util/Comparator<Ljava/lang/String;>;
+11 -1: getUserInfo
+46 -1: ([JIILjava/util/function/LongBinaryOperator;)V
+23 -1: (Ljava/util/Iterator;)V
+46 -1: ([Ljava/lang/Object;II)Ljava/util/Spliterator;
+67 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/Object;)Ljava/lang/Object;
+14 -1: normalizeMonth
+13 -1: getStackTrace
+51 -1: java/lang/invoke/MethodType$ConcurrentWeakInternSet
+8 -1: makeChar
+2 -1: %%
+9 -1: getTarget
+21 -1: packageDefinitionLock
+52 -1: java/util/concurrent/ConcurrentHashMap$ValueIterator
+12 -1: OTHER_NUMBER
+22 -1: java/util/jar/JarEntry
+11 -1: access$1000
+16 -1: NON_SPACING_MARK
+13 -1: last-modified
+68 -1: Ljava/lang/Object;Ljava/security/PrivilegedAction<Ljava/lang/Void;>;
+16 -1: Australia/Darwin
+55 -1: (Ljava/lang/management/ThreadInfo;[Ljava/lang/Object;)V
+29 -1: Ljava/lang/ref/WeakReference;
+19 -1: expungeStaleEntries
+41 -1: Ljava/security/PrivilegedActionException;
+6 -1: update
+23 -1: (Ljava/lang/Object;JB)V
+10 -1: newUpdater
+39 -1: (Ljava/net/URL;)Ljava/util/jar/JarFile;
+25 -1: Ljava/net/ContentHandler;
+21 -1: ARRAY_INT_INDEX_SCALE
+13 -1: hasSurrogates
+27 -1: (Ljava/lang/ThreadGroup;Z)Z
+20 -1: createGCNotification
+21 -1: negative day of week 
+11 -1: getInIfOpen
+22 -1: java/util/RandomAccess
+24 -1:     available locales = 
+21 -1: AccessController.java
+44 -1:  can not access a protected member of class 
+4 -1: LONG
+15 -1: objectOnlyTypes
+75 -1: (Ljava/io/InputStream;Ljava/lang/Object;Ljava/nio/charset/CharsetDecoder;)V
+14 -1: getFindClasses
+10 -1: storeFence
+16 -1: asNormalOriginal
+45 -1: (Ljava/lang/String;)Ljava/lang/StringBuilder;
+6 -1: millis
+16 -1: America/St_Johns
+38 -1: ()Ljava/lang/IllegalArgumentException;
+37 -1: DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+15 -1: implReplaceWith
+29 -1: ([C)Ljava/lang/StringBuilder;
+15 -1: Appendable.java
+41 -1: (Ljava/lang/String;)Ljava/io/InputStream;
+26 -1: Illegal Initial Capacity: 
+9 -1: checkBase
+7 -1: setYear
+15 -1: DISPLAY_VARIANT
+7 -1: getType
+31 -1: Ljava/lang/ref/Reference<+TT;>;
+15 -1: isFieldOrMethod
+35 -1: appendToClassPathForInstrumentation
+16 -1: LocaleNameGetter
+7 -1: compact
+55 -1: ()Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;
+10 -1: dummyQueue
+3 -1: ROC
+2 -1: ("
+15 -1: checkPermission
+38 -1: java/util/zip/ZipFile$ZipEntryIterator
+8 -1: hexDigit
+8 -1:  pairs: 
+2 -1: ()
+2 -1: )\n
+43 -1: handler for url different from this handler
+15 -1: isAutoDetecting
+37 -1: (Ljava/util/LinkedList$Node<TE;>;)TE;
+11 -1: Unsafe.java
+12 -1: windows-1250
+39 -1: java/util/Collections$CheckedCollection
+12 -1: windows-1251
+15 -1: codePointAtImpl
+12 -1: windows-1252
+12 -1: windows-1253
+12 -1: windows-1254
+58 -1: (Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/Integer;
+5 -1: deref
+12 -1: windows-1255
+12 -1: windows-1256
+12 -1: windows-1257
+12 -1: windows-1258
+14 -1: FT_CHECKED_REF
+47 -1: (Ljava/util/Hashtable;Ljava/util/Hashtable$1;)V
+37 -1: (J)Lsun/util/calendar/Gregorian$Date;
+19 -1: checkPropertyAccess
+4 -1: file
+17 -1: emptyListIterator
+26 -1: sun/util/calendar/ZoneInfo
+14 -1: file.separator
+4 -1: fill
+62 -1: (Ljava/util/Spliterator$OfLong;Z)Ljava/util/stream/LongStream;
+18 -1: java/util/Iterator
+20 -1: reduceValuesToDouble
+12 -1: LF_CS_LINKER
+26 -1: java/util/Arrays$ArrayList
+45 -1: Ljava/util/concurrent/ConcurrentHashMap$Node;
+6 -1: skipLF
+2 -1: )=
+39 -1: (I[Ljava/lang/invoke/LambdaForm$Name;)I
+90 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MemberName;)V
+18 -1: parameterModifiers
+31 -1: (Ljava/util/Collection<+TK;>;)Z
+21 -1: proxy can not be null
+22 -1: java/io/FileDescriptor
+6 -1: Loader
+21 -1: numberOfTrailingZeros
+10 -1: addMapping
+39 -1: (I[Ljava/lang/invoke/LambdaForm$Name;)Z
+30 -1: java/util/Locale$LanguageRange
+20 -1: getReflectionFactory
+16 -1: shouldMeterInput
+56 -1: ([Ljava/lang/reflect/Method;)[Ljava/lang/reflect/Method;
+23 -1: sun/net/ProgressMonitor
+510 -1: \xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\x01\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\x01\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80\xc0\x80
+28 -1: java/util/Spliterator$OfLong
+24 -1: SynchronizedNavigableMap
+4 -1: find
+6 -1: unsafe
+31 -1: java/nio/ByteBufferAsIntBufferB
+2 -1: ,\n
+6 -1: [ call
+14 -1: registerFilter
+10 -1: ValuesView
+9 -1: untreeify
+59 -1: ([Ljava/lang/Object;IILjava/util/function/BinaryOperator;)V
+13 -1: getSimpleName
+41 -1: (Ljava/util/Vector;Ljava/util/Vector$1;)V
+31 -1: java/nio/ByteBufferAsIntBufferL
+45 -1: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
+13 -1: getDefaultRef
+18 -1: mapAlternativeName
+30 -1: setDefaultAllowUserInteraction
+13 -1: cannotCastMsg
+4 -1: )=>{
+7 -1: println
+2 -1: , 
+70 -1: (Ljava/nio/Buffer;IILjava/nio/Buffer;II)Ljava/nio/charset/CoderResult;
+32 -1: (ILjava/util/Collection<+TE;>;)Z
+9 -1: interpret
+104 -1: <E:Ljava/lang/Object;>(Ljava/util/NavigableSet<TE;>;Ljava/lang/Class<TE;>;)Ljava/util/NavigableSet<TE;>;
+7 -1: advance
+86 -1: Ljava/lang/Object;Ljava/security/PrivilegedExceptionAction<Ljava/lang/reflect/Field;>;
+11 -1: Stack trace
+6 -1: raise0
+68 -1: ()Ljava/util/Collections$UnmodifiableNavigableMap$EmptyNavigableMap;
+32 -1: sun/util/calendar/Gregorian$Date
+33 -1: java/lang/ref/ReferenceQueue$Lock
+19 -1: constructorAccessor
+6 -1: IBM367
+18 -1: CharacterData.java
+8 -1: parseURL
+32 -1: java/io/FilePermissionCollection
+7 -1: ([JI)[J
+9 -1: JIS_X0201
+2 -1: -1
+8 -1: encoding
+63 -1: ([Ljava/util/WeakHashMap$Entry;[Ljava/util/WeakHashMap$Entry;)V
+9 -1: localhost
+66 -1: (Ljava/lang/ThreadLocal$ThreadLocalMap;Ljava/lang/ThreadLocal$1;)V
+54 -1: (II[Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+67 -1: (Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;
+14 -1: containsAllPDs
+23 -1: setAllowUserInteraction
+30 -1: Ljava/security/DomainCombiner;
+26 -1: Ljava/security/Permission;
+30 -1: serializePropertiesToByteArray
+112 -1: (Ljava/util/Iterator<Ljava/nio/charset/Charset;>;Ljava/util/Map<Ljava/lang/String;Ljava/nio/charset/Charset;>;)V
+2 -1: ..
+6 -1: LOCEXT
+2 -1: ./
+26 -1: (Ljava/nio/ByteBuffer;II)V
+18 -1: (Ljava/io/File;J)Z
+45 -1: (Ljava/lang/StringBuffer;Ljava/lang/String;)V
+17 -1: asCollectorChecks
+7 -1: actions
+5 -1: ([I)I
+20 -1: asChange_otherthread
+20 -1: forInputStreamReader
+69 -1: java/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject
+5 -1: FINAL
+17 -1: staticPermissions
+44 -1: (Ljava/lang/Object;)Ljava/lang/StringBuffer;
+5 -1: ([I)V
+4 -1: swap
+10 -1: readOffset
+2 -1: /*
+112 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<-TK;+TU;>;Ljava/util/function/BiFunction<-TU;-TU;+TU;>;)TU;
+12 -1: isAsciiDigit
+2 -1: /-
+2 -1: /.
+2 -1: //
+5 -1: zones
+37 -1: (ILjava/lang/Object;)Ljava/util/List;
+17 -1: SHUFFLE_THRESHOLD
+32 -1: java/lang/CharacterDataUndefined
+23 -1: sun.reflect.noInflation
+11 -1: Can not set
+36 -1: (Ljava/util/Properties$LineReader;)V
+9 -1: debugName
+78 -1: (Ljava/util/HashMap$Node;Ljava/util/HashMap$Node;)Ljava/util/HashMap$TreeNode;
+6 -1: (III)J
+58 -1: (Ljava/util/List;Ljava/util/Collection;)Ljava/lang/String;
+19 -1: BufferedWriter.java
+148 -1: <T:Ljava/lang/Object;>(Ljava/lang/Class<TT;>;[Ljava/lang/Class<*>;[Ljava/lang/Class<*>;IILjava/lang/String;[B[B)Ljava/lang/reflect/Constructor<TT;>;
+6 -1: printf
+7 -1: signers
+2 -1: 0.
+4 -1: Date
+15 -1: findReplacement
+6 -1: (III)V
+32 -1: java/nio/ReadOnlyBufferException
+92 -1: ([Ljava/lang/String;)Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;>;
+6 -1: (III)Z
+43 -1: (Ljava/lang/ClassValue;Ljava/lang/Object;)V
+32 -1: java/nio/ByteBufferAsLongBufferB
+16 -1: Constructor.java
+10 -1: removeLast
+9 -1: ([CII[B)I
+40 -1: ()Ljava/util/List<Ljava/lang/Class<*>;>;
+2 -1: 1.
+7 -1: VARARGS
+32 -1: java/nio/ByteBufferAsLongBufferL
+18 -1: java/lang/Shutdown
+40 -1:  not supported, using ISO-8859-1 instead
+40 -1: Ljava/util/Collections$EmptyEnumeration;
+146 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/SortedMap<TK;TV;>;Ljava/lang/Class<TK;>;Ljava/lang/Class<TV;>;)Ljava/util/SortedMap<TK;TV;>;
+20 -1: aliases_UTF_32LE_BOM
+23 -1: getEnclosingConstructor
+2 -1: 0X
+11 -1: NO_TIMEZONE
+37 -1: ()Lsun/misc/JavaNioAccess$BufferPool;
+18 -1: printXUsageMessage
+9 -1: isPrivate
+63 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/invoke/MethodHandle;)V
+17 -1: maxSkipBufferSize
+76 -1: (Ljava/io/OutputStream;Ljava/lang/Object;Ljava/nio/charset/CharsetEncoder;)V
+40 -1: (Ljava/lang/String;II)Ljava/lang/String;
+17 -1: selectAlternative
+53 -1: [Ljava/util/concurrent/ConcurrentHashMap$CounterCell;
+87 -1: <S:Ljava/lang/Object;>(Ljava/util/function/Supplier<+TS;>;)Ljava/lang/ThreadLocal<TS;>;
+40 -1: Ljava/util/concurrent/ConcurrentHashMap;
+41 -1: (Ljava/lang/Character;)Ljava/lang/String;
+19 -1: getMemberRefInfoAt0
+14 -1: reduceToDouble
+18 -1: SUPPRESSED_CAPTION
+6 -1: CANADA
+64 -1: (IZ[Ljava/lang/Class<*>;[Ljava/lang/Class<*>;)Ljava/lang/String;
+12 -1: UnicodeBlock
+2 -1: 0x
+44 -1: (Ljava/lang/CharSequence;II)Ljava/io/Writer;
+23 -1: getPermissionCollection
+19 -1: threadLocalHashCode
+9 -1: createMap
+25 -1: checkForSpecialAttributes
+12 -1: Mark invalid
+36 -1: java/lang/CharSequence$1CharIterator
+11 -1:  local time
+16 -1: Enumeration.java
+27 -1: (Ljava/util/zip/ZipEntry;)V
+11 -1: MATH_SYMBOL
+8 -1: filename
+24 -1: (Ljava/util/List<*>;II)V
+9 -1: bindCache
+18 -1: java/io/FileFilter
+12 -1: checkInvoker
+18 -1: OSEnvironment.java
+8 -1: EmptyMap
+11 -1: getIterator
+35 -1: java/util/function/IntUnaryOperator
+35 -1: java/util/WeakHashMap$EntryIterator
+90 -1: <E:Ljava/lang/Object;>(Ljava/util/Queue<TE;>;Ljava/lang/Class<TE;>;)Ljava/util/Queue<TE;>;
+8 -1: batchFor
+16 -1: isValidCodePoint
+27 -1: ([Lsun/util/calendar/Era;)V
+16 -1: ThreadGroup.java
+33 2: sun/net/www/protocol/file/Handler
+7 -1: isField
+22 -1: sun/misc/OSEnvironment
+38 -1: Ljava/lang/Class<Ljava/lang/Boolean;>;
+12 -1: ADDRESS_SIZE
+8 -1: forDigit
+49 -1: (Ljava/lang/Object;)Ljava/util/WeakHashMap$Entry;
+13 -1: getCodeSource
+41 -1: ([Ljava/lang/Class<*>;)Ljava/lang/String;
+39 -1: (Ljava/util/function/Predicate<-TE;>;)Z
+13 -1: asFloatBuffer
+34 -1: ()Lsun/reflect/generics/tree/Tree;
+3 -1: ftp
+18 -1: maybeReBoxElements
+82 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/Class;)[[Ljava/lang/annotation/Annotation;
+48 -1: ()Ljava/util/Set<Ljava/util/Map$Entry<TK;TV;>;>;
+27 -1: (Ljava/util/NavigableMap;)V
+18 -1: parameterSlotCount
+20 -1: NF_getCallSiteTarget
+16 -1: aliases_US_ASCII
+13 -1: NF_staticBase
+31 -1: sun/reflect/ConstructorAccessor
+26 -1: guessContentTypeFromStream
+10 -1: Deprecated
+35 -1: System initialization has completed
+11 -1: initialized
+7 -1: compare
+15 -1: maxDirectMemory
+19 -1: setLastModifiedTime
+7 -1: (J[BZ)J
+12 -1: readEpochSec
+66 -1: (Ljava/lang/String;Ljava/lang/String;)Lsun/util/locale/BaseLocale;
+69 -1: ()Lsun/misc/JavaSecurityProtectionDomainAccess$ProtectionDomainCache;
+9 -1: Constants
+11 -1: valueOffset
+62 -1: (Ljava/util/Hashtable<Ljava/lang/String;Ljava/lang/Object;>;)V
+33 -1: java/lang/CharacterDataPrivateUse
+21 -1: Exception in thread "
+40 -1: ()Ljava/util/Set<Ljava/lang/Character;>;
+12 -1: Asia/Yerevan
+40 -1: (Ljava/lang/Throwable;)Ljava/lang/Error;
+25 -1: (IS)Ljava/nio/ByteBuffer;
+7 -1: (I[CI)I
+45 -1: java/nio/charset/UnmappableCharacterException
+23 -1: java/util/WeakHashMap$1
+21 -1: setFXLaunchParameters
+1250 -1: ADANDAEAREAFAFGAGATGAIAIAALALBAMARMANANTAOAGOAQATAARARGASASMATAUTAUAUSAWABWAXALAAZAZEBABIHBBBRBBDBGDBEBELBFBFABGBGRBHBHRBIBDIBJBENBLBLMBMBMUBNBRNBOBOLBQBESBRBRABSBHSBTBTNBVBVTBWBWABYBLRBZBLZCACANCCCCKCDCODCFCAFCGCOGCHCHECICIVCKCOKCLCHLCMCMRCNCHNCOCOLCRCRICUCUBCVCPVCWCUWCXCXRCYCYPCZCZEDEDEUDJDJIDKDNKDMDMADODOMDZDZAECECUEEESTEGEGYEHESHERERIESESPETETHFIFINFJFJIFKFLKFMFSMFOFROFRFRAGAGABGBGBRGDGRDGEGEOGFGUFGGGGYGHGHAGIGIBGLGRLGMGMBGNGINGPGLPGQGNQGRGRCGSSGSGTGTMGUGUMGWGNBGYGUYHKHKGHMHMDHNHNDHRHRVHTHTIHUHUNIDIDNIEIRLILISRIMIMNININDIOIOTIQIRQIRIRNISISLITITAJEJEYJMJAMJOJORJPJPNKEKENKGKGZKHKHMKIKIRKMCOMKNKNAKPPRKKRKORKWKWTKYCYMKZKAZLALAOLBLBNLCLCALILIELKLKALRLBRLSLSOLTLTULULUXLVLVALYLBYMAMARMCMCOMDMDAMEMNEMFMAFMGMDGMHMHLMKMKDMLMLIMMMMRMNMNGMOMACMPMNPMQMTQMRMRTMSMSRMTMLTMUMUSMVMDVMWMWIMXMEXMYMYSMZMOZNANAMNCNCLNENERNFNFKNGNGANINICNLNLDNONORNPNPLNRNRUNUNIUNZNZLOMOMNPAPANPEPERPFPYFPGPNGPHPHLPKPAKPLPOLPMSPMPNPCNPRPRIPSPSEPTPRTPWPLWPYPRYQAQATREREUROROURSSRBRURUSRWRWASASAUSBSLBSCSYCSDSDNSESWESGSGPSHSHNSISVNSJSJMSKSVKSLSLESMSMRSNSENSOSOMSRSURSSSSDSTSTPSVSLVSXSXMSYSYRSZSWZTCTCATDTCDTFATFTGTGOTHTHATJTJKTKTKLTLTLSTMTKMTNTUNTOTONTRTURTTTTOTVTUVTWTWNTZTZAUAUKRUGUGAUMUMIUSUSAUYURYUZUZBVAVATVCVCTVEVENVGVGBVIVIRVNVNMVUVUTWFWLFWSWSMYEYEMYTMYTZAZAFZMZMBZWZWE
+60 -1: Ljava/util/Set<Ljava/lang/Class<+Ljava/lang/ClassLoader;>;>;
+24 -1: ()Ljava/security/Policy;
+7 -1: initted
+44 -1: java/util/Collections$UnmodifiableCollection
+12 -1: Pacific/Apia
+23 -1: checkProxyPackageAccess
+7 -1: (I[CI)V
+64 -1: ([Ljava/lang/Object;IILjava/lang/Object;Ljava/util/Comparator;)I
+16 -1: getJavaNioAccess
+7 -1: reverse
+7 -1: nocerts
+16 -1: activeGroupCount
+34 -1: java/util/jar/JarFile$JarFileEntry
+7 -1: loaders
+9 -1: toRadians
+24 -1: java/util/HashMap$KeySet
+37 -1: (Ljava/lang/Class;)Ljava/lang/Object;
+6 -1: getRef
+6 -1: H_DASH
+17 -1: LinkageError.java
+66 -1: (Ljava/lang/invoke/MethodTypeForm;)Ljava/lang/invoke/MethodHandle;
+41 -1: (Ljava/nio/ByteBuffer;)Ljava/util/BitSet;
+10 -1: addMinutes
+58 -1: <T:Ljava/lang/Object;>([TT;II)Ljava/util/Spliterator<TT;>;
+9 -1: parseJars
+13 -1: getUnsignedCS
+28 -1: (Ljava/util/AbstractList;I)V
+22 -1: threadLocalRandomProbe
+19 -1: newDirectByteBuffer
+27 -1: Filter already registered: 
+8 -1: unescape
+31 -1: sun/misc/URLClassPath$JarLoader
+6 -1: TAIWAN
+53 -1: <T:Ljava/lang/Object;>()Ljava/util/ListIterator<TT;>;
+17 -1: REVERSE_THRESHOLD
+31 -1: Java(TM) SE Runtime Environment
+7 -1: SECONDS
+70 -1: (Ljava/util/function/ToLongFunction<-TT;>;)Ljava/util/Comparator<TT;>;
+7 -1: BLOCKED
+6 -1: Caches
+63 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;)V
+2 -1: : 
+210 -1: (Ljava/util/Map<Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;Ljava/lang/annotation/Annotation;>;Ljava/util/Map<Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;Ljava/lang/annotation/Annotation;>;I)V
+153 -1: (JLjava/util/function/BiFunction<Ljava/util/Map$Entry<TK;TV;>;Ljava/util/Map$Entry<TK;TV;>;+Ljava/util/Map$Entry<TK;TV;>;>;)Ljava/util/Map$Entry<TK;TV;>;
+22 -1: ()Ljava/lang/Class<*>;
+28 -1: Ljava/lang/OutOfMemoryError;
+19 -1: writeFileDescriptor
+39 -1: Ljava/util/LinkedHashMap$Entry<TK;TV;>;
+26 -1: (ILjava/util/Collection;)Z
+18 -1: getEncodedInternal
+16 -1: ForEachValueTask
+23 -1: (Ljava/util/List<*>;I)V
+19 -1: SharedArchiveLoader
+20 -1: probeBackupLocations
+24 -1: java/lang/StringCoding$1
+28 -1: lookupContentHandlerClassFor
+36 -1: ()Lsun/misc/Launcher$ExtClassLoader;
+27 -1: reflectionFactoryAccessPerm
+14 -1: ACCESSOR_FORMS
+35 -1: ([JII)Ljava/util/stream/LongStream;
+34 -1: ISO-8859-1 charset not available: 
+8 -1: cscesu-8
+2 -1: ;/
+17 -1: typeToPackageName
+34 -1: (Ljava/net/URL;)Ljava/lang/String;
+5 -1: (IZ)V
+25 -1: Prohibited package name: 
+51 -1: (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V
+108 -1: (JLjava/util/function/ToIntFunction<Ljava/util/Map$Entry<TK;TV;>;>;ILjava/util/function/IntBinaryOperator;)I
+12 -1: soleInstance
+27 -1: (Ljava/io/BufferedReader;)V
+71 -1: (Ljava/nio/charset/CodingErrorAction;)Ljava/nio/charset/CharsetDecoder;
+17 -1: Ljava/lang/Class;
+38 -1: (Ljava/lang/String;)Ljava/lang/Double;
+10 -1: viewAsType
+22 -1: (Ljava/io/DataInput;)I
+22 -1: (Ljava/io/DataInput;)J
+105 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/WrongMethodTypeException;
+16 -1: setJavaNetAccess
+73 -1: (ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/util/HashMap$Node<TK;TV;>;
+22 -1: (Ljava/io/DataInput;)V
+14 -1: getHostAddress
+37 -1: sun/reflect/annotation/TypeAnnotation
+14 -1: ENCLOSING_MARK
+5 -1: FALSE
+14 -1: preDefineClass
+9 -1: newKeySet
+18 -1: getWaitQueueLength
+32 -1: ()Lsun/misc/URLClassPath$Loader;
+54 -1: (Ljava/nio/CharBuffer;I)Ljava/nio/charset/CoderResult;
+3 -1: SEP
+45 -1: (ITK;TV;Ljava/util/Hashtable$Entry<TK;TV;>;)V
+17 -1: getDeclaredFields
+7 -1: getDate
+10 -1: getClasses
+240 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceEntriesToIntTask;Ljava/util/function/ToIntFunction;ILjava/util/function/IntBinaryOperator;)V
+12 -1: WeakClassKey
+14 -1: LF_GEN_INVOKER
+25 -1: Ljava/lang/StringBuilder;
+2 -1: > 
+9 -1: getJarMap
+4 -1: asin
+37 -1: (Ljava/net/URLStreamHandlerFactory;)V
+30 -1: not a constructor type or name
+4 -1: main
+22 -1: java/io/FilenameFilter
+22 -1: sun.java.launcher.diag
+30 -1: ()Ljava/util/Spliterator<TE;>;
+57 -1: <T::Ljava/lang/Comparable<-TT;>;>(Ljava/util/List<TT;>;)V
+86 -1: <T:Ljava/lang/Object;>(Ljava/lang/ThreadLocal<Ljava/lang/ref/SoftReference<TT;>;>;)TT;
+18 -1: canBeCalledVirtual
+9 -1: Shift_JIS
+24 -1: ()Ljava/util/ArrayDeque;
+32 -1: (Ljava/lang/Class$MethodArray;)V
+22 -1: java/lang/StringCoding
+33 -1: sun/util/locale/LocaleObjectCache
+20 -1: Sorry, deque too big
+38 -1: java/lang/Throwable$WrappedPrintWriter
+25 -1: (Ljava/io/InputStream;J)J
+44 -1: (Ljava/security/Permission;)Ljava/util/List;
+5 -1: thunk
+5 -1: props
+15 -1: getLastModified
+120 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap<Ljava/lang/String;Ljava/util/LinkedList<Ljava/lang/String;>;>;)V
+146 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MemberName;Ljava/lang/Class;Ljava/lang/invoke/MethodHandleImpl$1;)V
+27 -1: parseExtensionsDependencies
+10 -1: getRawType
+39 -1: (Ljava/nio/charset/CodingErrorAction;)V
+22 -1: ObjectStreamField.java
+6 -1: handle
+11 -1: hasPrevious
+18 -1: instanceof Float: 
+52 -1: (ZLjava/io/OutputStream;Ljava/nio/charset/Charset;)V
+4 -1: make
+13 -1: isIdeographic
+26 -1: java/util/HashMap$EntrySet
+51 -1: (Ljava/util/Hashtable;)[Ljava/util/Hashtable$Entry;
+91 -1: (Ljava/lang/CharSequence;Ljava/lang/Iterable<+Ljava/lang/CharSequence;>;)Ljava/lang/String;
+13 -1: makeAllocator
+10 -1: , headless
+20 -1: expungeStaleElements
+58 -1: sun/reflect/annotation/TypeAnnotation$TypeAnnotationTarget
+41 -1: ([Ljava/lang/Object;Ljava/lang/Class$1;)V
+50 -1: <T:Ljava/lang/Object;>(I)Ljava/util/Iterator<TT;>;
+7 -1: TreeBin
+21 -1: Ljava/io/IOException;
+56 -1: (I[Ljava/lang/Class;)[Ljava/lang/invoke/LambdaForm$Name;
+6 -1: LOCFLG
+6 -1: DIRECT
+3 -1: SIG
+37 -1: java/security/NoSuchProviderException
+39 -1: " with illegal data type conversion to 
+16 -1: getCodeSourceURL
+51 -1: java/util/concurrent/ConcurrentHashMap$EntrySetView
+47 -1: (Ljava/util/ArrayList;Ljava/util/ArrayList$1;)V
+6 -1: delete
+38 -1: sun/reflect/UnsafeFieldAccessorFactory
+11 -1: isDestroyed
+140 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;ILjava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$Node;)Z
+9 -1: unaligned
+36 -1: ()Lsun/misc/Launcher$AppClassLoader;
+57 -1: (Ljava/lang/String;Ljava/util/Locale;)[Ljava/lang/String;
+37 -1: sun/reflect/annotation/AnnotationType
+49 -1: <T:Ljava/lang/Object;>([TT;)Ljava/util/List<TT;>;
+24 -1: (S)Ljava/nio/ByteBuffer;
+6 -1: ([DD)I
+9 -1: setTarget
+29 -1: (IF)Ljava/lang/StringBuilder;
+12 -1: forBasicType
+10 -1: (IIII[BI)V
+8 -1: ([DIID)I
+9 -1: BASE_YEAR
+19 -1: ()Ljava/lang/Error;
+42 -1: (Ljava/util/Map<TE;Ljava/lang/Boolean;>;)V
+6 -1: ([DD)V
+14 -1: Illegal size: 
+8 -1: ([DIID)V
+7 -1: (II[I)I
+17 -1: java_profile_name
+28 -1: java/util/AbstractCollection
+43 -1: (Ljava/net/URL;)[Ljava/security/CodeSource;
+62 -1: (Lsun/misc/URLClassPath$JarLoader;)Ljava/net/URLStreamHandler;
+33 -1: [Ljava/util/HashMap$Node<TK;TV;>;
+15 -1: (Native Method)
+11 -1: fileNameMap
+26 -1: ()Ljava/util/ListIterator;
+25 -1: java/util/LinkedList$Node
+18 -1: SELECT_ALTERNATIVE
+35 -1: (Ljava/lang/Object;)Ljava/util/Set;
+19 -1: java/io/IOException
+16 -1: : already loaded
+9 -1: image/gif
+6 -1: (TE;)I
+25 -1: (Ljava/util/Properties;)V
+40 -1: (Ljava/lang/String;)Ljava/nio/file/Path;
+19 -1: checkedNavigableMap
+9 -1: checkInt(
+17 -1: getContentTypeFor
+26 -1: ()Ljava/io/FileDescriptor;
+69 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V
+6 -1: (TE;)V
+25 -1: WARNING: Default charset 
+14 -1: ZipFile closed
+2 -1: CA
+6 -1: (TE;)Z
+64 -1: java/util/concurrent/ConcurrentHashMap$MapReduceValuesToLongTask
+15 -1: FileSystem.java
+75 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+10 -1: FileLoader
+44 -1: (Lsun/util/PreHashedMap;)[Ljava/lang/Object;
+19 -1: availableProcessors
+2 -1: CN
+36 -1: ([JII)Ljava/util/Spliterator$OfLong;
+11 -1: access$1100
+18 -1: getFieldAtIfLoaded
+30 -1: PrivilegedActionException.java
+6 -1: EUC-JP
+20 -1: (F)Ljava/lang/Float;
+22 -1: unable to instantiate 
+31 -1: java/lang/reflect/ReflectAccess
+23 -1: (Ljava/lang/Object;JC)V
+3 -1: get
+59 -1: <T:Ljava/lang/Object;>([TT;IILjava/util/Comparator<-TT;>;)V
+2 -1: DE
+13 -1: GMT_ID_LENGTH
+7 -1: execute
+12 -1: MethodHandle
+18 -1: AllPermission.java
+54 -1: (Ljava/util/Locale;)Lsun/util/locale/LocaleExtensions;
+23 -1: MapReduceKeysToLongTask
+12 -1: varargsArray
+23 -1: java/util/jar/JarFile$1
+23 -1: java/util/jar/JarFile$2
+23 -1: java/util/jar/JarFile$3
+12 -1: getAndUpdate
+13 -1: reserveMemory
+17 -1: expungeStaleEntry
+6 -1: EUC-KR
+120 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/ref/WeakReference<Ljava/lang/Object;>;Ljava/util/Map$Entry<TK;TV;>;
+69 -1: (Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;
+26 -1: ()Ljava/util/NavigableMap;
+7 -1: L_PCHAR
+23 -1: (Ljava/lang/String$1;)V
+4 -1: KEYS
+37 -1: (Ljava/util/List;Ljava/lang/Object;)I
+31 -1: Ljava/lang/ArithmeticException;
+15 -1: [Ljava/net/URL;
+37 -1: (Ljava/util/List;Ljava/lang/Object;)V
+18 -1: MAX_HIGH_SURROGATE
+6 -1: (JCZ)V
+4 -1: mark
+17 -1: setMethodAccessor
+21 -1: java/io/ExpiringCache
+21 -1: PrivilegedAction.java
+21 -1: MappedByteBuffer.java
+2 -1: FR
+10 -1: copyMemory
+8 -1: L_SERVER
+13 -1: assertionLock
+12 -1: searchValues
+46 -1: (Ljava/util/Collection<*>;Ljava/lang/Object;)I
+21 -1: ProtectionDomainCache
+32 -1: USE_PREDEFINED_INTERPRET_METHODS
+2 -1: GB
+16 -1: getFinalRefCount
+23 -1: Ljava/lang/ClassLoader;
+4 -1: mask
+94 -1: <T:Ljava/lang/Object;>(Ljava/util/function/ToDoubleFunction<-TT;>;)Ljava/util/Comparator<TT;>;
+4 -1: bind
+41 -1: (Ljava/lang/Class<*>;I)Ljava/lang/Object;
+9 -1: COUNT_GWT
+16 -1: DASH_PUNCTUATION
+24 -1: UNICODE_LOCALE_EXTENSION
+15 -1: checkInvariants
+10 -1: stringSize
+12 -1: deepHashCode
+30 -1: java/security/cert/Certificate
+19 -1: America/Los_Angeles
+19 -1: unmappableForLength
+6 -1: UTF-16
+10 -1: methodType
+21 -1: sun/misc/URLClassPath
+19 -1: META-INF/INDEX.LIST
+10 -1: jniVersion
+6 -1: IBM437
+29 -1: sun/reflect/FieldAccessorImpl
+21 -1: ()Ljava/lang/Package;
+32 -1: java/security/SecurityPermission
+57 -1: (Lsun/util/calendar/Era;)Lsun/util/calendar/CalendarDate;
+34 -1: [Ljava/util/concurrent/locks/Lock;
+11 -1: replacement
+20 -1: ()Ljava/lang/String;
+6 -1: resize
+12 -1: UTF_32BE_BOM
+26 -1: (Ljava/util/jar/JarFile;)V
+24 -1: DEFAULT_INITIAL_CAPACITY
+87 -1: (ILjava/lang/Object;Ljava/lang/Class;)Ljava/util/concurrent/ConcurrentHashMap$TreeNode;
+74 -1: (Ljava/util/jar/JarFile;)Ljava/util/Enumeration<Ljava/util/jar/JarEntry;>;
+18 -1: parameterSlotDepth
+26 -1: (Ljava/util/jar/JarFile;)Z
+18 -1: makePlatformString
+24 -1: doPrivilegedWithCombiner
+48 -1: (Ljava/lang/String;)Lsun/util/calendar/ZoneInfo;
+27 -1: ()Ljava/lang/ref/Reference;
+40 -1: java/util/ArrayList$ArrayListSpliterator
+67 -1: ([Ljava/lang/Object;IILjava/util/Comparator;[Ljava/lang/Object;II)V
+2 -1: ID
+19 -1: stringPropertyNames
+28 -1: (Ljava/util/Collections$1;)V
+12 -1: STATE_YELLOW
+12 -1: isNormalized
+10 -1: fromIndex(
+16 -1: getFloatVolatile
+37 -1: Lsun/util/calendar/BaseCalendar$Date;
+10 -1: properties
+17 -1: peakFinalRefCount
+102 -1: (Ljava/util/HashMap$Node<TK;TV;>;Ljava/util/HashMap$Node<TK;TV;>;)Ljava/util/HashMap$TreeNode<TK;TV;>;
+68 -1: (Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/DirectMethodHandle;
+2 -1: IT
+9 -1: ([BI[BI)V
+51 -1: scl           permissions SecureClassLoader assigns
+36 -1: (Ljava/util/Set;Ljava/lang/Object;)V
+11 -1: ([SII[SII)V
+21 -1: sun.io.useCanonCaches
+18 -1: Illegal capacity: 
+22 -1: (Ljava/lang/Integer;)I
+83 -1: ([Ljava/lang/Object;Ljava/lang/StringBuilder;Ljava/util/Set<[Ljava/lang/Object;>;)V
+65 -1: (Ljava/util/HashMap<TK;TV;>;[Ljava/util/HashMap$Node<TK;TV;>;II)V
+17 -1: java/util/Objects
+48 -1: (ILjava/util/List;)Ljava/lang/invoke/LambdaForm;
+31 -1: java/util/Properties$XmlSupport
+10 -1: L_LOWALPHA
+13 -1: long overflow
+25 -1: NullPointerException.java
+32 -1: (I)Ljava/lang/StackTraceElement;
+34 -1: ()[Ljava/lang/reflect/Constructor;
+2 -1: JP
+3 -1: SST
+12 -1: ShortCountry
+48 -1: (Ljava/util/stream/Collector;)Ljava/lang/Object;
+29 -1: Lsun/reflect/CallerSensitive;
+10 -1: addElement
+12 -1: lastReturned
+6 -1: putInt
+34 -1: sun.misc.JarIndex.metaInfFilenames
+13 -1: getBaseLocale
+20 -1: StringTokenizer.java
+8 -1: entrySet
+11 -1: getTypeName
+17 -1: America/Sao_Paulo
+5 -1: \t... 
+35 -1: (Lsun/util/calendar/CalendarDate;)I
+28 -1: java/lang/StackOverflowError
+35 -1: (Lsun/util/calendar/CalendarDate;)J
+10 -1: logicalAnd
+18 -1: csISOLatinCyrillic
+43 -1: (Ljava/lang/String;II)Ljava/nio/CharBuffer;
+73 -1: (Ljava/lang/Class<*>;[Ljava/lang/Class<*>;Z)Ljava/lang/invoke/MethodType;
+14 -1: aliases_MS1250
+14 -1: aliases_MS1251
+17 -1: getImplMethodKind
+17 -1: getLastAccessTime
+14 -1: aliases_MS1252
+14 -1: aliases_MS1253
+35 -1: (Lsun/util/calendar/CalendarDate;)V
+2 -1: KR
+14 -1: aliases_MS1254
+14 -1: getGenericInfo
+8 -1: utf_32be
+14 -1: aliases_MS1257
+35 -1: (Lsun/util/calendar/CalendarDate;)Z
+13 -1: StringEncoder
+7 -1: LDT2037
+7 -1: generic
+2 -1: L9
+45 -1: ([DLjava/util/function/IntToDoubleFunction;)V
+17 -1: isOtherAlphabetic
+9 -1: implWrite
+24 -1: PC-Multilingual-850+euro
+12 -1: valueMatches
+78 -1: (Ljava/lang/String;Lsun/util/locale/ParseStatus;)Lsun/util/locale/LanguageTag;
+3 -1: gmt
+19 -1: (Ljava/io/Reader;)V
+25 -1: (JJ)Ljava/nio/ByteBuffer;
+7 -1: val$url
+26 -1: (Ljava/nio/ByteBuffer;IJ)V
+10 -1: isImplicit
+19 -1: getDeclaredClasses0
+4 -1: (I)B
+4 -1: (I)C
+4 -1: (I)D
+9 -1: byteValue
+4 -1: (I)F
+5 -1: ([J)I
+6 -1: isLive
+5 -1: sleep
+4 -1: (I)I
+4 -1: (I)J
+6 -1: outBuf
+77 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractCollection<TE;>;Ljava/util/Set<TE;>;
+4 -1: (I)S
+5 -1: ([J)V
+4 -1: (I)V
+30 -1: (I[C)Ljava/lang/StringBuilder;
+14 -1: intBitsToFloat
+4 -1: (I)Z
+15 -1: MethodType.java
+14 -1: resolveSibling
+9 -1: Enum.java
+111 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;[Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;)V
+14 -1: IS_CONSTRUCTOR
+4 -1: bits
+34 -1: java/security/PermissionCollection
+9 -1: autoFlush
+21 -1: java/util/Collections
+12 -1: bindReceiver
+20 -1: DMH.invokeStaticInit
+11 -1: charsetName
+14 -1: x-utf-32be-bom
+5 -1: cause
+7 -1: handle0
+43 -1: ([I[C[Ljava/lang/invoke/LambdaForm$Name;I)Z
+30 -1: getDefaultAllowUserInteraction
+18 -1: ConcurrentMap.java
+35 -1: (Ljava/lang/String;Z)Ljava/net/URL;
+33 -1: Ljava/nio/charset/CharsetDecoder;
+36 -1: java/lang/invoke/MethodHandleStatics
+34 -1: java/util/concurrent/ConcurrentMap
+16 -1: collectArguments
+22 -1: packageAssertionStatus
+79 -1: (JLjava/util/function/ToLongFunction;JLjava/util/function/LongBinaryOperator;)J
+39 -1: Cannot reflectively create enum objects
+62 -1: attempt to add a Permission to a readonly PermissionCollection
+22 -1: FieldAccessorImpl.java
+9 -1: ByteCache
+4 -1: TRUE
+85 -1: Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/lang/Character;>;
+17 -1: java.library.path
+7 -1: encoder
+21 -1:     default locale = 
+11 -1: secondOfDay
+37 -1: (Lsun/util/calendar/ZoneInfoFile$1;)V
+35 -1: sun/reflect/UnsafeFieldAccessorImpl
+24 -1: (Ljava/lang/Object;JJJ)V
+16 -1: countStackFrames
+24 -1: (Ljava/lang/Object;JJJ)Z
+17 -1: nonfairTryAcquire
+20 -1: ArrayListSpliterator
+5 -1: /DMH=
+68 -1: (Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
+2 -1: PI
+8 -1: cspcp852
+112 -1: (Ljava/util/List<Ljava/util/Locale$LanguageRange;>;Ljava/util/Collection<Ljava/util/Locale;>;)Ljava/util/Locale;
+8 -1: cspcp855
+58 -1: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
+33 -1: sun/misc/PerfCounter$CoreCounters
+6 -1: CESU_8
+7 -1: vmslots
+4 -1: Init
+7 -1: handler
+11 -1: getProperty
+10 -1: isVolatile
+8 -1: ([J[IJ)I
+25 -1: ()Ljava/lang/ClassLoader;
+8 -1: asChange
+81 -1: (Ljava/net/URLClassLoader;Ljava/lang/String;Lsun/misc/Resource;)Ljava/lang/Class;
+12 -1: naturalOrder
+8 -1: getState
+40 -1: (Ljava/lang/Object;I)[Ljava/lang/String;
+36 -1: java/security/AccessControlException
+10 -1: linkBefore
+48 -1: (Ljava/util/HashMap;[Ljava/util/HashMap$Node;Z)V
+26 -1: (Ljava/util/WeakHashMap;)V
+23 -1: bad method type alias: 
+7 -1: putChar
+18 -1: basicTypeSignature
+33 -1: sun/misc/InvalidJarIndexException
+13 -1: getPrivateuse
+14 -1: isConstantZero
+24 -1: java/io/FilePermission$1
+9 -1: Long.java
+19 -1: getLocaleExtensions
+10 -1: discovered
+17 -1: Invalid file path
+12 -1: MAX_MH_ARITY
+20 -1: observesDaylightTime
+31 -1: Ljava/lang/invoke/MethodHandle;
+6 -1: , end 
+24 -1: java/io/FileDescriptor$1
+12 -1: loadLibrary.
+11 -1: Method.java
+12 -1: loadLibrary0
+23 -1: java/util/stream/Stream
+37 -1: sun.lang.ClassLoader.allowArraySyntax
+8 -1: appClass
+15 -1: FileReader.java
+5 -1: (IF)I
+29 -1: [Ljava/lang/ClassValue$Entry;
+12 -1: (principals 
+30 -1: jar           jar verification
+22 -1: ARRAY_CHAR_BASE_OFFSET
+18 -1: newDirectoryStream
+4 -1: atan
+5 -1: (IF)V
+24 -1: (Ljava/lang/Character;)I
+2 -1: TH
+10 -1: startsWith
+9 -1: baseCount
+13 -1: canonicalize0
+47 -1: (Ljava/lang/ClassLoader;[Ljava/lang/Class<*>;)V
+22 -1: Ljava/io/OutputStream;
+2 -1: TW
+10 -1: H_RESERVED
+19 -1: URLClassLoader.java
+16 -1: isAccessibleFrom
+59 -1: Ljava/util/Hashtable<Ljava/lang/Object;Ljava/lang/Object;>;
+33 -1: java/lang/invoke/ConstantCallSite
+14 -1: Ljava/net/URL;
+12 -1: deleteOnExit
+20 -1: MAX_SKIP_BUFFER_SIZE
+30 -1: [Ljava/lang/ref/WeakReference;
+15 -1: contentPathProp
+9 -1: initCause
+53 -1: (Ljava/util/Queue;Ljava/lang/Class;)Ljava/util/Queue;
+20 -1: java/util/TimeZone$1
+2 -1: UK
+86 -1: (BLjava/lang/Class;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/DirectMethodHandle;
+51 -1: (II[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+18 -1: Lsun/misc/Cleaner;
+31 -1: RuntimeInvisibleTypeAnnotations
+2 -1: US
+7 -1: makeInt
+40 -1: sun/reflect/annotation/AnnotationSupport
+28 -1: sun/reflect/misc/ReflectUtil
+8 -1: utf_32le
+40 -1: (Ljava/lang/Object;JLjava/lang/Object;)V
+24 -1: java/nio/file/WatchEvent
+66 -1: (Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/invoke/MethodType;
+91 -1: (Ljava/lang/String;[BIILjava/security/ProtectionDomain;Ljava/lang/String;)Ljava/lang/Class;
+114 -1: (Ljava/lang/ThreadLocal;ILjava/lang/ThreadLocal$ThreadLocalMap$Entry;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+20 -1: internalWriteEntries
+79 -1: <T:Ljava/lang/Object;>(TT;Ljava/util/function/Supplier<Ljava/lang/String;>;)TT;
+14 -1: bitIndex < 0: 
+88 -1: (Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;
+6 -1: , len 
+28 -1: java/io/BufferedOutputStream
+11 -1: System.java
+11 -1: csISOLatin1
+11 -1: csISOLatin2
+28 -1: Ljava/io/OutputStreamWriter;
+27 -1: IllegalAccessException.java
+11 -1: csISOLatin4
+14 -1: isDaylightTime
+11 -1: csISOLatin5
+21 -1: getYearLengthInMonths
+13 -1: canonicalizes
+93 -1: "'s signer information does not match signer information of other classes in the same package
+32 -1: ()Lsun/management/GcInfoBuilder;
+37 -1: (IILjava/nio/charset/CoderResult$1;)V
+10 -1: stateNames
+46 -1: (Ljava/lang/String;)Ljava/nio/charset/Charset;
+21 -1: acquireMethodAccessor
+2 -1: X-
+32 -1: java/security/ProtectionDomain$1
+5 -1: atan2
+32 -1: java/security/ProtectionDomain$2
+32 -1: java/security/ProtectionDomain$3
+41 -1: malformed input: partial character at end
+18 -1: dropParameterTypes
+44 -1: (Ljava/lang/String;)Ljava/lang/StringBuffer;
+18 -1: CalendarUtils.java
+5 -1: month
+84 -1: Ljava/lang/Object;Ljava/security/PrivilegedExceptionAction<Ljava/lang/ClassLoader;>;
+33 -1: sun/misc/JavaNioAccess$BufferPool
+18 -1: SearchMappingsTask
+38 -1: DelegatingConstructorAccessorImpl.java
+80 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/Class<*>;)Ljava/lang/invoke/MemberName;
+8 -1: instance
+54 -1: Parameter annotations don't match number of parameters
+14 -1: createConstant
+35 -1: java/lang/invoke/MemberName$Factory
+4 -1: scrt
+34 -1: Ljava/lang/InstantiationException;
+20 -1: allowUserInteraction
+15 -1: java/util/Deque
+16 -1: forEachRemaining
+35 -1: (J)Lsun/util/calendar/CalendarDate;
+13 -1: no such field
+25 -1: java/nio/file/FileSystems
+16 -1: expectedModCount
+44 -1: (Ljava/io/File;ILjava/nio/charset/Charset;)V
+12 -1: createString
+15 -1: useDaylightTime
+31 -1: java/util/Properties$LineReader
+111 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Class<*>;I[Ljava/lang/invoke/MemberName;)I
+16 -1: java/util/Locale
+26 -1: URLClassPath.getResource("
+58 -1: (Ljava/util/SortedMap;Ljava/lang/Class;Ljava/lang/Class;)V
+10 -1: appendTail
+7 -1: cleaner
+78 -1: (Lsun/nio/cs/FastCharsetProvider;Ljava/lang/String;)Ljava/nio/charset/Charset;
+18 -1: convertOldISOCodes
+4 -1: year
+38 -1: java/lang/ReflectiveOperationException
+28 -1: (Ljava/lang/StringBuffer;B)V
+27 -1: (D)Ljava/lang/StringBuffer;
+17 -1: emptyNavigableSet
+7 -1: indices
+10 -1:  is sealed
+21 -1: SPECIFICATION_VERSION
+3 -1: TE;
+8 -1: addMonth
+24 -1: java/util/HashMap$Values
+17 -1: SEARCH_ALL_SUPERS
+18 -1: uncaught exception
+14 -1: declaredFields
+2 -1: [B
+2 -1: [C
+8 -1: ABSTRACT
+2 -1: [D
+2 -1: [F
+2 -1: [I
+2 -1: [J
+5 -1: false
+36 -1: (Ljava/net/URL;Ljava/lang/String;J)V
+12 -1: equalContext
+11 -1: VOID_RESULT
+2 -1: [S
+24 -1: (JLjava/lang/Object;JJ)V
+36 -1: Ljava/security/PermissionCollection;
+2 -1: [Z
+17 -1: floatToRawIntBits
+2 -1: []
+21 -1: ()[Ljava/lang/Thread;
+20 -1: [Ljava/lang/Integer;
+42 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Z)V
+19 -1: checkPrintJobAccess
+40 -1: (Ljava/lang/Object;)Ljava/lang/Class<*>;
+31 -1: (Lsun/reflect/FieldAccessor;Z)V
+10 -1: reallyPoll
+52 -1: (Ljava/lang/ref/Reference;)Ljava/lang/ref/Reference;
+100 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<-TV;+TU;>;Ljava/util/function/Consumer<-TU;>;)V
+19 -1: CheckedNavigableMap
+48 -1: (Ljava/lang/String;)Ljava/lang/RuntimeException;
+35 -1: java/util/Hashtable$ValueCollection
+89 -1: (JLjava/util/function/ToDoubleFunction<-TK;>;DLjava/util/function/DoubleBinaryOperator;)D
+10 -1: Stack.java
+57 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;I)V
+12 -1: getTimeOfDay
+12 -1: reduceValues
+22 -1: warnUnsupportedCharset
+34 -1: (Ljava/lang/ref/Reference<+TS;>;)Z
+31 -1: EEE, dd MMM yyyy HH:mm:ss 'GMT'
+19 -1: setCachedLambdaForm
+21 -1: (I)Ljava/lang/Object;
+85 -1: (Lsun/util/locale/BaseLocale;Lsun/util/locale/LocaleExtensions;Ljava/util/Locale$1;)V
+36 -1: java/security/AccessControlContext$1
+27 -1: Lsun/net/www/MessageHeader;
+23 -1: ()[Ljava/lang/Class<*>;
+14 -1: refKindIsValid
+41 -1: sun/reflect/NativeConstructorAccessorImpl
+6 -1: binary
+23 -1: ()Ljava/nio/CharBuffer;
+8 -1: getSpace
+45 -1: bootstrap method failed to produce a CallSite
+15 -1: getISO3Language
+17 -1: TRANSITION_NSHIFT
+163 -1: ([Ljava/lang/String;Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;>;)Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;>;
+7 -1: os.name
+38 -1: java/util/function/IntToDoubleFunction
+8 -1: checkInt
+21 -1: java/lang/VerifyError
+42 -1: sunpkcs11     SunPKCS11 provider debugging
+19 -1: URI is not absolute
+23 -1: java/io/DataInputStream
+53 -1: (Ljava/lang/Object;)Ljava/nio/charset/CharsetEncoder;
+2 -1: _#
+41 -1: (Ljava/io/FilenameFilter;)[Ljava/io/File;
+26 -1: Ljava/util/jar/Attributes;
+7 -1: collect
+17 -1: Lsun/misc/Unsafe;
+97 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
+78 -1: <T:Ljava/lang/Object;>(Ljava/util/Enumeration<TT;>;)Ljava/util/ArrayList<TT;>;
+28 -1: (II)Ljava/lang/StringBuffer;
+54 -1: (Ljava/lang/reflect/Constructor<*>;)Ljava/lang/String;
+28 -1: ()Ljava/util/ResourceBundle;
+48 -1: java/util/ArraysParallelSortHelpers$FJInt$Sorter
+9 -1: no access
+57 -1: <S:Ljava/lang/Object;>Ljava/lang/ref/ReferenceQueue<TS;>;
+7 -1: getPerf
+11 -1: getClassAt0
+11 -1: rtypeOffset
+20 -1: thread can't be null
+12 -1: addArguments
+12 -1: utf_32le_bom
+21 -1: allowThreadSuspension
+25 -1: defaultExpectedLineLength
+11 -1: removeFirst
+13 -1: reduceEntries
+20 -1: Read-ahead limit < 0
+57 -1: <T:Ljava/lang/Object;>(Ljava/util/Collection<-TT;>;[TT;)Z
+39 -1: ()Ljava/lang/invoke/MemberName$Factory;
+13 -1: ZipCoder.java
+16 -1: java/lang/Thread
+27 -1: java/lang/NoSuchMethodError
+66 -1: (Ljava/util/jar/JarFile;Ljava/net/URL;)[Ljava/security/CodeSource;
+22 -1: java/lang/StringBuffer
+3 -1: TK;
+34 -1: (I)Ljava/lang/invoke/MethodHandle;
+30 -1: (Ljava/lang/reflect/Method;Z)V
+13 -1: file.encoding
+14 -1: removeTreeNode
+27 -1: sun/misc/JavaSecurityAccess
+58 -1: ([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;
+19 -1: equalLimitedContext
+22 -1: appendVmSynonymMessage
+10 -1: applyAsInt
+23 -1: privateGetPublicMethods
+11 -1: dumpThreads
+25 -1: RuntimeVisibleAnnotations
+37 -1: (IF)Ljava/lang/AbstractStringBuilder;
+18 -1: getBooleanVolatile
+27 -1: (Ljava/util/zip/ZipFile;J)V
+25 -1: INITIAL_QUOTE_PUNCTUATION
+51 -1: (Ljava/util/Map;)[Ljava/lang/annotation/Annotation;
+54 -1: (ILjava/lang/Object;)Ljava/lang/AbstractStringBuilder;
+20 -1: reflectionDataOffset
+2 1: aa
+51 -1: (Ljava/util/jar/Attributes$Name;)Ljava/lang/String;
+13 -1: transferLinks
+18 -1: java/util/Vector$1
+10 -1: ensureOpen
+22 -1: getDeclaredConstructor
+2 -1: am
+19 -1: NF_allocateInstance
+66 -1: (Ljava/util/Spliterator$OfDouble;Z)Ljava/util/stream/DoubleStream;
+6 -1: ([SS)I
+17 -1: newReflectionData
+19 -1: subclassAuditsQueue
+11 -1: access$1200
+16 -1: ValueSpliterator
+18 -1: preparedLambdaForm
+38 -1: (Ljava/net/URL;)Ljava/net/InetAddress;
+14 -1: getMaxPriority
+32 -1: ()[Ljava/lang/StackTraceElement;
+67 -1: java/util/concurrent/ConcurrentHashMap$MapReduceEntriesToDoubleTask
+62 -1: (Ljava/util/Hashtable<Ljava/lang/String;Ljava/lang/String;>;)V
+6 -1: EXTHDR
+14 -1: java/util/Date
+2 -1: az
+6 -1: ([SS)V
+15 -1: arrayBaseOffset
+9 -1: isTrusted
+23 -1: (Ljava/lang/Object;JD)V
+2 -1: bb
+10 -1: ([BII[BI)V
+7 -1: toLower
+14 -1: invoke_LLLLL_L
+7 -1: jarfile
+42 -1: (Ljava/lang/String;)Lsun/misc/PerfCounter;
+28 -1: java/lang/ref/Reference$Lock
+16 -1: java/util/BitSet
+22 -1: jarfile parsing error!
+18 -1: jdk_update_version
+14 -1: invoke_LLLLL_V
+20 -1: java/util/LinkedList
+22 -1: erasedInvokerWithDrops
+25 -1: timeout value is negative
+21 -1: getCalendarProperties
+25 -1: not a method descriptor: 
+2 -1: cb
+31 -1: (Lsun/misc/JavaUtilJarAccess;)V
+2 -1: cd
+43 -1: Lsun/util/PreHashedMap<Ljava/lang/String;>;
+12 -1: getEntrySize
+2 -1: ce
+24 -1: guessContentTypeFromName
+2 -1: ch
+14 -1: JulianCalendar
+22 -1: [Ljava/lang/Cloneable;
+122 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractCollection<TE;>;Ljava/util/Deque<TE;>;Ljava/lang/Cloneable;Ljava/io/Serializable;
+34 -1: Lsun/util/locale/BaseLocale$Cache;
+14 -1: LinkedEntrySet
+72 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractSet<TE;>;Ljava/io/Serializable;
+39 -1: ()Ljava/io/ObjectOutputStream$PutField;
+2 -1: cs
+8 -1: indexFor
+25 -1: (Ljava/util/List<+TE;>;)V
+7 -1: subpath
+11 -1: invokeExact
+14 -1: setFileNameMap
+22 -1: LangReflectAccess.java
+8 -1: referent
+34 -1: java/util/MissingResourceException
+77 -1: (Ljava/lang/String;Ljava/util/jar/Manifest;Ljava/net/URL;)Ljava/lang/Package;
+11 -1: ([FII[FII)V
+17 -1: getParameterCount
+18 -1: isMemberAccessible
+10 -1: getExtDirs
+69 -1: <T:Ljava/lang/Object;>(Ljava/util/List<-TT;>;Ljava/util/List<+TT;>;)V
+9 -1: getNextPC
+13 -1: setProperties
+2 -1: de
+16 -1: generateCertPath
+6 -1: decode
+16 -1: getDefaultParent
+50 -1: (Ljava/net/URL;[Ljava/security/cert/Certificate;)V
+24 -1: Certificate factory for 
+35 -1: ()Ljava/lang/reflect/AnnotatedType;
+2 -1: ee
+12 -1: asLongBuffer
+7 -1: PRIVATE
+16 -1: aliases_UTF_32BE
+2 -1: en
+2 -1: eq
+7 -1: indexOf
+136 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class<+Ljava/lang/Throwable;>;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;
+24 -1: (Ljava/lang/Class<*>;I)V
+72 -1: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/IllegalAccessException;
+35 -1: java/util/jar/JavaUtilJarAccessImpl
+24 -1: (Ljava/lang/Class<*>;I)Z
+2 -1: ex
+24 -1: getProtectionDomainCache
+101 -1: (Ljava/lang/ThreadGroup;Ljava/lang/Runnable;Ljava/lang/String;JLjava/security/AccessControlContext;)V
+3 -1: hit
+8 -1: UTF_16BE
+2 -1: fd
+16 -1: EmptyEnumeration
+4 -1: attr
+16 -1: fromIndex < -1: 
+7 -1: getIntB
+22 -1: java/io/FilePermission
+2 -1: fr
+2 -1: fs
+7 -1: lazySet
+7 -1: getIntL
+37 -1: configfile    JAAS ConfigFile loading
+24 -1: sun/nio/cs/StreamEncoder
+40 -1: (Ljava/time/ZoneId;)Ljava/util/TimeZone;
+132 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/function/BiConsumer;)V
+2 -1: gc
+18 -1: Ljava/lang/Thread;
+10 -1: cacheArray
+48 -1: (Ljava/util/jar/JarFile;)Ljava/util/jar/JarFile;
+61 -1: (Ljava/util/NavigableMap;Ljava/lang/Class;Ljava/lang/Class;)V
+8 -1: readByte
+7 -1: ([S[S)Z
+24 -1: findBootstrapClassOrNull
+2 -1: hb
+7 -1: REPLACE
+45 -1: ()Ljava/util/Enumeration<Ljava/lang/String;>;
+10 -1: isOverflow
+2 -1: he
+13 -1: getCachedJan1
+12 -1: getClassPath
+8 -1: leapYear
+31 -1: java/lang/invoke/MethodTypeForm
+10 -1: ANNOTATION
+20 -1: getGregorianCalendar
+11 -1: ISO_8859_13
+11 -1: ISO_8859_15
+6 -1: invoke
+2 -1: ht
+7 -1: ListItr
+15 -1: synchronizedMap
+7 -1: cleanup
+94 -1: (Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;)Lsun/reflect/annotation/AnnotationType;
+3 -1: TT;
+69 -1: (JLsun/util/calendar/CalendarDate;)Lsun/util/calendar/Gregorian$Date;
+81 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/HashMap$TreeNode<TK;TV;>;)Z
+20 -1:     Min. Heap Size: 
+33 -1: (IZ)Ljava/lang/invoke/MethodType;
+2 -1: id
+7 -1: ([DI)[D
+37 -1: (Ljava/lang/reflect/Constructor<*>;)I
+42 -1: <T::Ljava/lang/Comparable<-TT;>;>([TT;II)V
+13 -1: addSuppressed
+28 -1: internalMemberNameEnsureInit
+2 -1: in
+17 -1: getCompressedSize
+34 -1: sun/misc/Launcher$AppClassLoader$1
+88 -1: (Ljava/security/DomainCombiner;Ljava/lang/Class<*>;)Ljava/security/AccessControlContext;
+37 -1: (Ljava/lang/reflect/Constructor<*>;)V
+2 -1: is
+2 -1: it
+6 -1: ENDOFF
+4 -1: void
+2 -1: iw
+14 -1: emptySortedSet
+2 -1: ix
+17 -1: unicode-1-1-utf-8
+64 -1: (Ljava/lang/Class;Ljava/util/List;)Ljava/lang/invoke/MethodType;
+46 -1: (Lsun/misc/URLClassPath$Loader;)Ljava/net/URL;
+2 -1: ja
+13 -1: synchronized 
+76 -1: ([DLjava/util/function/IntToDoubleFunction;)Ljava/util/function/IntConsumer;
+11 -1: wrapperType
+51 -1: <T:Ljava/lang/Object;>()Ljava/util/Comparator<TT;>;
+106 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/Object;
+17 -1: removeAllElements
+2 -1: ji
+24 -1: java/util/Vector$ListItr
+14 -1: getNestedTypes
+6 -1: L_MARK
+27 -1: Source does not fit in dest
+2 -1: l1
+2 -1: jp
+2 -1: l2
+4 -1: (J)B
+57 -1: (Ljava/lang/String;Ljava/util/Locale;I)Ljava/lang/String;
+4 -1: (J)C
+27 -1: ForEachTransformedValueTask
+2 -1: l4
+26 -1: java/util/Hashtable$KeySet
+4 -1: (J)D
+2 -1: l5
+39 -1: java/security/BasicPermissionCollection
+4 -1: (J)F
+2 -1: jv
+29 -1: MapReduceMappingsToDoubleTask
+18 -1: copyFromShortArray
+2 -1: l9
+3 -1: TV;
+4 -1: (J)I
+4 -1: (J)J
+23 -1: Lsun/util/calendar/Era;
+8 -1: x-EUC-TW
+15 -1: checkSetFactory
+7 -1: Special
+4 -1: (J)S
+4 -1: (J)V
+7 -1: invoke_
+25 -1: (IC)Ljava/nio/ByteBuffer;
+68 -1: (JLjava/util/concurrent/TimeUnit;)Ljava/nio/file/attribute/FileTime;
+36 -1: ()Ljava/net/URLStreamHandlerFactory;
+4 -1: (J)Z
+181 -1: <T:Ljava/lang/Object;>(Ljava/lang/Class<*>;Ljava/lang/ref/SoftReference<Ljava/lang/Class$ReflectionData<TT;>;>;Ljava/lang/ref/SoftReference<Ljava/lang/Class$ReflectionData<TT;>;>;)Z
+9 -1: getOffset
+46 -1: (ILjava/lang/String;)Ljava/lang/StringBuilder;
+7 -1: element
+15 -1: createByteArray
+17 -1: uncaughtException
+2 -1: ko
+29 -1: java/nio/file/DirectoryStream
+15 -1: getISOCountries
+246 -1: <NoSuchMemberException:Ljava/lang/ReflectiveOperationException;>(BLjava/lang/invoke/MemberName;Ljava/lang/Class<*>;Ljava/lang/Class<TNoSuchMemberException;>;)Ljava/lang/invoke/MemberName;^Ljava/lang/IllegalAccessException;^TNoSuchMemberException;
+7 -1: invoker
+17 -1: langReflectAccess
+10 -1: bindSingle
+23 -1: java/lang/reflect/Proxy
+2 -1: lb
+2 -1: lc
+29 -1: CREATE_CLASSLOADER_PERMISSION
+5 -1: isSet
+18 -1: ([Ljava/io/File;)V
+15 -1: urlNoFragString
+21 -1: DirectByteBuffer.java
+15 -1: java.class.path
+15 -1: createDirectory
+4 -1:  GMT
+37 -1: sun/reflect/annotation/ExceptionProxy
+28 -1: (Ljava/util/Map<+TK;+TV;>;)V
+17 -1: getContentHandler
+26 -1: GenericDeclRepository.java
+56 -1: (Ljava/lang/String;)Ljava/lang/IllegalArgumentException;
+15 -1: getJavaIOAccess
+39 -1: java/util/Collections$EmptyListIterator
+34 -1: java/lang/ConditionalSpecialCasing
+82 -1: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/management/GarbageCollectorMBean;
+58 -1: (Ljava/util/function/ToIntFunction;)Ljava/util/Comparator;
+21 -1: ()Lsun/misc/Launcher;
+2 -1: lt
+92 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;IIILjava/util/concurrent/ConcurrentHashMap;)V
+8 -1: disjoint
+62 -1: (Ljava/net/URL;Ljava/lang/String;Ljava/net/URLStreamHandler;)V
+24 -1: ([Ljava/lang/Object;)TT;
+4 -1: lmap
+8 -1: SATURDAY
+12 -1: toStringUTF8
+91 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BinaryOperator;)Ljava/lang/Object;
+46 -1: pkcs11        PKCS11 session manager debugging
+27 -1: (Z)Ljava/lang/StringBuffer;
+7 -1: forEach
+17 -1: (Ljava/io/File;)I
+17 -1: (Ljava/io/File;)J
+5 -1: RESET
+6 -1: isFile
+14 -1: Exception.java
+8 -1: isPublic
+27 -1: computeInitialPreparedForms
+50 -1: (BZLjava/lang/Class;)Ljava/lang/invoke/LambdaForm;
+19 -1: getAvailableLocales
+17 -1: (Ljava/io/File;)V
+28 -1: ()Ljava/nio/charset/Charset;
+10 -1: appendNull
+17 -1: (Ljava/io/File;)Z
+23 -1: java/lang/InternalError
+2 -1: ne
+6 -1: radix 
+8 -1: checksum
+66 -1: (Lsun/net/www/MessageHeader;Ljava/lang/String;Ljava/lang/Object;)V
+45 -1: (Ljava/io/FilenameFilter;)[Ljava/lang/String;
+8 -1: checkJar
+28 -1:     default format locale = 
+13 -1: normalizeTime
+26 -1: java/util/AbstractList$Itr
+30 -1: java/util/function/IntFunction
+7 -1: TIS-620
+12 -1: reverseBytes
+2 -1: of
+26 -1: java/lang/ClassFormatError
+109 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+10 -1: delimiters
+20 -1: indexOfSupplementary
+16 -1: aliases_UTF_32LE
+134 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Map<TK;TV;>;Ljava/lang/Class<TK;>;Ljava/lang/Class<TV;>;)Ljava/util/Map<TK;TV;>;
+17 -1: [Ljava/lang/Long;
+2 -1: or
+12 -1: getClassName
+31 -1: (Ljava/nio/charset/Charset;FF)V
+6 -1: ([FF)I
+39 -1: (Ljava/util/Locale;)[Ljava/lang/String;
+33 -1: java/util/WeakHashMap$KeyIterator
+8 -1: UTF_16LE
+12 -1: isISOControl
+75 -1: (Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;Z)Ljava/nio/charset/CoderResult;
+7 -1: ([I[I)Z
+28 -1: Self-causation not permitted
+6 -1: ([FF)V
+14 -1: defaultCharset
+12 -1: isJavaLetter
+2 -1: pm
+39 -1: cannot reflectively invoke MethodHandle
+20 -1: getSystemClassLoader
+42 -1: ([Ljava/lang/Object;IILjava/lang/Object;)I
+56 -1: (Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;
+42 -1: ([Ljava/lang/Object;IILjava/lang/Object;)V
+12 -1: ZipFile.java
+43 -1: (Ljava/util/zip/ZipFile;)Ljava/lang/String;
+22 -1: Ljava/net/InetAddress;
+15 -1: getCharVolatile
+32 -1: ()[Ljava/lang/reflect/Parameter;
+13 -1: delimsChanged
+13 -1: getFileSystem
+13 -1: METHOD_RETURN
+20 -1: sun/misc/PerfCounter
+61 -1: (Ljava/util/HashMap<TK;TV;>;)Ljava/util/HashMap$Node<TK;TV;>;
+8 -1: newIndex
+18 -1: getDisplayLanguage
+36 -1: (C)Ljava/lang/AbstractStringBuilder;
+36 -1: java/lang/StringCoding$StringEncoder
+12 -1: forEachEntry
+23 -1: [Ljava/io/Serializable;
+13 -1: totalCapacity
+26 -1: java/io/FileOutputStream$1
+14 -1: signatureArity
+90 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/security/cert/Certificate;)V
+17 -1: reflectionFactory
+6 -1: ibm737
+17 -1: fillInStackTrace0
+16 -1: allocateInstance
+52 -1: (Lsun/util/locale/BaseLocale$Key;)Ljava/lang/String;
+9 -1: addExtURL
+16 -1: copyFromIntArray
+65 -1: (Ljava/security/Permission;Z)Ljava/security/PermissionCollection;
+57 -1: java/util/concurrent/ConcurrentHashMap$SearchMappingsTask
+10 -1: toEpochDay
+4 -1: gate
+24 -1: sun/nio/cs/UTF_8$Decoder
+8 -1: entries2
+18 -1: isCharsetSupported
+10 -1: toCustomID
+2 -1: rw
+33 -1: java/nio/ByteBufferAsFloatBufferB
+25 -1: (ID)Ljava/nio/ByteBuffer;
+12 -1: addTimeOfDay
+61 -1: (Ljava/security/ProtectionDomain;Ljava/security/Permission;)Z
+2 -1: sd
+25 -1: (Ljava/net/InetAddress;)V
+33 -1: java/nio/ByteBufferAsFloatBufferL
+2 -1: se
+15 -1: hasQueuedThread
+24 -1: assertMemberIsConsistent
+37 -1: java/util/Collections$UnmodifiableMap
+2 -1: sp
+20 -1: setJavaUtilJarAccess
+96 -1: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
+8 -1: language
+76 -1: <T:Ljava/lang/Object;>(Ljava/util/SortedSet<TT;>;)Ljava/util/SortedSet<TT;>;
+11 -1: findLibrary
+61 -1: (Ljava/lang/Class<*>;)Lsun/reflect/annotation/AnnotationType;
+6 -1: ([BZ)V
+24 -1: DEFAULT_BYTE_BUFFER_SIZE
+25 -1: (Ljava/util/ArrayList;I)V
+2 -1: th
+47 -1: (Ljava/util/Collection;)Ljava/util/Enumeration;
+49 -1: (Lsun/misc/URLClassPath$JarLoader;)Ljava/net/URL;
+7 -1: ([D[D)Z
+2 -1: to
+22 -1: java/util/Locale$Cache
+8 -1: iterator
+30 -1: (Ljava/lang/StringBuilder;IZ)V
+17 -1: ()Ljava/util/Set;
+2 -1: tr
+27 -1: (Ljava/nio/ByteBuffer;ISZ)V
+6 -1: method
+13 -1: allPermission
+9 -1: ruleArray
+8 -1: UTC_TIME
+10 -1: LF_COUNTER
+26 -1: Lsun/nio/cs/StreamDecoder;
+25 -1: ()Lsun/util/calendar/Era;
+6 -1: LOCHDR
+21 -1: sun/net/www/MimeTable
+12 -1: Cannot cast 
+2 -1: us
+2 -1: ut
+52 -1: Ljava/lang/invoke/MethodHandle$PolymorphicSignature;
+6 -1: encode
+15 -1: CharBuffer.java
+24 -1: (C)Ljava/nio/ByteBuffer;
+56 -1: (Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;)V
+18 -1: getEnclosingMethod
+56 -1: (Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;)Z
+6 -1: ibm775
+9 -1: (IIIIII)I
+44 -1: ([JLjava/util/function/IntToLongFunction;I)V
+9 -1: (IIIIII)J
+64 -1: (Ljava/util/Locale$LocaleKey;)Lsun/util/locale/LocaleExtensions;
+2 -1: x-
+2 -1: vm
+5 -1: clock
+9 -1: (IIIIII)V
+10 -1: XmlSupport
+19 -1: sun/nio/cs/US_ASCII
+10 -1: toRealPath
+5 -1: cp367
+6 -1: ST_END
+58 -1: [Lsun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule;
+12 -1: hasSameRules
+108 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lsun/util/locale/LocaleExtensions;
+22 -1: java/lang/Class$Atomic
+4 -1: sync
+6 -1: listen
+12 -1: firstElement
+142 -1: (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/Class;[Ljava/lang/Class;IILjava/lang/String;[B[B[B)Ljava/lang/reflect/Method;
+18 -1: internalProperties
+28 -1: (Ljava/lang/StringBuffer;C)V
+7 -1: factory
+18 -1: ()Ljava/util/List;
+50 -1: (Ljava/util/concurrent/CountedCompleter;[D[DIIII)V
+44 -1: (Ljava/lang/Class;)Lsun/invoke/util/Wrapper;
+83 -1: (JLjava/util/function/ToDoubleFunction;DLjava/util/function/DoubleBinaryOperator;)D
+12 -1: erasedType: 
+53 -1: (Ljava/util/AbstractList;Ljava/util/AbstractList$1;)V
+20 -1: Cannot find package 
+27 -1: java/util/ArrayList$ListItr
+10 -1: copyMethod
+23 -1: java/lang/ThreadLocal$1
+16 -1: iso_646.irv:1983
+42 -1: (Ljava/lang/Thread;Ljava/lang/Throwable;)V
+19 -1: DEFAULT_LOAD_FACTOR
+40 -1: ([Ljava/lang/Object;)[Ljava/lang/Object;
+10 -1: (JJJ[BII)I
+12 -1: singletonMap
+8 -1: RESERVED
+9 -1: zipAccess
+21 -1: SynchronizedSortedMap
+4 -1: flag
+15 -1: UnmodifiableSet
+18 -1: WrappedPrintWriter
+7 -1: resume0
+2 -1: yi
+10 -1: erasedType
+31 -1: CHECK_AWT_EVENTQUEUE_PERMISSION
+8 -1: <clinit>
+59 -1: (Ljava/lang/String;)Ljava/security/cert/CertificateFactory;
+40 -1: java/lang/management/MemoryManagerMXBean
+33 -1: newGetIntIllegalArgumentException
+16 -1: iso_646.irv:1991
+58 -1: (Ljava/lang/ClassValue$Entry;)Ljava/lang/ClassValue$Entry;
+2 -1: zc
+26 -1: (Ljava/util/AbstractMap;)V
+6 -1: THROWS
+11 -1: toCharArray
+64 -1: (Ljava/lang/reflect/Constructor;)Ljava/lang/reflect/Constructor;
+2 -1: zh
+68 -1: Ljava/lang/ref/SoftReference<Ljava/lang/Class$ReflectionData<TT;>;>;
+25 -1: (Ljava/util/Collection;)V
+20 -1: getJdkSpecialVersion
+17 -1: getTypeParameters
+32 -1: [Ljava/lang/ClassValue$Entry<*>;
+25 -1: (Ljava/util/Collection;)Z
+26 -1: Lsun/nio/ch/Interruptible;
+5 -1: 0.0p0
+5 -1: CACHE
+7 -1: namesOK
+21 -1: Ljava/lang/Exception;
+51 -1: (Ljava/net/URL;Lsun/net/www/protocol/jar/Handler;)V
+19 -1: jdk_special_version
+66 -1: <T:Ljava/lang/Object;>(Ljava/util/List<TT;>;)Ljava/util/List<TT;>;
+75 -1: (Ljava/util/Comparator;Ljava/util/function/Function;)Ljava/util/Comparator;
+11 -1: Arrays.java
+19 -1: (Ljava/lang/Byte;)I
+17 -1: java/lang/Class$1
+17 -1: java/lang/Class$2
+17 -1: java/lang/Class$3
+47 -1: java/lang/invoke/MethodHandleImpl$WrappedMember
+17 -1: java/lang/Class$4
+44 -1: (Ljava/lang/Throwable;)Ljava/lang/Throwable;
+9 -1: charCount
+24 -1: ()Ljava/net/FileNameMap;
+44 -1: sun/util/locale/provider/TimeZoneNameUtility
+17 -1: not an array type
+2 -1: {}
+24 -1: (Lsun/misc/Launcher$1;)V
+12 -1: directMemory
+10 -1: parameters
+5 -1: java.
+14 -1: allocateDirect
+51 -1: (Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;
+23 -1: java/nio/file/Watchable
+37 -1: createDiagnosticFrameworkNotification
+54 -1: (Ljava/lang/Class<*>;Z)Ljava/lang/invoke/MethodHandle;
+35 -1: sun/nio/cs/StandardCharsets$Aliases
+9 -1: retDelims
+11 -1: MAX_ENTRIES
+12 -1: CumulateTask
+64 -1: java/util/concurrent/ConcurrentHashMap$ForEachTransformedKeyTask
+3 -1: iae
+12 -1: AF_PUTSTATIC
+21 -1: java/lang/Throwable$1
+45 -1: (Ljava/util/HashMap;)Ljava/util/HashMap$Node;
+77 -1: (JLjava/util/function/ToIntFunction;ILjava/util/function/IntBinaryOperator;)I
+5 -1: after
+29 -1: (Ljava/security/CodeSource;)Z
+248 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceValuesToDoubleTask;Ljava/util/function/ToDoubleFunction;DLjava/util/function/DoubleBinaryOperator;)V
+6 -1: H_URIC
+7 -1: L_DIGIT
+7 -1: toNanos
+24 -1: (D)Ljava/nio/ByteBuffer;
+25 -1: getDiagnosticCommandMBean
+6 2: [LFoo;
+14 -1: path.separator
+16 -1: toUnsignedString
+40 -1: DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+87 -1: (Ljava/security/Permission;[Ljava/security/cert/Certificate;)Ljava/security/Permission;
+16 -1: inheritedChannel
+11 -1: audio/basic
+27 -1: sun.classloader.findClasses
+10 -1: queryCount
+20 -1: NF_ensureInitialized
+12 -1: getBufIfOpen
+23 -1: sun/nio/cs/UTF_16LE_BOM
+134 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
+17 -1: getImplMethodName
+14 -1: linkMethod => 
+25 -1: Ljava/lang/invoke/Stable;
+32 -1: Ljava/lang/annotation/Retention;
+7 -1: doInput
+9 -1: -_.!~*'()
+62 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Class<*>;B)V
+18 -1: separateWithCommas
+43 -1: com/sun/crypto/provider/CipherBlockChaining
+14 -1: createTempFile
+9 -1: implFlush
+20 -1: getOffsetsByStandard
+21 -1: OutOfMemoryError.java
+7 -1: jce.jar
+46 -1: java/util/Collections$UnmodifiableNavigableMap
+30 -1: (Ljava/io/File;)Ljava/io/File;
+15 -1: LinkedList.java
+15 -1: iso_8859-9:1989
+50 -1: sun/reflect/generics/factory/CoreReflectionFactory
+10 -1: : JVM has 
+19 -1: HeapByteBuffer.java
+6 -1: getURL
+37 -1: java/security/cert/CertificateFactory
+23 -1: getAllowUserInteraction
+12 -1: otherParents
+25 -1: ARRAY_BOOLEAN_BASE_OFFSET
+9 -1: L_UPALPHA
+41 -1: ([Ljava/util/Hashtable$Entry<**>;TK;TV;)V
+6 -1: LOCHOW
+11 -1: access$1300
+30 -1: sun/reflect/MethodAccessorImpl
+130 -1: (Ljava/util/List<Ljava/util/Locale$LanguageRange;>;Ljava/util/Collection<Ljava/util/Locale;>;)Ljava/util/List<Ljava/util/Locale;>;
+9 -1: MALFORMED
+38 -1: (Ljava/lang/String;I)Ljava/lang/Short;
+26 -1: File format not recognised
+12 -1: setTimeOfDay
+19 -1: java/lang/Exception
+15 -1: getOutputStream
+74 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+41 -1: (Ljava/lang/String;Z)Ljava/util/TimeZone;
+49 -1: Lsun/reflect/generics/repository/ClassRepository;
+8 -1: getCerts
+90 -1: (Ljava/lang/Class<*>;ZLjava/lang/Class<*>;)Ljava/util/List<Ljava/lang/invoke/MemberName;>;
+5 -1: clone
+32 -1: ()Ljava/lang/ref/Reference$Lock;
+15 -1: caseIgnoreMatch
+23 -1: (Ljava/util/Set<TE;>;)V
+25 -1: enumerateStringProperties
+9 -1: inherited
+4 -1: flip
+8 -1: setMonth
+38 -1: (Ljava/util/function/Consumer<-TV;>;)V
+55 -1: java/util/concurrent/ConcurrentHashMap$ReduceValuesTask
+37 -1: getJavaSecurityProtectionDomainAccess
+67 -1: (Ljava/util/NavigableSet;Ljava/lang/Class;)Ljava/util/NavigableSet;
+10 -1: reduceKeys
+14 -1: MAX_CODE_POINT
+24 -1: getGenericExceptionTypes
+8 -1: fraction
+30 -1: java/lang/InterruptedException
+46 -1: (Ljava/lang/String;II[BI)Ljava/nio/ByteBuffer;
+114 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>([Ljava/util/HashMap$Node<TK;TV;>;Ljava/util/HashMap$TreeNode<TK;TV;>;)V
+66 -1: (Ljava/lang/String;Ljava/lang/Throwable;)Ljava/lang/InternalError;
+45 -1: (Ljava/lang/Object;)Ljava/lang/StringBuilder;
+8 -1: putLongB
+101 -1: (Ljava/nio/channels/ReadableByteChannel;Ljava/nio/charset/CharsetDecoder;I)Lsun/nio/cs/StreamDecoder;
+16 -1: standardProvider
+14 -1: parameterCount
+59 -1: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/util/List;
+8 -1: putLongL
+12 -1: (TT;TV;TV;)Z
+37 -1: Lsun/reflect/ConstructorAccessorImpl;
+11 -1: ([CII[CII)V
+14 -1: parameterArray
+15 -1: | interpretName
+62 -1: (JLjava/util/function/Function;Ljava/util/function/Consumer;)V
+30 -1: (Z)Lsun/reflect/FieldAccessor;
+19 -1: jvm_special_version
+22 -1: java/util/ArrayDeque$1
+12 -1: initVersions
+22 -1: java/lang/CharSequence
+21 -1: NF_internalMemberName
+5 -1: ()TE;
+97 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;IZ)Ljava/lang/invoke/MethodHandle;
+25 -1: java/nio/MappedByteBuffer
+6 -1: addURL
+17 -1: isConvertibleFrom
+14 -1: extendWithType
+9 -1: interrupt
+11 -1: floorDivide
+16 -1: x-ISO-2022-CN-GB
+12 -1: CheckedQueue
+7 -1: setLong
+64 -1: (Ljava/lang/ThreadGroup;Ljava/lang/Runnable;Ljava/lang/String;)V
+108 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/NavigableMap<TK;TV;>;)Ljava/util/NavigableMap<TK;TV;>;
+38 -1: java/nio/channels/spi/SelectorProvider
+17 -1: makeGuardWithTest
+20 -1: (Ljava/util/List;Z)V
+8 -1: val$path
+12 -1: Runtime.java
+7 -1: channel
+71 -1: <T:Ljava/lang/Object;>([TT;IILjava/util/function/BinaryOperator<TT;>;)V
+18 -1: initializedHeaders
+32 -1: ()[Lsun/launcher/LauncherHelper;
+13 -1: jvInitialized
+10 -1: getSeconds
+7 -1: Decoder
+20 -1: getYearFromFixedDate
+6 -1: PREFIX
+21 -1: sun.boot.library.path
+11 -1: FIXED_DATES
+33 -1: (JLjava/util/function/Consumer;)V
+27 -1: initializeJavaAssertionMaps
+13 -1: toOctalString
+9 -1: fixResult
+10 -1: typeParams
+94 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;I)Ljava/util/concurrent/ConcurrentHashMap$Node;
+4 -1: Help
+11 -1: setIfNotSet
+39 -1: java/lang/UnsupportedOperationException
+15 -1: zip file closed
+8 -1: floorDiv
+10 -1: canExecute
+10 -1: encodeLoop
+18 -1: addRequestProperty
+56 -1: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;I)V
+10 -1: superclass
+5 -1: close
+56 -1: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;I)Z
+6 -1: ignore
+32 -1: ()Ljava/lang/ref/ReferenceQueue;
+19 -1: java/util/Formatter
+27 -1: java/lang/ClassLoaderHelper
+23 -1: (Ljava/lang/Object;JZ)V
+29 -1: java/nio/file/WatchEvent$Kind
+6 -1: CENLEN
+4 -1: SIZE
+68 -1: <T:Ljava/lang/Object;>(Ljava/util/Deque<TT;>;)Ljava/util/Queue<TT;>;
+9 -1: isEscaped
+12 -1: LF_INTERPRET
+22 -1: (I)Ljava/lang/Integer;
+60 -1: (Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MemberName;
+49 -1: ([Ljava/lang/Class<*>;Ljava/lang/StringBuilder;)V
+11 -1: getZipEntry
+16 -1: metaInfFilenames
+27 -1: (Ljava/lang/StringBuffer;)V
+57 -1: (Ljava/lang/Object;)Ljava/util/WeakHashMap$Entry<TK;TV;>;
+76 -1: (Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class<*>;
+8 -1: ([CII)[B
+27 -1: (Ljava/lang/StringBuffer;)Z
+24 -1: getManifestFromReference
+8 -1: ([CII)[C
+10 -1: H_LOWALPHA
+18 -1: FileURLMapper.java
+12 -1: fxLaunchMode
+24 -1: isMethodHandleInvokeName
+17 -1: winTimeToFileTime
+19 -1: checkTopLevelWindow
+26 -1: MapReduceMappingsToIntTask
+13 -1: NORM_PRIORITY
+18 -1: lookupViaProviders
+30 -1: (I)Ljava/util/LinkedList$Node;
+3 -1: UTC
+10 -1: UNMAPPABLE
+68 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;B)V
+9 -1: META-INF/
+13 -1: Iterable.java
+71 -1: ([Ljava/lang/reflect/Field;Ljava/lang/String;)Ljava/lang/reflect/Field;
+9 -1: setOffset
+8 -1: FJObject
+50 -1: (Ljava/lang/CharSequence;)Ljava/util/StringJoiner;
+23 -1: java/nio/HeapByteBuffer
+23 -1: sun/util/PreHashedMap$1
+23 -1: sun/util/PreHashedMap$2
+34 -1: newGetCharIllegalArgumentException
+40 -1: jca           JCA engine class debugging
+39 -1: (Ljava/lang/Object;I)Ljava/lang/Object;
+42 -1: (Ljava/lang/String;)Ljava/net/InetAddress;
+25 -1: (Ljava/net/FileNameMap;)V
+44 -1: (Ljava/util/SortedMap;)Ljava/util/SortedMap;
+52 -1: (Ljava/lang/String;Ljava/lang/Long;)Ljava/lang/Long;
+27 -1: ()[Ljava/util/HashMap$Node;
+29 -1: java/util/EmptyStackException
+16 -1: not a field type
+14 -1: Ljava/io/File;
+28 -1: ()[Ljava/security/Principal;
+69 -1: (Ljava/io/OutputStream;Ljava/lang/Object;Ljava/nio/charset/Charset;)V
+5 -1: ()TK;
+10 -1: ISO8859-13
+40 -1: java/lang/invoke/DirectMethodHandle$Lazy
+30 -1: The object is not initialized.
+10 -1: ISO8859-15
+88 -1: <E:Ljava/lang/Object;>(Ljava/util/List<TE;>;Ljava/lang/Class<TE;>;)Ljava/util/List<TE;>;
+25 -1: (ZILjava/lang/String;II)Z
+9 -1: stackSize
+61 -1: (Ljava/util/Comparator;Ljava/lang/Object;Ljava/lang/Object;)I
+16 -1: synchronizedList
+90 -1: (Ljava/util/Comparator;Ljava/util/function/Function;Ljava/lang/Object;Ljava/lang/Object;)I
+9 -1: nullCheck
+174 -1: Ljava/util/concurrent/ConcurrentMap<Ljava/lang/invoke/MethodType$ConcurrentWeakInternSet$WeakEntry<TT;>;Ljava/lang/invoke/MethodType$ConcurrentWeakInternSet$WeakEntry<TT;>;>;
+14 -1: java/lang/Enum
+3 -1: int
+13 -1: detailMessage
+56 -1: java/util/concurrent/ConcurrentHashMap$SearchEntriesTask
+10 -1: ISO-8859-1
+10 -1: ISO-8859-2
+10 -1: ISO-8859-3
+10 -1: ISO-8859-4
+10 -1: ISO-8859-5
+10 -1: ISO-8859-6
+24 -1: ([Ljava/lang/Object;II)V
+10 -1: ISO-8859-7
+10 -1: ISO-8859-8
+139 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$Node;)[Ljava/util/concurrent/ConcurrentHashMap$Node;
+10 -1: ISO-8859-9
+5 -1: round
+25 -1: DIRECTIONALITY_WHITESPACE
+13 -1: NamedFunction
+10 -1: startAgent
+3 -1: ioe
+7 -1: closing
+24 -1: appendSchemeSpecificPart
+56 -1: sun/reflect/ReflectionFactory$GetReflectionFactoryAction
+83 -1: Ljava/lang/Object;Ljava/security/PrivilegedAction<Lsun/reflect/ReflectionFactory;>;
+17 -1: isCharsetDetected
+11 -1: getJarFiles
+22 -1: getEnclosingMethodInfo
+11 -1: setReadable
+61 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;)V
+10 -1: attachment
+34 -1: (Ljava/io/File;)Ljava/lang/String;
+18 -1: ZipFileInputStream
+15 -1: CodeSource.java
+61 -1: (Ljava/util/jar/JarFile;)Ljava/util/List<Ljava/lang/Object;>;
+7 -1: cp00858
+108 -1: ([Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/invoke/LambdaForm$Name;II)Ljava/lang/invoke/LambdaForm$Name;
+38 -1: ([DII)Ljava/util/Spliterator$OfDouble;
+8 -1: val$name
+11 -1: LF_REINVOKE
+12 -1: validateTime
+17 -1: copyFromCharArray
+32 -1: throwSetIllegalArgumentException
+14 -1: fieldModifiers
+52 -1: (Ljava/lang/ClassValue;)Ljava/lang/ClassValue$Entry;
+58 -1: (Ljava/io/OutputStream;Ljava/nio/charset/CharsetEncoder;)V
+14 -1: generalInvoker
+11 -1: interrupted
+246 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceMappingsToLongTask;Ljava/util/function/ToLongBiFunction;JLjava/util/function/LongBinaryOperator;)V
+20 -1: java/util/Dictionary
+17 -1: getDoubleVolatile
+41 -1: (Ljava/lang/Class<*>;Ljava/lang/Object;)Z
+8 -1: intValue
+24 -1: (F)Ljava/nio/ByteBuffer;
+5 -1: reset
+54 -1: (ILjava/util/List;)[Ljava/lang/invoke/LambdaForm$Name;
+19 -1: [Ljava/util/Locale;
+43 -1: (Ljava/lang/String;II)Ljava/nio/ByteBuffer;
+38 -1: ()Ljava/io/ObjectInputStream$GetField;
+18 -1: [Locked by thread 
+10 -1: checkedMap
+16 -1: checkedSortedMap
+14 -1: illegal symbol
+16 -1: TITLECASE_LETTER
+4 -1: root
+22 -1: (ZLjava/lang/String;)V
+27 -1: ([JII)Ljava/nio/LongBuffer;
+15 -1: printStackTrace
+30 -1: newConstructorForSerialization
+14 -1: getPermissions
+13 -1: toStringCache
+15 -1: equalParamTypes
+37 -1: throwFinalFieldIllegalAccessException
+35 -1: (Ljava/lang/String;Ljava/io/File;)V
+34 -1: java/nio/charset/CoderResult$Cache
+3 -1: .\n\n
+33 -1: Ljava/nio/charset/CharsetEncoder;
+11 -1: lambdaForms
+65 -1: <T::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TT;>;)TT;
+39 -1: (CLjava/lang/Class;Ljava/lang/Object;)Z
+3 -1: ise
+14 -1: forLanguageTag
+45 -1: ([Ljava/lang/Class<*>;[Ljava/lang/Class<*>;)Z
+36 -1: RuntimeInvisibleParameterAnnotations
+12 -1: binarySearch
+24 -1: getAssociatedAnnotations
+10 -1: decoderFor
+6 -1: ibm813
+10 -1: logicalXor
+10 -1: setVarargs
+71 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Void;)V
+4 -1: cast
+6 -1: ibm819
+23 -1: getParentDelegationTime
+8 -1: ([FII)[F
+4 -1: .tmp
+6 -1: (JII)J
+27 -1: ()Ljava/lang/ref/Finalizer;
+9 -1: sunec.jar
+22 -1: java/net/URLConnection
+41 -1: (Ljava/lang/Runnable;Ljava/lang/String;)V
+20 -1: SecurityManager.java
+18 -1: getZipFileOpenTime
+7 -1: country
+13 -1: inflaterCache
+4 -1:     
+17 -1: java/lang/Runtime
+125 -1: (Lsun/management/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V
+24 -1: java/util/ResourceBundle
+64 -1: Ljava/util/Hashtable<Lsun/misc/Signal;Lsun/misc/SignalHandler;>;
+79 -1: ([Ljava/util/WeakHashMap$Entry<TK;TV;>;[Ljava/util/WeakHashMap$Entry<TK;TV;>;)V
+8 -1: x-ibm737
+39 -1: (Ljava/security/AccessControlContext;)Z
+21 -1: (Ljava/lang/Class;I)V
+4 -1:    -
+15 -1: calculateFields
+22 -1: Ljava/util/Properties;
+8 -1: getArray
+21 -1: (Ljava/lang/Class;I)Z
+41 -1: (Ljava/lang/ThreadGroup;)Ljava/lang/Void;
+17 -1: Ljava/io/Console;
+115 -1: (Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;[Ljava/security/Permission;)Ljava/lang/Object;
+12 -1: nextThreadID
+81 -1: (Ljava/net/URLClassLoader;Ljava/lang/SecurityManager;Ljava/security/Permission;)V
+23 -1: ARRAY_SHORT_BASE_OFFSET
+10 -1: interpret_
+144 -1: (Ljava/net/URL;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+20 -1: isIPv6LiteralAddress
+13 -1: launcher_name
+36 -1: java/util/function/IntToLongFunction
+38 -1: java/util/WeakHashMap$EntrySpliterator
+8 -1: copyInto
+3 -1: ACT
+11 -1: metafactory
+31 -1: ([BLjava/nio/charset/Charset;)V
+30 -1: java/lang/annotation/Retention
+13 -1: getYearLength
+42 -1: java/util/AbstractMap$SimpleImmutableEntry
+31 -1: ()Ljava/lang/invoke/MemberName;
+21 -1: sun/misc/JavaIOAccess
+16 -1: jdk_build_number
+8 -1: ST_RESET
+96 -1: (BLjava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MemberName;
+13 -1: getTypeString
+15 -1: maxCharsPerByte
+8 -1: checkKey
+49 -1: (Ljava/nio/charset/Charset;Lsun/nio/cs/UTF_8$1;)V
+80 -1: (Ljava/lang/ClassValue;Ljava/lang/ClassValue$Entry;)Ljava/lang/ClassValue$Entry;
+32 -1: Ljava/security/ProtectionDomain;
+5 -1: ()TT;
+6 -1: insert
+10 -1: intersects
+38 -1: ([Ljava/lang/Class;Ljava/lang/Class;)V
+15 -1: java/lang/Class
+12 -1: getPublicKey
+37 -1: (ID)Ljava/lang/AbstractStringBuilder;
+6 -1: ibm850
+6 -1: locsig
+6 -1: ibm852
+19 -1: changeReferenceKind
+3 -1: AET
+42 -1: (Ljava/util/Collection;Ljava/lang/Class;)V
+6 -1: ibm855
+16 -1: getPolicyNoCheck
+39 -1: ([B)[[Ljava/lang/annotation/Annotation;
+6 -1: ibm857
+10 -1: Error.java
+38 -1: ()Ljava/util/List<Ljava/lang/Object;>;
+14 -1: createInstance
+5 -1: cp437
+28 -1: Lsun/util/locale/BaseLocale;
+17 -1: getStandardOffset
+29 -1: sun/nio/cs/StandardCharsets$1
+36 -1: Ljava/security/ProtectionDomain$Key;
+14 -1: ArrayList.java
+78 -1: (Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MemberName;
+38 -1: java/lang/invoke/MethodHandleImpl$Lazy
+42 -1: (Ljava/util/LinkedHashMap$Entry<TK;TV;>;)V
+8 -1: getLongB
+7 -1: vmentry
+21 -1: lookupExtendedCharset
+32 -1: <T:Ljava/lang/Object;>([TT;)[TT;
+53 -1: Ljava/util/concurrent/ConcurrentHashMap$EntrySetView;
+6 -1: ibm862
+8 -1: getLongL
+32 -1: (Ljava/lang/invoke/MemberName;)J
+67 -1: Ljava/lang/Object;Ljava/security/PrivilegedAction<Lsun/misc/Perf;>;
+6 -1: region
+6 -1: ibm866
+89 -1: (Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)Lsun/reflect/ConstructorAccessor;
+22 -1: java/util/ListIterator
+9 -1: wednesday
+16 -1: unsuspendThreads
+20 -1: Not a Proxy instance
+45 -1: Ljava/lang/reflect/InvocationTargetException;
+61 -1: (Ljava/lang/CharSequence;II)Ljava/lang/AbstractStringBuilder;
+5 -1: ()TV;
+32 -1: (Ljava/lang/invoke/MemberName;)V
+82 -1: (Ljava/util/jar/JarFile;Ljava/util/jar/JarEntry;)[Ljava/security/cert/Certificate;
+34 -1: java/lang/ClassValue$ClassValueMap
+32 -1: (Ljava/lang/invoke/MemberName;)Z
+15 -1: SPACE_SEPARATOR
+17 -1: caseIgnoreCompare
+58 -1: (Ljava/lang/Class;)Ljava/lang/invoke/MethodHandles$Lookup;
+4 -1: Code
+3 -1: AGT
+54 -1: (Ljava/lang/StringBuilder;II)Ljava/lang/StringBuilder;
+6 -1: ibm874
+15 -1: newMemberBuffer
+42 -1: (Ljava/nio/file/Path;)Ljava/nio/file/Path;
+33 -1: Ljava/lang/NumberFormatException;
+10 -1: Field.java
+67 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<-TK;+TU;>;)TU;
+4 -1: rows
+12 -1: MIN_PRIORITY
+25 -1: URI has a query component
+41 -1: provider      security provider debugging
+29 -1: sun/nio/cs/ISO_8859_1$Encoder
+26 -1: (Ljava/util/zip/ZipFile;)I
+26 -1: (Ljava/util/zip/ZipFile;)J
+20 -1: Bad digit at end of 
+29 -1: Ljava/lang/RuntimePermission;
+12 -1: initResolved
+9 -1: loadFence
+13 -1: fieldAccessor
+26 -1: (Ljava/util/zip/ZipFile;)V
+36 -1: java/lang/CloneNotSupportedException
+19 -1: getBasicConstraints
+16 -1: putOrderedObject
+26 -1: (Ljava/util/zip/ZipFile;)Z
+6 -1: target
+50 -1: (Ljava/util/concurrent/CountedCompleter;[I[IIIII)V
+16 -1: changeReturnType
+13 -1: CAUSE_CAPTION
+14 -1: checkExactType
+50 -1: sun/util/locale/provider/LocaleServiceProviderPool
+47 -1: java/lang/invoke/DirectMethodHandle$Constructor
+20 -1: CallerSensitive.java
+30 -1: java/security/ProtectionDomain
+26 -1: java.launcher.opt.vmselect
+4 -1: \tat 
+42 -1: java/util/ArraysParallelSortHelpers$FJLong
+39 -1: (Ljava/lang/String;)[Ljava/lang/String;
+19 -1: sun.net.www.content
+34 -1: ([III)Ljava/util/stream/IntStream;
+20 -1: (Ljava/util/Deque;)V
+35 -1: (Ljava/lang/reflect/Constructor;)[B
+16 -1: WeakHashMap.java
+8 -1: ([III)[I
+46 -1: (Ljava/util/Properties;Ljava/io/InputStream;)V
+54 -1: (I)Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
+65 -1: (ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/util/HashMap$Node;
+27 -1: URI path component is empty
+3 -1: -1-
+32 -1: Ljava/io/InterruptedIOException;
+9 -1: setLocale
+7 -1: [^, ;]*
+6 -1: format
+61 -1: (Ljava/util/function/Supplier;IZ)Ljava/util/stream/IntStream;
+20 -1: getRequestProperties
+16 -1: reallocateMemory
+28 -1: java/lang/IllegalAccessError
+5 -1: query
+83 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;II)Ljava/lang/invoke/MethodHandle;
+7 -1: threadQ
+6 -1: STATIC
+7 -1: enqueue
+21 -1: uninitializedCallSite
+3 -1: -2-
+26 -1: ()Ljava/util/NavigableSet;
+27 -1: getUncaughtExceptionHandler
+42 -1: ([Ljava/net/URL;)Ljava/net/URLClassLoader;
+30 -1: java/lang/UnsatisfiedLinkError
+39 -1: java/util/Collections$ReverseComparator
+7 -1: resolve
+4 -1: poll
+7 -1: (TE;I)V
+21 -1: : Unknown launch mode
+53 -1: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
+36 -1: sun.classloader.parentDelegationTime
+25 -1: java/net/URLStreamHandler
+39 -1: (Ljava/lang/Object;J)Ljava/lang/Object;
+53 -1: Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;
+51 -1: java/util/ArraysParallelSortHelpers$FJDouble$Sorter
+26 -1: getAnnotatedParameterTypes
+18 -1: codePointCountImpl
+7 -1: threads
+12 -1: offsetBefore
+29 -1: ()Ljava/util/Collection<TV;>;
+58 -1: (Lsun/invoke/util/Wrapper;)Ljava/lang/invoke/MethodHandle;
+17 -1: DMH.invokeSpecial
+3 -1: -3-
+16 -1: decodeBufferLoop
+43 -1: java/util/concurrent/atomic/AtomicReference
+16 -1: reduceKeysToLong
+27 -1: newIllegalArgumentException
+3 -1: ALL
+5 -1: cache
+5 -1: queue
+4 -1: 8bit
+3 -1: -4-
+35 -1: Ljava/util/Set<Ljava/lang/String;>;
+9 -1: MIN_RADIX
+26 -1: ZipFileInflaterInputStream
+13 -1: MANIFEST_NAME
+18 -1: java/util/TimeZone
+175 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MemberName;Ljava/lang/invoke/MemberName;Ljava/lang/Class;Ljava/lang/invoke/DirectMethodHandle$1;)V
+16 -1: getContentLength
+11 -1: setDoOutput
+22 -1: (Ljava/io/Closeable;)V
+13 -1: TimeZone.java
+28 -1: sun/misc/ExtensionDependency
+6 -1: bindTo
+3 -1: -5-
+40 -1: ()[Ljava/util/WeakHashMap$Entry<TK;TV;>;
+20 -1: ()Lsun/misc/Cleaner;
+9 -1: compareTo
+68 -1: java/util/concurrent/ConcurrentHashMap$MapReduceMappingsToDoubleTask
+11 -1: checkedList
+14 -1: (ITK;TV;ZZ)TV;
+5 -1: greek
+3 -1: jar
+21 -1: (Ljava/lang/String;)B
+21 -1: (Ljava/lang/String;)C
+21 -1: (Ljava/lang/String;)D
+5 -1: (JS)V
+21 -1: (Ljava/lang/String;)F
+13 -1: LETTER_NUMBER
+14 -1: isAlphaNumeric
+21 -1: (Ljava/lang/String;)I
+73 -1: (Ljava/nio/charset/Charset;Ljava/lang/String;Ljava/lang/StringCoding$1;)V
+21 -1: (Ljava/lang/String;)J
+25 -1: makeExactOrGeneralInvoker
+3 -1: -6-
+25 -1: java/nio/StringCharBuffer
+21 -1: Ljava/util/Hashtable;
+8 -1: ENQUEUED
+8 -1: finalize
+22 -1: DirectLongBufferU.java
+21 -1: (Ljava/lang/String;)S
+10 -1: localhost:
+33 -1: isKnownNotToHaveSpecialAttributes
+21 -1: (Ljava/lang/String;)V
+45 -1: (Ljava/lang/Class<*>;[Ljava/lang/Class<*>;Z)V
+21 -1: (Ljava/lang/String;)Z
+22 -1: (Ljava/util/Vector;I)V
+44 -1: java/nio/charset/UnsupportedCharsetException
+23 -1: java/lang/CharacterName
+7 -1: checkIO
+33 -1: (I)Lsun/misc/URLClassPath$Loader;
+90 -1: (Ljava/lang/Class<*>;Ljava/lang/reflect/Constructor<*>;)Ljava/lang/reflect/Constructor<*>;
+18 -1: getHeaderFieldDate
+9 -1: MIN_VALUE
+95 -1: (Ljava/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject;)Ljava/util/Collection;
+44 -1: (Ljava/lang/String;Z)Ljava/util/Enumeration;
+8 -1: NOVEMBER
+4 -1: gcal
+17 -1: getConnectTimeout
+124 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+24 -1: INDEXOFSUBLIST_THRESHOLD
+16 -1: isJulianLeapYear
+21 -1: reduceEntriesToDouble
+15 -1: getPrefixLength
+17 -1:  is not param at 
+14 -1: inDaylightTime
+39 -1: (Ljava/lang/Class;[I)Ljava/lang/Object;
+5 -1: force
+98 -1: (Ljava/lang/Class;Lsun/reflect/annotation/AnnotationType;Lsun/reflect/annotation/AnnotationType;)Z
+40 -1: (Lsun/reflect/ConstructorAccessorImpl;)V
+27 -1: RuntimeInvisibleAnnotations
+17 -1: checkTargetChange
+9 -1: skipBytes
+4 -1: port
+25 -1: sun/nio/cs/UTF_16$Encoder
+28 -1: MIN_SUPPLEMENTARY_CODE_POINT
+4 -1: node
+11 -1: not param: 
+9 -1: debugInit
+6 -1: setURL
+14 -1: getMonthLength
+23 -1: ()Ljava/nio/ByteBuffer;
+17 -1: CALENDAR_JAPANESE
+11 -1: access$1400
+16 -1: ()Ljava/net/URI;
+29 -1: (IZ)Ljava/lang/StringBuilder;
+15 -1: Native Library 
+30 -1: Invalid lambda deserialization
+14 -1: throwException
+18 -1: nothing to verify!
+23 -1: (Ljava/lang/Object;JF)V
+3 -1: ART
+16 -1: isExtClassLoader
+18 -1: Illegal Capacity: 
+26 -1: java/util/zip/ZipException
+4 -1: /../
+34 -1: ([II)Ljava/util/Spliterator$OfInt;
+26 -1: (I)Ljava/util/Enumeration;
+60 -1: (Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodType;
+43 -1: not a field or nested class, no simple type
+12 -1: nextPutIndex
+15 -1: getConstructor0
+3 -1: AST
+11 -1: fromURIPath
+49 -1: (Ljava/util/Collections$UnmodifiableCollection;)V
+8 -1: makeImpl
+51 -1: (Ljava/util/WeakHashMap;Ljava/util/WeakHashMap$1;)V
+32 -1: (Ljava/util/function/Supplier;)V
+20 -1: namedFunctionInvoker
+37 -1: newGetBooleanIllegalArgumentException
+19 -1: (Ljava/io/File;ZI)V
+8 -1: NULL_KEY
+36 -1: Ljava/lang/reflect/Constructor<TT;>;
+21 -1: (Ljava/lang/Object;)B
+21 -1: (Ljava/lang/Object;)C
+21 -1: (Ljava/lang/Object;)D
+21 -1: (Ljava/lang/Object;)F
+30 -1: ()Lsun/util/locale/BaseLocale;
+21 -1: (Ljava/lang/Object;)I
+21 -1: (Ljava/lang/Object;)J
+10 -1: lineNumber
+95 -1: (JLjava/util/function/ToDoubleBiFunction<-TK;-TV;>;DLjava/util/function/DoubleBinaryOperator;)D
+16 -1: CoderResult.java
+44 -1: (Ljava/util/NavigableSet;Ljava/lang/Class;)V
+21 -1: (Ljava/lang/Object;)S
+13 -1: getNameString
+129 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MemberName;Ljava/lang/invoke/DirectMethodHandle$1;)V
+21 -1: (Ljava/lang/Object;)V
+21 -1: (Ljava/lang/Object;)Z
+81 -1: Ljava/util/HashMap<Ljava/lang/String;Ljava/util/LinkedList<Ljava/lang/String;>;>;
+49 -1: java/util/concurrent/locks/ReentrantLock$FairSync
+11 -1: csisolatin0
+11 -1: csisolatin1
+7 -1: isSpace
+10 -1: getDefault
+11 -1: csisolatin2
+16 -1: ()Ljava/net/URL;
+11 -1: csisolatin4
+14 -1: invokeExact_MT
+11 -1: csisolatin5
+28 -1: (Ljava/io/FileInputStream;)V
+11 -1: csisolatin9
+8 -1: isLetter
+15 -1: getConstructors
+21 -1: mainAppContextDefault
+29 -1: ()[Ljava/lang/reflect/Method;
+23 -1: Ljava/util/WeakHashMap;
+12 -1: LF_INVSTATIC
+17 -1: DirectBuffer.java
+10 -1: newEncoder
+10 -1: getVersion
+32 -1: java/lang/IllegalAccessException
+20 -1: java/util/Collection
+61 -1: (Ljava/util/concurrent/ConcurrentHashMap;Ljava/lang/Object;)V
+19 -1: $deserializeLambda$
+8 -1: removeIf
+25 -1: sun/reflect/FieldAccessor
+129 -1: <U::Ljava/lang/Comparable<-TU;>;>(Ljava/util/function/Function<-TT;+TU;>;Ljava/util/Comparator<-TU;>;)Ljava/util/Comparator<TT;>;
+17 -1: parseAbsoluteSpec
+37 -1: ([Ljava/util/HashMap$Node<TK;TV;>;I)V
+17 -1: java/util/HashSet
+13 -1: spreadInvoker
+20 -1: suppressAccessChecks
+32 -1: Ljava/lang/InterruptedException;
+11 -1: oldMappings
+9 -1: lookupTag
+16 -1: java/lang/System
+5 -1: LFI: 
+6 -1: IBM737
+9 -1: SHORT_IDS
+45 -1: ([IIILjava/util/function/IntBinaryOperator;)V
+20 -1: getMetaInfEntryNames
+10 -1: isReadOnly
+50 -1: <E:Ljava/lang/Object;>()Ljava/util/SortedSet<TE;>;
+12 -1: java.vm.name
+30 -1: java/lang/Class$AnnotationData
+61 -1: (ILjava/lang/invoke/LambdaForm;)Ljava/lang/invoke/LambdaForm;
+7 -1: address
+44 -1: (Ljava/util/function/BiConsumer<-TK;-TV;>;)V
+58 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;I)V
+112 -1: (Ljava/lang/Object;TV;Ljava/lang/ref/ReferenceQueue<Ljava/lang/Object;>;ILjava/util/WeakHashMap$Entry<TK;TV;>;)V
+14 -1: aliases_KOI8_R
+3 -1: AWT
+14 -1: aliases_KOI8_U
+24 -1: ARRAY_DOUBLE_BASE_OFFSET
+23 -1: Ljava/util/jar/JarFile;
+91 -1: (Ljava/lang/Class<TT;>;[Ljava/lang/Class<*>;[Ljava/lang/Class<*>;IILjava/lang/String;[B[B)V
+14 -1: mappingAddress
+19 -1: [Ljava/lang/Object;
+17 -1: sun/misc/JarIndex
+9 -1: image/jpg
+49 -1: (Ljava/lang/String;I)Lsun/util/calendar/ZoneInfo;
+37 -1: java/lang/invoke/DirectMethodHandle$1
+34 -1: java/util/Collections$SingletonMap
+89 -1: (JLjava/util/function/ToIntBiFunction<-TK;-TV;>;ILjava/util/function/IntBinaryOperator;)I
+46 -1: (Ljava/util/Comparator;)Ljava/util/Comparator;
+11 -1: isTitleCase
+38 -1: java/lang/IllegalMonitorStateException
+33 -1: java/nio/BufferUnderflowException
+28 -1: java/lang/ClassValue$Version
+11 -1: printLocale
+13 -1: STORE_BARRIER
+42 -1: ([ILjava/util/function/IntUnaryOperator;)V
+26 -1: sun/util/locale/BaseLocale
+29 -1: java/io/ObjectStreamException
+41 -1: sun/reflect/UnsafeStaticFieldAccessorImpl
+60 -1: ([Ljava/lang/Object;Ljava/util/Iterator;)[Ljava/lang/Object;
+30 -1: (Ljava/nio/charset/Charset;)[B
+73 -1: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
+3 -1: VST
+80 -1: Java(TM) SE Runtime Environment (build 1.8.0-internal-iklam_2013_11_27_21_25-b00
+85 -1: (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/net/URLStreamHandler;)V
+20 -1: getStackTraceElement
+36 -1: java/util/LinkedHashMap$LinkedKeySet
+17 -1: getNormalizedYear
+15 -1: maxBytesPerChar
+16 -1: java/util/Random
+34 -1: (I[C)Ljava/lang/invoke/LambdaForm;
+11 -1: nbits < 0: 
+7 -1: H_PCHAR
+29 -1: (Ljava/nio/charset/Charset;)I
+36 -1: (I[I[C)Ljava/lang/invoke/LambdaForm;
+23 -1: java/lang/ClassLoader$1
+23 -1: java/lang/ClassLoader$2
+23 -1: java/lang/ClassLoader$3
+9 -1: sizeTable
+36 -1: (Z)Ljava/lang/AbstractStringBuilder;
+29 -1: (Ljava/nio/charset/Charset;)V
+25 -1: ARRAY_BOOLEAN_INDEX_SCALE
+29 -1: (Ljava/nio/charset/Charset;)Z
+6 -1: keySet
+20 -1: declaredConstructors
+25 -1: oracle/jrockit/jfr/Timing
+12 -1: sizeIsSticky
+6 -1: IBM775
+17 -1: currentTimeMillis
+28 -1: java/nio/DirectDoubleBufferS
+71 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/invoke/MethodType;B)V
+28 -1: java/nio/DirectDoubleBufferU
+19 -1: cachedFixedDateJan1
+15 -1: getClassContext
+65 -1: (Ljava/security/CodeSource;Ljava/security/PermissionCollection;)V
+16 -1: unmodifiableList
+10 -1: getDoubleB
+82 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/String;
+11 -1: getEntryCrc
+10 -1: getDoubleL
+20 -1: (C)Ljava/lang/Class;
+11 -1: Null action
+22 -1: java/io/BufferedWriter
+67 -1: (Ljava/lang/String;[Ljava/lang/Class<*>;)Ljava/lang/reflect/Method;
+22 -1: parseSelectAnnotations
+6 -1: rename
+20 -1: acquireFieldAccessor
+43 -1: (Ljava/util/Vector;[Ljava/lang/Object;III)V
+32 -1: Ljava/lang/NullPointerException;
+29 -1: (Ljava/lang/ThreadLocal<*>;)V
+18 -1: descendingIterator
+37 -1: java/util/Collections$SynchronizedSet
+24 -1: mark/reset not supported
+12 -1: ) > toIndex(
+13 -1: <<ALL FILES>>
+10 -1: fastRemove
+4 -1: load
+31 -1: sun/reflect/ReflectionFactory$1
+39 -1: (Ljava/util/List<*>;)Ljava/lang/Object;
+39 -1: Ljava/util/Map<TE;Ljava/lang/Boolean;>;
+9 -1: offerLast
+31 -1: ()Ljava/lang/invoke/MethodType;
+40 -1: <E:Ljava/lang/Object;>Ljava/lang/Object;
+17 -1: getObjectVolatile
+14 -1: suspendThreads
+55 -1: (Ljava/lang/String;ZLjava/util/Set;)Lsun/misc/Resource;
+75 -1: <T:Ljava/lang/Object;>(Ljava/util/List<+Ljava/lang/Comparable<-TT;>;>;TT;)I
+6 -1: Lookup
+20 -1: java/io/OutputStream
+41 -1: Could not create application class loader
+28 -1: Lsun/misc/JavaUtilJarAccess;
+46 -1: java/util/Collections$SynchronizedNavigableSet
+8 -1: override
+21 -1: threadLocalRandomSeed
+10 -1: TEXT_PLAIN
+22 -1: ([B)Ljava/lang/String;
+29 -1: java/nio/InvalidMarkException
+14 -1: Throwable.java
+27 -1: newWrongMethodTypeException
+6 -1: ptypes
+8 -1: bugLevel
+62 -1: (ILjava/lang/CharSequence;II)Ljava/lang/AbstractStringBuilder;
+37 -1: ()Ljava/util/Locale$LocaleNameGetter;
+14 -1: getEntryMethod
+7 -1: getByte
+12 -1: UTF-32BE-BOM
+4 -1: lock
+34 -1: java/security/AccessControlContext
+79 -1: (Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/MemberName;
+5 -1: DEBUG
+5 -1: unbox
+17 -1: CLASSPATH_OPTOSFT
+4 -1: cbrt
+21 -1: LocalizedObjectGetter
+21 -1: ProtectionDomain.java
+22 -1: ([J)Ljava/util/BitSet;
+17 -1: getUnresolvedName
+34 -1: (Ljava/util/Map;Ljava/util/Map;I)V
+7 -1: cskoi8r
+14 -1: getInterfaces0
+48 -1: (Lsun/net/www/MessageHeader;)[Ljava/lang/String;
+14 -1: getFileNameMap
+16 -1: preserveCombiner
+19 -1: getDefaultUseCaches
+57 -1: (Ljava/lang/Class;[B[Ljava/lang/Object;)Ljava/lang/Class;
+21 -1: (D)Ljava/lang/Double;
+15 -1: iso8859_15_fdis
+23 -1: java/util/regex/Pattern
+6 -1: ibm912
+14 -1: findBuiltinLib
+42 -1: java/lang/annotation/AnnotationFormatError
+6 -1: ibm914
+6 -1: ibm915
+44 -1: java/nio/charset/IllegalCharsetNameException
+22 -1: COMBINING_SPACING_MARK
+20 -1: ()Ljava/lang/Thread;
+8 -1: readLine
+12 -1: (unresolved 
+65 -1: (Ljava/lang/String;Z)Ljava/util/Enumeration<Lsun/misc/Resource;>;
+41 -1: ([Ljava/lang/String;[Ljava/lang/String;)V
+30 -1: java/lang/Class$ReflectionData
+8 -1: requests
+52 -1: (Ljava/nio/charset/Charset;Lsun/nio/cs/US_ASCII$1;)V
+12 -1: ACCESS_WRITE
+6 -1: ibm920
+12 -1: CR_ERROR_MIN
+6 -1: jarMap
+6 -1: ibm923
+15 -1: java/lang/Error
+11 -1: VM_SETTINGS
+18 -1: name can't be null
+7 -1: PRESENT
+19 -1: setSecurityManager0
+101 -1: (Ljava/nio/channels/WritableByteChannel;Ljava/nio/charset/CharsetEncoder;I)Lsun/nio/cs/StreamEncoder;
+25 -1: ()Ljava/util/jar/JarFile;
+26 -1: java/io/ObjectOutputStream
+13 -1: no !/ in spec
+5 -1: (II)C
+12 -1: setPriority0
+30 -1: (Z)[Ljava/lang/reflect/Method;
+28 -1: sun/nio/cs/ThreadLocalCoders
+5 -1: (II)I
+22 -1: java/io/BufferedReader
+26 -1: ()Lsun/misc/JavaNetAccess;
+10 -1: Asia/Dhaka
+14 -1: parallelStream
+5 -1: (II)V
+5 -1: (II)Z
+31 -1: Ljava/lang/reflect/Constructor;
+21 -1: ()Ljava/time/Instant;
+31 -1: (Ljava/lang/String;III[J[I[IZ)V
+8 -1: Volatile
+23 -1: isUnicodeIdentifierPart
+27 -1: longPrimitiveParameterCount
+16 -1: Map is non-empty
+24 -1: getLocalizedOutputStream
+14 -1: java/lang/Byte
+10 -1: staticBase
+11 -1: lastElement
+17 -1: replaceStaleEntry
+17 -1: MAX_LOW_SURROGATE
+28 -1: java.launcher.X.macosx.usage
+20 -1: registerShutdownHook
+16 -1: SECOND_IN_MILLIS
+8 -1: Embedded
+16 -1: BootstrapMethods
+14 -1: numInvocations
+79 -1: <T:Ljava/lang/Object;>(Ljava/util/Collection<TT;>;)Ljava/util/Enumeration<TT;>;
+10 -1: rotateLeft
+46 -1: ([Ljava/lang/Object;)Ljava/util/stream/Stream;
+6 -1: verify
+17 -1: OTHER_PUNCTUATION
+26 -1: acquireConstructorAccessor
+38 -1: (Ljava/lang/String;I)Ljava/lang/Class;
+30 -1: java/net/UnknownContentHandler
+20 -1: PREFIX_LENGTH_OFFSET
+12 -1: nextGetIndex
+14 -1: standardOffset
+10 -1: entryNames
+15 -1: application/xml
+3 -1: BET
+39 -1: ([DIII)Ljava/util/Spliterator$OfDouble;
+83 -1: (JLjava/util/function/BiFunction;Ljava/util/function/BiFunction;)Ljava/lang/Object;
+10 -1: initMethod
+47 -1: (Ljava/util/LinkedList$Node;)Ljava/lang/Object;
+8 -1: isSealed
+12 -1: isAccessible
+11 -1: audio/x-wav
+46 -1: (Ljava/lang/String;)Ljava/util/jar/Attributes;
+24 -1: ()Ljava/io/OutputStream;
+15 -1: FIELD_MODIFIERS
+30 -1: sun/misc/URLClassPath$Loader$1
+20 -1: recursive invocation
+34 -1: (Ljava/lang/String;)Ljava/net/URL;
+12 -1: linkNodeLast
+34 -1: call site initialization exception
+17 -1: casAnnotationType
+8 -1: x-ibm874
+7 -1: isUpper
+58 -1: java/util/concurrent/ConcurrentHashMap$MapReduceValuesTask
+31 -1: Ill-formed Unicode locale key: 
+12 -1: defineClass0
+12 -1: defineClass1
+12 -1: defineClass2
+59 -1: Can not call newInstance() on the Class for java.lang.Class
+10 -1: codePoints
+3 -1: ...
+14 -1: readAheadLimit
+14 -1: parallelSetAll
+41 -1: ([Ljava/lang/Object;I)[Ljava/lang/Object;
+148 -1: (Ljava/lang/Throwable$PrintStreamOrWriter;[Ljava/lang/StackTraceElement;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set<Ljava/lang/Throwable;>;)V
+10 -1: Deque.java
+21 -1: Must be volatile type
+7 -1: setForm
+58 -1: Ljava/lang/Number;Ljava/lang/Comparable<Ljava/lang/Byte;>;
+47 -1: (Ljava/lang/String;Ljava/security/CodeSource;)V
+30 -1: java/io/InterruptedIOException
+44 -1: java/util/Collections$SynchronizedCollection
+16 -1: Invalid Jar file
+32 -1: sun/util/calendar/CalendarSystem
+67 -1: (JLsun/util/calendar/CalendarDate;)Lsun/util/calendar/CalendarDate;
+19 -1: DEFAULT_BUFFER_SIZE
+16 -1: readObjectNoData
+16 -1: setJavaNioAccess
+73 -1: (Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object;
+14 -1: copyToIntArray
+10 -1: hasWaiters
+20 -1: (I)Ljava/lang/Class;
+35 -1: all           turn on all debugging
+14 -1: Invalid host: 
+26 -1: Lsun/nio/cs/StreamEncoder;
+43 -1: sun/misc/JavaSecurityProtectionDomainAccess
+11 -1: getNamedCon
+8 -1: H_SERVER
+27 -1: java/util/function/Consumer
+12 -1: isLocalClass
+81 -1: (Ljava/util/LinkedHashMap$Entry<TK;TV;>;Ljava/util/LinkedHashMap$Entry<TK;TV;>;)V
+83 -1: Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/lang/Boolean;>;
+4 -1: exec
+43 -1: java/lang/reflect/InvocationTargetException
+35 -1: (Ljava/io/File;Ljava/lang/String;)V
+9 -1: modifiers
+35 -1: (Ljava/io/File;Ljava/lang/String;)Z
+9 -1: Byte.java
+12 -1: unknown mode
+18 -1: initializeVerifier
+24 -1: (Ljava/nio/ByteBuffer;)I
+22 -1: ([Ljava/lang/Object;)I
+11 -1: correctType
+6 -1: escape
+52 -1: (Ljava/security/ProtectionDomain;)Ljava/lang/String;
+11 -1: annotations
+121 -1: (Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;
+22 -1:  using an instance of 
+14 -1: getSpeciesData
+28 -1: ()Ljava/security/CodeSource;
+12 -1: JZENTRY_NAME
+24 -1: (Ljava/nio/ByteBuffer;)V
+4 -1: ZBSC
+22 -1: ([Ljava/lang/Object;)V
+7 -1: isParam
+165 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+70 -1: (ILjava/util/List<Ljava/lang/Class<*>;>;)Ljava/lang/invoke/LambdaForm;
+24 -1: Ljava/io/FilePermission;
+22 -1: ([Ljava/lang/Object;)Z
+11 -1: mergeHeader
+11 -1: applyAsLong
+28 -1: (IJ)Ljava/lang/StringBuffer;
+10 -1: arityCheck
+52 -1: (ILjava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+13 -1: toUpperCaseEx
+9 -1: nextIndex
+11 -1: start > end
+4 -1: long
+6 -1: Static
+27 -1: ()Ljava/lang/reflect/Field;
+10 -1: bufUpdater
+43 -1: averageBytesPerChar exceeds maxBytesPerChar
+105 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lsun/util/locale/BaseLocale$1;)V
+23 -1: ARRAY_SHORT_INDEX_SCALE
+15 -1: getHeaderFields
+36 -1: java/util/HashMap$HashMapSpliterator
+10 -1: Guard.java
+29 -1: java/util/RandomAccessSubList
+6 -1: addAll
+7 -1: getTime
+16 -1: invokeHandleForm
+32 -1: sun/util/locale/LocaleExtensions
+16 -1: checkAndLoadMain
+19 -1: INTERFACE_MODIFIERS
+11 -1: resolveName
+20 -1: getContentLengthLong
+53 -1: (ICLjava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+19 -1: name cannot be null
+23 -1: hasReceiverTypeDispatch
+12 -1: getExtension
+49 -1: Ljava/util/Set<Ljava/security/ProtectionDomain;>;
+114 -1: (Ljava/lang/String;[J[I[J[I[Lsun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule;)Lsun/util/calendar/ZoneInfo;
+24 -1: NativeSignalHandler.java
+58 -1: (Ljava/lang/Thread;)Ljava/lang/ThreadLocal$ThreadLocalMap;
+10 -1: interface 
+68 -1: (Ljava/lang/String;)Ljava/lang/invoke/BoundMethodHandle$SpeciesData;
+15 -1: addShutdownHook
+32 -1: java/security/AccessController$1
+10 -1: filterTags
+19 -1: [Ljava/lang/Number;
+92 -1: <T:Ljava/lang/Object;>(Ljava/util/function/ToLongFunction<-TT;>;)Ljava/util/Comparator<TT;>;
+43 -1: java/util/LinkedHashMap$LinkedEntryIterator
+5 -1: utf-8
+11 -1: iso-8859-13
+11 -1: iso-8859-15
+58 -1: (Lsun/misc/URLClassPath$JarLoader;)Ljava/util/jar/JarFile;
+41 -1:               CertPathValidator debugging
+22 -1: ARRAY_LONG_BASE_OFFSET
+57 -1: (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+13 -1: queuePrintJob
+14 -1: Watchable.java
+15 -1: jdkMajorVersion
+62 -1: (Ljava/lang/String;ZJJ)Ljava/lang/management/MemoryPoolMXBean;
+23 -1: twoToTheDoubleScaleDown
+22 -1: registerVMNotification
+30 -1: ()Lsun/misc/JavaUtilJarAccess;
+17 -1: getTargetVolatile
+4 -1: exit
+13 -1: StringDecoder
+12 -1: hasRemaining
+9 -1: bigEndian
+14 -1: checkMulticast
+13 -1: clearProperty
+18 -1: ForEachMappingTask
+15 -1: Collection.java
+55 -1: (Ljava/io/InputStream;)Ljava/security/cert/Certificate;
+5 -1: UTF-8
+11 -1: transitions
+7 -1: wrapAlt
+27 -1: ClassNotFoundException.java
+20 -1: UnresolvedPermission
+14 -1: charsetForName
+9 -1: getParent
+18 -1: [Ljava/lang/Short;
+24 -1: UnmodifiableNavigableMap
+5 -1: xflow
+10 -1: interfaces
+19 -1: doubleToRawLongBits
+73 -1: (Ljava/lang/reflect/Constructor<*>;[Ljava/lang/Object;)Ljava/lang/Object;
+10 -1: getInCheck
+21 -1: (Ljava/lang/Thread;)V
+15 -1: fromIndex < 0: 
+63 -1: (ITK;TV;Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;)V
+9 -1: pollFirst
+21 -1: (Ljava/lang/Thread;)Z
+16 -1: checkProxyMethod
+39 -1: generateLambdaFormInterpreterEntryPoint
+15 -1: findLoadedClass
+6 -1: system
+5 -1: ITALY
+45 -1: combiner      SubjectDomainCombiner debugging
+34 -1: NativeConstructorAccessorImpl.java
+22 -1: ([C)Ljava/lang/String;
+39 -1: (Ljava/lang/String;Ljava/lang/Class;Z)V
+18 -1: java/lang/Thread$1
+20 -1: window can't be null
+10 -1: Debug.java
+17 -1: singletonIterator
+53 -1: java/util/concurrent/ConcurrentHashMap$ForEachKeyTask
+20 -1: java/security/Policy
+13 -1: getDescriptor
+32 -1: (I)Ljava/lang/invoke/MethodType;
+15 -1: nativeLibraries
+27 -1: sun/util/locale/LanguageTag
+8 -1: priority
+12 -1: IntegerCache
+14 -1: connectTimeout
+9 -1: namePairs
+17 -1: vmAllowSuspension
+16 -1: METHOD_MODIFIERS
+51 -1: (Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+20 -1: MIN_TREEIFY_CAPACITY
+13 -1: getEntryBytes
+33 -1: ()Lsun/reflect/ReflectionFactory;
+17 -1: getDisplayCountry
+13 -1: isWrapperType
+5 -1: utf16
+12 -1: parallelSort
+27 -1: (Ljava/nio/ByteBuffer;IIZ)V
+56 -1: (Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;I)Z
+9 -1: isDefined
+20 -1: sun/misc/FloatConsts
+10 -1: putDoubleB
+30 -1: java/lang/NoSuchFieldException
+27 -1: Value out of range. Value:"
+36 -1: sun/reflect/NativeMethodAccessorImpl
+7 -1: decoder
+38 -1: ([Ljava/lang/invoke/MutableCallSite;)V
+10 -1: putDoubleL
+68 -1: (Ljava/lang/reflect/Method;)Lsun/reflect/generics/scope/MethodScope;
+37 -1: java/lang/invoke/MethodHandles$Lookup
+9 -1: Void.java
+28 -1: sun/util/locale/BaseLocale$1
+10 -1: stackTrace
+7 -1: toClass
+11 -1: access$1500
+41 -1: (Ljava/lang/Object;I)Ljava/lang/Class<*>;
+148 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MemberName;Ljava/lang/Object;JLjava/lang/invoke/DirectMethodHandle$1;)V
+22 -1: ARRAY_BYTE_BASE_OFFSET
+13 -1: ZipEntry.java
+56 -1: (Ljava/util/List;Ljava/util/Collection;)Ljava/util/List;
+5 -1: utf32
+16 -1: ISO_646.irv:1991
+5 -1: p-126
+20 -1: sun.net.www.protocol
+3 -1: key
+20 -1: IMPLEMENTATION_TITLE
+93 -1: (Lsun/util/locale/BaseLocale;Lsun/util/locale/LocaleExtensions;)Lsun/util/locale/LanguageTag;
+66 -1: ([Ljava/lang/Object;[Ljava/lang/Object;IIILjava/util/Comparator;)V
+27 -1: java/nio/DirectFloatBufferS
+27 -1: java/nio/DirectFloatBufferU
+15 -1: JZENTRY_COMMENT
+8 -1: casTabAt
+10 -1: getVariant
+24 -1: Ljava/lang/Thread$State;
+35 -1: ()Ljava/lang/AbstractStringBuilder;
+114 -1: (Ljava/security/CodeSource;Ljava/security/PermissionCollection;Ljava/lang/ClassLoader;[Ljava/security/Principal;)V
+16 -1: getShortVolatile
+18 -1: SoftReference.java
+3 -1: BST
+12 -1: isCastableTo
+28 -1: sun.zip.disableMemoryMapping
+11 -1: copyOfRange
+17 -1: ()Lsun/misc/Perf;
+59 -1: (Ljava/lang/String;[Ljava/io/File;Ljava/lang/ClassLoader;)V
+27 -1: (Lsun/misc/JavaAWTAccess;)V
+8 -1: DECLARED
+18 -1: loadedLibraryNames
+6 -1: CENNAM
+7 -1: encprop
+5 -1: ABASE
+27 -1: java/util/WeakHashMap$Entry
+13 -1: wrapWithPrims
+5 -1: UTF32
+29 -1: Ljava/net/URISyntaxException;
+6 -1: groups
+65 -1: <T:Ljava/lang/Object;>(Ljava/util/Set<+TT;>;)Ljava/util/Set<TT;>;
+32 -1: lambda$comparingByKey$6d558cbf$1
+15 -1: removeElementAt
+49 -1: [Ljava/util/concurrent/ConcurrentHashMap$Segment;
+32 -1: Sign character in wrong position
+6 -1: IBM819
+39 -1: java/security/cert/CertificateException
+4 -1: join
+30 -1: Ljava/lang/invoke/ForceInline;
+14 -1: expandCapacity
+19 -1: Ljava/lang/Integer;
+11 -1: NUMBER_THAI
+10 -1: getExtURLs
+9 -1: retainAll
+21 -1: (S)Ljava/lang/String;
+8 -1: truncate
+51 -1: java/util/ArraysParallelSortHelpers$FJObject$Sorter
+28 -1: newIndexOutOfBoundsException
+26 -1: JavaUtilJarAccessImpl.java
+22 -1: (II)Ljava/util/BitSet;
+10 -1: getLongAt0
+65 -1: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
+26 -1: (Ljava/lang/ThreadLocal;)I
+5 -1: (J)[B
+27 -1: Ljava/lang/CharacterData00;
+18 -1: sun/misc/Cleaner$1
+59 -1: (Ljava/util/List;Ljava/lang/Object;Ljava/util/Comparator;)I
+114 -1: (JLjava/util/function/ToDoubleFunction<Ljava/util/Map$Entry<TK;TV;>;>;DLjava/util/function/DoubleBinaryOperator;)D
+28 -1: java/lang/ClassCastException
+26 -1: (Ljava/lang/ThreadLocal;)V
+27 -1: ()[Ljava/lang/reflect/Type;
+13 -1: not invoker: 
+56 -1: (Ljava/net/URL;Ljava/net/Proxy;)Ljava/net/URLConnection;
+6 -1: before
+37 -1: ([DII)Ljava/util/stream/DoubleStream;
+9 -1: logicalOr
+9 -1: IS_METHOD
+12 -1: SPACE_USABLE
+12 -1: lastModified
+10 -1: setSigners
+8 -1: Invokers
+7 -1: nCopies
+12 -1: utf-32le-bom
+7 -1: (IIII)J
+17 -1: jdkSpecialVersion
+26 -1: ()Ljava/lang/StringBuffer;
+17 -1: SearchEntriesTask
+14 -1: java/net/Parts
+20 -1: Ljava/lang/Runnable;
+35 -1: java/util/WeakHashMap$ValueIterator
+19 -1: FinalReference.java
+7 -1: (IIII)V
+23 -1: Ljava/lang/ThreadGroup;
+10 -1: nullsFirst
+8 -1: setCache
+55 -1: (Ljava/util/List;Ljava/lang/Object;Ljava/lang/Object;)Z
+24 -1: java/util/SimpleTimeZone
+6 -1: IBM850
+6 -1: IBM852
+25 -1: sun/net/www/MeteredStream
+4 -1: exts
+6 -1: IBM855
+16 -1: allocateElements
+6 -1: IBM857
+19 -1: setDefaultUseCaches
+6 -1: IBM858
+5 -1: slice
+9 -1: marklimit
+77 -1: Ljava/lang/Object;Ljava/security/PrivilegedExceptionAction<Ljava/lang/Void;>;
+32 -1: java/util/Collections$CheckedSet
+12 -1: getModifiers
+8 -1: protocol
+10 -1: getInteger
+33 -1: ([J)Ljava/util/stream/LongStream;
+6 -1: IBM862
+8 -1: Map.java
+35 -1: java/lang/Class$EnclosingMethodInfo
+25 -1: (J)Ljava/math/BigInteger;
+31 -1: (Ljava/net/URL;Ljava/io/File;)V
+6 -1: IBM866
+6 -1: unload
+28 -1: sun/invoke/util/VerifyAccess
+105 -1: ()Ljava/util/Map<Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;Ljava/lang/annotation/Annotation;>;
+25 -1: Resetting to invalid mark
+20 -1: java/util/Vector$Itr
+5 -1: SHIFT
+11 -1: NonfairSync
+18 -1: getSecurityManager
+34 -1: ()[Ljava/lang/ClassValue$Entry<*>;
+28 -1: (J)Ljava/lang/StringBuilder;
+28 -1: (Ljava/security/PublicKey;)V
+12 -1: getResources
+6 -1: IBM874
+27 -1:  which Java does not define
+36 -1: (Ljava/lang/invoke/MethodTypeForm;)V
+48 -1: array length is not legal for long[] or double[]
+18 -1: IS_FIELD_OR_METHOD
+7 -1: Aliases
+17 -1: checkedExceptions
+13 -1: getDayOfMonth
+51 -1: (Ljava/util/Spliterator;Z)Ljava/util/stream/Stream;
+20 -1: java/io/EOFException
+26 -1: Enclosing method not found
+17 -1: flushLeftoverChar
+122 -1: (Ljava/lang/Class<*>;[Ljava/lang/Class<*>;[Ljava/lang/Class<*>;IILjava/lang/String;[B[B)Ljava/lang/reflect/Constructor<*>;
+18 -1: buildAnnotatedType
+21 -1: setContextClassLoader
+22 -1: java/io/UnixFileSystem
+20 -1: nonSyncContentEquals
+43 -1: java/util/Collections$SynchronizedSortedMap
+15 -1: Properties.java
+35 -1: com.oracle.usagetracker.config.file
+13 -1: java/util/Map
+18 -1: setEagerValidation
+13 -1: getSetMessage
+6 -1: unlock
+14 -1: refKindIsField
+22 -1: bad field type alias: 
+17 -1: casAnnotationData
+6 -1: AUGUST
+106 -1: (Ljava/util/concurrent/CountedCompleter;[Ljava/lang/Object;[Ljava/lang/Object;IIIILjava/util/Comparator;)V
+11 -1: monitorExit
+17 -1: linkMethodTracing
+69 -1: (Ljava/lang/String;Ljava/lang/String;Lsun/util/locale/BaseLocale$1;)V
+21 -1: java/lang/ClassLoader
+39 -1:               PKCS11 KeyStore debugging
+10 -1: checkRtype
+25 -1: getLocalGregorianCalendar
+23 -1: GenericDeclaration.java
+12 -1: isViewableAs
+22 -1: static_oop_field_count
+72 -1: (Ljava/util/function/ToDoubleFunction<-TT;>;)Ljava/util/Comparator<TT;>;
+11 -1: languageKey
+6 -1: Class 
+34 -1: java/util/HashMap$ValueSpliterator
+37 -1: (IJ)Ljava/lang/AbstractStringBuilder;
+17 -1: privilegedContext
+36 -1: java/util/LinkedHashMap$LinkedValues
+11 -1: getHostName
+10 -1: beginEntry
+7 -1: isAlpha
+61 -1: (Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/LambdaForm;
+10 -1: expandArgs
+14 -1: Finalizer.java
+14 -1: timeDefinition
+28 -1: ()Ljava/util/jar/Attributes;
+14 -1: ansi_x3.4-1968
+11 -1: setPriority
+23 -1: (C)Ljava/lang/Class<*>;
+26 -1: (Ljava/lang/Object;TV;)TV;
+70 -1: (Ljava/util/function/BiFunction;Ljava/lang/Object;Ljava/lang/Object;)V
+48 -1: ()Lsun/reflect/generics/factory/GenericsFactory;
+25 -1: java/lang/invoke/CallSite
+8 -1: tzdb.dat
+17 -1: containsAllLimits
+17 -1: fileNameMapLoaded
+6 -1: values
+17 -1: setLastAccessTime
+12 -1: expandFromVM
+50 -1: java/lang/invoke/MethodHandle$PolymorphicSignature
+3 -1: .EC
+14 -1: access denied 
+22 -1: java/util/AbstractList
+47 -1: (IILjava/lang/String;)Ljava/lang/StringBuilder;
+52 -1: ()Lsun/reflect/generics/repository/MethodRepository;
+22 -1: (Ljava/lang/String;)[B
+57 -1: (Ljava/lang/Object;)Ljava/lang/invoke/DirectMethodHandle;
+18 -1: compareAndSwapLong
+4 -1:  != 
+6 -1: StdArg
+29 -1: (Ljava/security/Permission;)V
+22 -1: ([D)Ljava/lang/String;
+28 -1: Lsun/reflect/MethodAccessor;
+14 -1: ansi_x3.4-1986
+20 -1: getPeakFinalRefCount
+29 -1: (Ljava/security/Permission;)Z
+5 -1: debug
+38 -1: (Ljava/lang/reflect/Constructor<*>;)[B
+27 -1: java/util/GregorianCalendar
+16 -1: Null replacement
+26 -1: ()Ljava/lang/reflect/Type;
+28 -1: DIRECTIONALITY_LEFT_TO_RIGHT
+102 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lsun/util/locale/BaseLocale;
+15 -1: isConvertibleTo
+24 -1: ARRAY_DOUBLE_INDEX_SCALE
+16 -1: getComponentType
+29 -1: sun/util/locale/LocaleMatcher
+11 -1: LOCALECACHE
+6 -1: UNWRAP
+16 -1: AbstractSet.java
+3 -1: CAT
+36 -1: java/lang/annotation/RetentionPolicy
+14 -1: getParameters0
+8 -1: .Handler
+33 -1: Ljava/lang/IllegalStateException;
+10 -1: RAW_RETURN
+20 -1: java/lang/ClassValue
+16 -1: getDisplayString
+152 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>([Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;I)Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+67 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>()Ljava/util/Map<TK;TV;>;
+214 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+33 -1: java/lang/invoke/SerializedLambda
+42 -1: ([Ljava/lang/Object;II)[Ljava/lang/Object;
+22 -1: java/util/zip/ZipUtils
+9 -1: setDaemon
+26 -1: java/net/HttpURLConnection
+6 -1: mkdirs
+20 -1: (Ljava/io/Reader;I)V
+28 -1: (IC)Ljava/lang/StringBuffer;
+45 -1: ([Ljava/lang/Class<*>;I)[Ljava/lang/Class<*>;
+29 -1: java/lang/invoke/MethodHandle
+28 -1: sun/misc/CompoundEnumeration
+6 -1: setVal
+23 -1: INTERNED_ARGUMENT_LIMIT
+4 -1: NULL
+49 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/Class;)Z
+43 -1: java/util/Collections$UnmodifiableSortedMap
+39 -1: (Ljava/lang/Object;Ljava/lang/Object;)I
+6 -1: ([JJ)I
+19 -1: java/io/PrintWriter
+25 -1: ()Ljava/lang/ThreadGroup;
+5 -1: (IJ)J
+16 -1: onMalformedInput
+15 -1: decrementAndGet
+11 -1: -2147483648
+6 -1: reduce
+12 -1: asCharBuffer
+39 -1: (Ljava/lang/Object;Ljava/lang/Object;)V
+44 -1: (Ljava/util/SortedSet;)Ljava/util/SortedSet;
+9 -1: backtrace
+3 3: Bar
+47 -1: ()Lsun/misc/JavaSecurityProtectionDomainAccess;
+39 -1: (Ljava/lang/Object;Ljava/lang/Object;)Z
+5 -1: (IJ)V
+6 -1: ([JJ)V
+22 -1: ([Ljava/lang/Thread;)I
+5 -1: (IJ)Z
+7 -1: ([BII)I
+79 -1: <T:Ljava/lang/Object;>(Ljava/util/Comparator<-TT;>;)Ljava/util/Comparator<TT;>;
+12 -1: getUnchecked
+10 -1: getBaseURL
+36 -1: (Ljava/lang/Object;)Ljava/util/List;
+53 -1: (Ljava/util/function/Function;)Ljava/util/Comparator;
+10 -1: getComment
+7 -1: ([BII)V
+30 -1: privateGetDeclaredConstructors
+58 -1: (Ljava/lang/String;ZILjava/util/Locale;)Ljava/lang/String;
+18 -1: unknown era name: 
+13 -1: invokeSpecial
+9 -1: checkLink
+16 -1: cspc8codepage437
+6 -1: stream
+18 -1: sun/nio/cs/UTF_8$1
+18 -1: contextClassLoader
+50 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;I)V
+30 -1: sun/util/calendar/BaseCalendar
+11 -1: enumeration
+18 -1: key can't be empty
+137 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<Ljava/util/Map$Entry<TK;TV;>;+TU;>;Ljava/util/function/BiFunction<-TU;-TU;+TU;>;)TU;
+10 -1: getBoolean
+5 -1: eetop
+49 -1: (Ljava/lang/invoke/MethodType;)Ljava/lang/String;
+43 -1: sun/reflect/generics/scope/ConstructorScope
+13 -1: CANADA_FRENCH
+39 -1: Ljava/nio/channels/ReadableByteChannel;
+15 -1: java/lang/Float
+29 -1: DIRECTIONALITY_OTHER_NEUTRALS
+52 -1: (ZLjava/nio/charset/Charset;Ljava/io/OutputStream;)V
+8 -1: appendTo
+19 -1: PARAGRAPH_SEPARATOR
+16 -1: (Unknown Source)
+4 -1: tree
+38 -1: (I[C)Ljava/lang/AbstractStringBuilder;
+14 -1: VerifierStream
+48 -1: (Ljava/util/Collection<TE;>;Ljava/lang/Object;)V
+15 -1: releaseInflater
+20 -1: getHeaderNamesInList
+17 -1: getSystemPackages
+8 -1: teardown
+6 -1: (BZI)I
+10 -1: checkWrite
+19 -1: JavaLangAccess.java
+31 -1: Ljava/lang/ClassValue$Identity;
+50 -1: (Ljava/util/concurrent/CountedCompleter;[S[SIIII)V
+24 -1: getDeclaredConstructors0
+3 -1: /..
+3 -1: /./
+16 -1: hashCodeForCache
+18 -1: Property settings:
+26 -1: Illegal initial capacity: 
+10 -1: text/plain
+61 -1: (Ljava/util/function/ToDoubleFunction;)Ljava/util/Comparator;
+24 -1: createMemoryManagerMBean
+10 -1: ,lastRule=
+9 -1: GMT-00:00
+5 -1: mtime
+40 -1: (Ljava/lang/String;I)[Ljava/lang/String;
+11 -1: (TT;TV;)TV;
+154 -1: (Ljava/lang/Class<*>;Ljava/lang/String;[Ljava/lang/Class<*>;Ljava/lang/Class<*>;[Ljava/lang/Class<*>;IILjava/lang/String;[B[B[B)Ljava/lang/reflect/Method;
+41 -1: (Ljava/util/jar/JarFile;)Ljava/util/List;
+43 -1: (JILjava/lang/Object;)Ljava/nio/ByteBuffer;
+19 -1: MethodTypeForm.java
+21 -1: java/util/jar/JarFile
+30 -1: java/lang/Integer$IntegerCache
+22 -1: getDisplayVariantArray
+6 -1: setAll
+13 -1: ClassValueMap
+52 -1: (Ljava/security/PublicKey;Ljava/security/Provider;)V
+51 -1: java/util/concurrent/ConcurrentHashMap$BaseIterator
+59 -1: (Ljava/lang/Runnable;Ljava/security/AccessControlContext;)V
+100 -1: (Ljava/util/concurrent/ConcurrentMap;Ljava/util/function/BiFunction;)Ljava/util/function/BiConsumer;
+8 -1: default 
+13 -1: compareAndSet
+10 -1: iso8859-13
+9 -1: putShortB
+14 -1: skipDelimiters
+28 -1: URI has a fragment component
+10 -1: iso8859-15
+42 -1: (Ljava/net/Proxy;)Ljava/net/URLConnection;
+23 -1: needsPackageAccessCheck
+9 -1: putShortL
+3 -1: //[
+69 -1: (Ljava/security/AccessControlContext;Ljava/security/DomainCombiner;)V
+18 -1: too many arguments
+35 -1: ([III)Ljava/util/Spliterator$OfInt;
+10 -1: CopiesList
+10 -1: iso-8859-1
+9 -1: ([BII[C)I
+10 -1: iso-8859-2
+11 -1: returnCount
+10 -1: iso-8859-4
+10 -1: iso-8859-5
+8 -1: utf_16be
+10 -1: iso-8859-7
+9 -1: isLimited
+9 -1: parseByte
+10 -1: iso-8859-9
+13 -1: , s.length() 
+10 -1: matchCerts
+14 -1: RECURSIVE_CHAR
+11 -1: reduceToInt
+11 -1: displayName
+9 -1: calendars
+64 -1: (Ljava/lang/String;ZLjava/util/jar/JarEntry;)Lsun/misc/Resource;
+11 -1: isProtected
+78 -1: (Ljava/util/SortedMap;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/SortedMap;
+4 -1: trim
+20 -1: java/nio/FloatBuffer
+17 -1: PreHashedMap.java
+74 -1: Ljava/util/concurrent/ConcurrentMap<Ljava/lang/String;Ljava/lang/String;>;
+22 -1: ([S)Ljava/lang/String;
+19 -1: PrintStreamOrWriter
+38 -1: java/util/Collections$EmptyEnumeration
+22 -1: java/util/LinkedList$1
+13 -1: sunpkcs11.jar
+25 -1: java/nio/DirectByteBuffer
+96 -1: (ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;
+7 -1: isArray
+43 -1: (Ljava/lang/String;)Ljava/util/Enumeration;
+52 -1: java/lang/invoke/MethodHandleImpl$AsVarargsCollector
+59 -1: (Ljava/lang/String;Lsun/misc/Resource;)Ljava/lang/Class<*>;
+26 -1: setJavaNetHttpCookieAccess
+15 -1: wrongTargetType
+57 -1: java/util/concurrent/ConcurrentHashMap$ForEachMappingTask
+33 -1: [Ljava/lang/reflect/TypeVariable;
+5 -1: load0
+39 -1: (Ljava/lang/String;)Ljava/lang/Boolean;
+21 -1: isHeldByCurrentThread
+14 -1: outOfBoundsMsg
+30 -1: Ljava/lang/ref/Reference$Lock;
+11 -1: ISO-8859-13
+84 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue<TT;>;)Ljava/lang/ClassValue$Entry<TT;>;
+11 -1: ISO-8859-15
+40 -1: (Ljava/net/URL;)Ljava/net/URLConnection;
+84 -1: <T:Ljava/lang/Object;:Ljava/lang/Comparable<-TT;>;>(Ljava/util/Collection<+TT;>;)TT;
+38 -1: sun/reflect/generics/scope/MethodScope
+5 -1: mutex
+11 -1: loaderTypes
+8 -1: defaults
+22 -1: getActualTypeArguments
+41 -1: DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+4 -1: keys
+71 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+94 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/MethodHandle;
+113 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractSet<TE;>;Ljava/util/Set<TE;>;Ljava/lang/Cloneable;Ljava/io/Serializable;
+12 -1: checkConnect
+39 -1: (Ljava/lang/String;Ljava/util/Locale;)V
+26 -1: ([CII[C)Ljava/lang/String;
+12 -1: isDoubleWord
+37 -1: configparser  JAAS ConfigFile parsing
+27 -1: sun/misc/Perf$GetPerfAction
+44 -1: (Ljava/util/Collections$UnmodifiableList;I)V
+4 -1: acos
+26 -1: java/nio/DirectLongBufferS
+7 -1: (ITE;)V
+14 -1: putIntVolatile
+24 -1: setContentHandlerFactory
+26 -1: java/nio/DirectLongBufferU
+10 -1: fieldCount
+11 -1: invokeBasic
+50 -1: (Ljava/util/zip/ZipEntry;)Ljava/util/jar/JarEntry;
+24 -1: java/util/Locale$Builder
+9 -1: setParent
+11 -1: asLifoQueue
+33 -1: lambda$comparingDouble$8dcf42ea$1
+24 -1: (Ljava/lang/Throwable;)I
+35 -1: (Lsun/misc/JavaUtilZipFileAccess;)V
+49 -1: (ILjava/lang/Object;)Ljava/util/HashMap$TreeNode;
+10 -1: CLASS_PATH
+6 -1: tclass
+11 -1: getExponent
+23 -1: getAnnotatedReturnType0
+18 -1: checkPackageAccess
+35 -1: Can not instantiate java.lang.Class
+24 -1: (Ljava/lang/Throwable;)V
+195 -1: (Ljava/lang/invoke/LambdaForm$Name;Ljava/lang/invoke/LambdaForm$Name;Ljava/lang/invoke/BoundMethodHandle$SpeciesData;Ljava/lang/invoke/BoundMethodHandle$SpeciesData;)Ljava/lang/invoke/LambdaForm;
+17 -1: Empty replacement
+3 -1: .SF
+14 -1: ByteOrder.java
+39 -1: ()Lsun/util/calendar/BaseCalendar$Date;
+35 -1: ()[Ljava/security/ProtectionDomain;
+12 -1: setElementAt
+30 -1: (Ljava/security/CodeSource;Z)Z
+45 -1: (Ljava/lang/Class<*>;)Ljava/lang/ClassLoader;
+52 -1: (Ljava/nio/charset/Charset;)Ljava/util/zip/ZipCoder;
+13 -1: foldArguments
+23 -1: java/time/LocalDateTime
+30 -1: [Lsun/launcher/LauncherHelper;
+16 -1: 0123456789abcdef
+60 -1: (Ljava/util/Spliterator$OfInt;Z)Ljava/util/stream/IntStream;
+33 -1: (ILjava/lang/String;IIIIIIIIIII)V
+20 -1: DMH.newInvokeSpecial
+28 -1: java/nio/charset/CoderResult
+33 -1: sun/nio/cs/StandardCharsets$Cache
+11 -1: saveConvert
+14 -1: ExtClassLoader
+12 -1: parentOrNull
+20 -1: insertParameterTypes
+32 -1: (II)Ljava/util/stream/IntStream;
+13 -1: setStackTrace
+20 -1:  is not an enum type
+3 -1: CNT
+4 -1: host
+85 -1: ([Ljava/lang/Object;Ljava/util/function/IntFunction;)Ljava/util/function/IntConsumer;
+11 -1: batchRemove
+8 -1: newField
+16 5: sun/nio/cs/UTF_8
+104 -1: (Ljava/lang/invoke/LambdaForm$Name;Ljava/lang/invoke/LambdaForm$Name;)Ljava/lang/invoke/LambdaForm$Name;
+8 -1: saturday
+35 -1: java/util/ArraysParallelSortHelpers
+15 -1: java/util/Queue
+40 -1: (Ljava/lang/Class<*>;)Ljava/lang/String;
+7 -1: toChars
+5 -1: first
+17 -1: ArrayDecoder.java
+30 -1: ()Lsun/reflect/MethodAccessor;
+26 -1: thread group can't be null
+13 -1: IllegalName: 
+32 -1: java/util/Collections$SetFromMap
+14 -1: line.separator
+17 -1: getDeclaredMethod
+10 -1: getMinutes
+35 -1: (Lsun/util/locale/BaseLocale$Key;)I
+40 -1: ([Ljava/lang/String;)Ljava/lang/Process;
+31 -1: Ljava/util/LinkedHashMap$Entry;
+13 -1: , str.length 
+8 -1: getProbe
+6 -1: ([DI)I
+5 -1: (CI)I
+23 -1: saveAndRemoveProperties
+6 -1: rehash
+3 -1: lcb
+31 -1: Ljava/util/Arrays$NaturalOrder;
+55 -1: (IILjava/lang/String;)Ljava/lang/AbstractStringBuilder;
+10 -1: loadFactor
+15 -1: putLongVolatile
+34 -1: sun/misc/URLClassPath$FileLoader$1
+12 -1: Europe/Paris
+8 -1: DECEMBER
+86 -1: Ljava/lang/Object;Ljava/security/PrivilegedAction<Lsun/misc/Launcher$AppClassLoader;>;
+22 -1: getImplMethodSignature
+38 -1: Malformed enclosing method information
+8 -1: maskNull
+3 -1: lct
+21 -1: CONSTRUCTOR_MODIFIERS
+36 -1: ()Lsun/misc/JavaNetHttpCookieAccess;
+12 -1: HashIterator
+84 -1: (Ljava/lang/Class;Ljava/lang/Class$AnnotationData;Ljava/lang/Class$AnnotationData;)Z
+33 -1: java/lang/Character$UnicodeScript
+5 -1: toHex
+27 -1: java/security/AllPermission
+17 -1: appendReplacement
+20 -1: SimpleImmutableEntry
+18 -1: getRequestProperty
+12 -1: compareCerts
+44 -1: java/util/ArrayPrefixHelpers$IntCumulateTask
+19 -1: makeSpreadArguments
+222 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceEntriesTask;Ljava/util/function/Function;Ljava/util/function/BiFunction;)V
+8 -1: addFirst
+6 -1: nextUp
+35 -1: (Ljava/net/ContentHandlerFactory;)V
+40 -1: (Ljava/lang/String;)Ljava/lang/Class<*>;
+23 -1: java/util/LocaleISOData
+14 -1: PREPARED_FORMS
+6 -1: FJByte
+20 -1: getGenericSuperclass
+6 -1: offset
+16 -1: LocaleUtils.java
+12 -1: isUnresolved
+18 -1: aliases_ISO_8859_1
+18 -1: aliases_ISO_8859_2
+15 -1: isSurrogatePair
+18 -1: aliases_ISO_8859_4
+18 -1: aliases_ISO_8859_5
+6 -1: EXTLEN
+18 -1: aliases_ISO_8859_7
+15 -1: Comparator.java
+18 -1: aliases_ISO_8859_9
+15 -1: ISO_8859-2:1987
+22 -1: Ljava/util/List<+TE;>;
+16 -1: Unknown Category
+3 -1: CST
+51 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractList<TE;>;
+6 -1: FRIDAY
+40 -1: (Ljava/lang/String;ZZ)Ljava/lang/String;
+13 -1: isInterrupted
+8 -1: utf_16le
+89 -1: (BLjava/lang/Class<*>;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/DirectMethodHandle;
+22 -1: checkInvocationCounter
+12 -1: EPOCH_OFFSET
+35 -1: (JJILjava/nio/DirectByteBuffer$1;)V
+7 -1: canRead
+9 -1: getLoader
+18 -1: publicConstructors
+23 -1: factory already defined
+33 -1: java/lang/ref/ReferenceQueue$Null
+37 -1: (Ljava/util/List;Ljava/util/Random;)V
+25 -1: setPackageAssertionStatus
+20 -1: MapReduceEntriesTask
+11 -1: OPEN_DELETE
+35 -1: (Ljava/util/Set;Ljava/lang/Class;)V
+9 -1: rootGroup
+10 -1: updateForm
+22 -1: JavaUtilJarAccess.java
+3 -1: CTT
+57 -1: (Lsun/reflect/MethodInfo;)Ljava/lang/reflect/Constructor;
+82 -1: <T:Ljava/lang/Object;>(Ljava/util/NavigableSet<TT;>;)Ljava/util/NavigableSet<TT;>;
+13 -1: getReturnType
+34 -1: java/util/HashMap$EntrySpliterator
+14 -1: TIME_UNDEFINED
+32 -1: com/sun/crypto/provider/AESCrypt
+7 -1: H_DIGIT
+20 -1: clearAssertionStatus
+44 -1: java/lang/invoke/MethodHandleImpl$BindCaller
+8 -1: scloader
+6 -1: IBM923
+5 -1: read0
+5 -1: read1
+4 -1: true
+9 -1: BA_HIDDEN
+16 -1: jvmUpdateVersion
+36 -1: java/lang/StringCoding$StringDecoder
+37 -1: (J)Ljava/nio/file/attribute/FileTime;
+3 -1: lib
+17 -1: getParameterTypes
+15 -1: FinalizerThread
+31 -1: ()Lsun/util/calendar/Gregorian;
+50 -1: (Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;
+13 -1: PROP_SETTINGS
+33 -1: java/util/function/BinaryOperator
+70 -1: (ILjava/util/List<Ljava/lang/Class<*>;>;)Ljava/lang/invoke/MethodType;
+25 -1: getDefaultRequestProperty
+27 -1: (Ljava/util/jar/JarEntry;)V
+27 -1: SPLITERATOR_CHARACTERISTICS
+18 -1: FieldAccessor.java
+10 -1: setComment
+62 -1: (Ljava/lang/String;)Ljava/lang/management/MemoryManagerMXBean;
+11 -1: array_klass
+39 -1: ()Ljava/lang/Class$EnclosingMethodInfo;
+67 -1: ([Ljava/lang/ClassValue$Entry<*>;ILjava/lang/ClassValue$Entry<*>;)I
+9 -1: (II[CII)I
+50 -1: (Ljava/util/jar/JarFile;Ljava/util/zip/ZipEntry;)V
+20 -1: SPECIFICATION_VENDOR
+72 -1: (Lsun/misc/URLClassPath$JarLoader;Ljava/net/URL;)Ljava/util/jar/JarFile;
+87 -1: <T:Ljava/lang/Object;>(Ljava/lang/ThreadLocal<Ljava/lang/ref/SoftReference<TT;>;>;TT;)V
+9 -1: isVarArgs
+10 -1: setBoolean
+12 -1: (TK;TV;TV;)Z
+16 -1: findSharedClass0
+5 -1: csize
+49 -1: Ljava/security/cert/CertificateEncodingException;
+40 -1: java/util/concurrent/locks/ReentrantLock
+86 -1: (Ljava/io/OutputStream;Ljava/lang/Object;Ljava/lang/String;)Lsun/nio/cs/StreamEncoder;
+5 -1: ready
+38 -1: Ljava/security/AccessControlException;
+28 -1: UnmodifiableRandomAccessList
+69 -1: <T:Ljava/lang/Object;>([TT;Ljava/util/function/BinaryOperator<TT;>;)V
+27 -1: Ljava/lang/invoke/Invokers;
+39 -1: java/util/LinkedList$DescendingIterator
+11 -1: writeFields
+17 -1: classLoaderDepth0
+18 -1: permutedTypesMatch
+52 -1: (Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/List;
+12 -1: linkToStatic
+10 -1: CheckedMap
+6 -1: CENOFF
+8 -1: lastRule
+15 -1: java/lang/Short
+39 -1: ()Ljava/lang/Class$ReflectionData<TT;>;
+8 -1: nextDown
+14 -1: image/x-pixmap
+39 -1: (Ljava/lang/Class;[Ljava/lang/Object;)V
+25 -1: defineClassSourceLocation
+23 -1: sun/misc/PostVMInitHook
+15 -1: could not load 
+16 -1: allowArraySyntax
+90 -1: Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater<Ljava/io/BufferedInputStream;[B>;
+10 -1: putBoolean
+11 -1:  has params
+14 -1: setMaxPriority
+10 -1: mayContain
+46 -1: java/lang/reflect/MalformedParametersException
+10 -1: baseLocale
+14 -1: isSubwordOrInt
+10 -1: nextDouble
+32 -1: java/lang/Character$UnicodeBlock
+85 -1: (JLjava/util/function/ToDoubleBiFunction;DLjava/util/function/DoubleBinaryOperator;)D
+20 -1: numberOfLeadingZeros
+59 -1: (I[Ljava/lang/Class<*>;)[Ljava/lang/invoke/LambdaForm$Name;
+7 -1: setSize
+29 -1: java/io/FileNotFoundException
+9 -1: getString
+24 -1: ([CII)Ljava/lang/String;
+38 -1: (Ljava/lang/String;Ljava/lang/Class;)V
+5 -1: shift
+18 -1: getConstructorSlot
+41 -1: java/lang/ThreadLocal$SuppliedThreadLocal
+16 -1: UNASSIGNED_STACK
+20 -1: Malformed class name
+12 -1: ofEpochMilli
+34 -1: sun/launcher/LauncherHelper$StdArg
+33 -1: java/nio/ByteBufferAsShortBufferB
+7 -1: convert
+21 -1: ()[Ljava/util/Locale;
+15 -1: ISO_8859-5:1988
+35 -1: av[0] not instace of MethodHandle: 
+33 -1: java/nio/ByteBufferAsShortBufferL
+5 -1: hypot
+16 -1: InputStream.java
+13 -1: reinvokerForm
+39 -1: JVMTI_THREAD_STATE_WAITING_INDEFINITELY
+16 -1: sun/misc/Version
+66 -1: <T::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TT;>;)[TT;
+11 -1: codePointAt
+30 -1: ([Ljava/lang/reflect/Method;)V
+9 -1: duplicate
+9 -1: interface
+5 -1: X.509
+24 -1: SynchronizedNavigableSet
+8 -1: us-ascii
+17 -1: getUnresolvedType
+21 -1: PRIVATE_USE_EXTENSION
+4 -1: form
+93 -1: (Ljava/util/ArrayPrefixHelpers$LongCumulateTask;Ljava/util/function/LongBinaryOperator;[JII)V
+27 -1: sealing violation: package 
+34 -1: RuntimeVisibleParameterAnnotations
+17 -1: LF_INVSTATIC_INIT
+14 -1: Gregorian.java
+32 -1: java/util/function/UnaryOperator
+3 -1: log
+3 -1: low
+22 -1: sun/misc/JavaNetAccess
+9 -1: getLength
+21 -1: getRawTypeAnnotations
+36 -1: (Ljava/lang/String;)Ljava/lang/Long;
+9 -1: getNumber
+66 -1: (ILjava/lang/Object;)Ljava/util/concurrent/ConcurrentHashMap$Node;
+20 -1: (Ljava/lang/Class;)C
+89 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Map$Entry<TK;TV;>;
+6 -1: ENDSIG
+20 -1: (Ljava/lang/Class;)I
+20 -1: (Ljava/lang/Class;)J
+24 -1: [[Ljava/io/Serializable;
+22 -1: serialPersistentFields
+7 -1: console
+142 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+27 -1: (Ljava/nio/ByteBuffer;ICZ)V
+20 -1: (Ljava/lang/Class;)V
+40 -1: java/lang/ArrayIndexOutOfBoundsException
+6 -1: this$0
+51 -1: (Ljava/lang/invoke/MemberName;[Ljava/lang/Object;)V
+18 -1: packageAccessValid
+33 -1: ([Ljava/lang/StackTraceElement;)V
+8 -1: constant
+113 -1: (Ljava/lang/String;Ljava/nio/ByteBuffer;IILjava/security/ProtectionDomain;Ljava/lang/String;)Ljava/lang/Class<*>;
+8 -1: isMethod
+20 -1: (Ljava/lang/Class;)Z
+6 -1: ENDSIZ
+8 -1: newEntry
+57 -1: (Ljava/lang/Object;)Ljava/lang/IndexOutOfBoundsException;
+25 -1: (Ljava/util/Comparator;)V
+8 -1: isBridge
+6 -1: ([BI)I
+6 -1: ([BI)J
+16 -1: getReferenceKind
+26 -1: [Ljava/security/Principal;
+71 -1: (Ljava/lang/Class;[Ljava/lang/reflect/Field;)[Ljava/lang/reflect/Field;
+32 -1: ()Ljava/lang/ClassValue$Version;
+16 -1: SearchValuesTask
+17 -1: setCompressedSize
+16 -1: DEFAULT_CAPACITY
+108 -1: <K:Ljava/lang/Object;V::Ljava/lang/Comparable<-TV;>;>()Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
+27 -1: java/util/ComparableTimSort
+41 -1: null StackTraceElement in serial stream. 
+6 -1: ([BI)V
+44 -1: (Ljava/util/jar/JarFile;)Lsun/misc/JarIndex;
+71 -1: (Ljava/util/jar/JarFile;Ljava/util/Enumeration;)Ljava/util/Enumeration;
+52 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/Class<*>;)Z
+36 -1: [Ljava/lang/reflect/TypeVariable<*>;
+17 -1: OutputStream.java
+8 -1: combiner
+15 -1: decodeArrayLoop
+19 -1: (Ljava/io/Writer;)V
+41 -1: (Ljava/util/List<*>;Ljava/util/List<*>;)I
+35 -1: ()[Ljava/security/cert/Certificate;
+33 -1: ([I)Ljava/util/Spliterator$OfInt;
+9 -1: NF_asType
+17 -1: java/io/Closeable
+11 -1: updateBytes
+12 -1: charsets.jar
+18 -1: getDeclaredFields0
+47 -1: (Ljava/lang/Object;I)Ljava/lang/reflect/Member;
+60 -1: (Ljava/lang/String;ILjava/lang/String;)Ljava/nio/ByteBuffer;
+15 -1: getTotalSeconds
+57 -1: (Ljava/util/Collection<+Ljava/util/Map$Entry<TK;TV;>;>;)Z
+4 -1: JULY
+10 -1: Exceptions
+41 -1: ()Ljava/util/List<Ljava/io/IOException;>;
+14 -1: ParseUtil.java
+13 -1: getJarFileURL
+29 -1: setJavaIOFileDescriptorAccess
+24 -1: ARRAY_OBJECT_BASE_OFFSET
+21 -1: onUnmappableCharacter
+53 -1: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map;
+24 -1: MethodHandleNatives.java
+40 -1: java/nio/charset/MalformedInputException
+37 -1: [Ljava/lang/reflect/AnnotatedElement;
+15 -1: CLASSPATH_CHARS
+18 -1: [Ljava/lang/Class;
+7 -1: FJFloat
+47 -1: <T:Ljava/lang/Object;>(Ljava/util/List<TT;>;I)V
+19 -1: Ljava/lang/Runtime;
+23 -1: java/lang/CharacterData
+42 -1: (Ljava/lang/Void;Ljava/lang/ClassLoader;)V
+76 -1: (Ljava/nio/channels/ReadableByteChannel;Ljava/nio/charset/CharsetDecoder;I)V
+56 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;B)V
+19 -1: java/util/zip/CRC32
+33 -1: <T:Ljava/lang/Object;>([TT;I)[TT;
+22 -1: ([F)Ljava/lang/String;
+5 -1: UTF_8
+20 -1: aliases_UTF_32BE_BOM
+11 -1: Buffer.java
+78 -1: <T:Ljava/lang/Object;>(Ljava/util/Comparator<TT;>;)Ljava/util/Comparator<TT;>;
+44 -1: (Ljava/lang/String;)Ljava/util/zip/ZipEntry;
+9 -1: malformed
+4 -1: JUNE
+51 -1: (Ljava/util/jar/JarFile;Ljava/util/jar/JarFile$1;)V
+6 -1: locale
+34 -1: (Ljava/util/function/BiFunction;)V
+10 -1: setMinutes
+40 -1: (Ljava/lang/reflect/AccessibleObject;Z)V
+12 -1: maybeCompile
+46 -1: (Ljava/lang/Class;Ljava/lang/reflect/Method;)V
+7 -1: getEras
+55 -1: <T:Ljava/lang/Object;>([TT;Ljava/util/Iterator<*>;)[TT;
+17 -1: toUnsignedString0
+32 -1: (Ljava/lang/invoke/MethodType;)V
+32 -1: (Ljava/lang/invoke/MethodType;)Z
+10 -1: Class.java
+27 -1: ()Ljava/util/Iterator<TK;>;
+29 -1: WINDOWS_EPOCH_IN_MICROSECONDS
+41 -1: (Ljava/io/InputStream;)Ljava/lang/String;
+4 -1: prev
+24 -1: ()Ljava/util/Properties;
+11 -1: awaitBooted
+19 -1: generateConstructor
+22 -1: sun/misc/SharedSecrets
+19 -1: getDateTimeInstance
+43 -1: (IIILsun/util/calendar/BaseCalendar$Date;)J
+5 -1: setID
+11 -1: Locale.java
+12 -1: getRootGroup
+15 -1: setLastModified
+7 -1: trouble
+28 -1: (Z)Ljava/lang/StringBuilder;
+5 -1: setIO
+17 -1: loadClassInternal
+23 -1: java/lang/ref/Finalizer
+8 -1: EmptySet
+16 -1: aliases_UTF_16BE
+50 -1: (Ljava/util/NavigableMap;)Ljava/util/NavigableMap;
+15 -1: unmodifiableMap
+48 -1: (Ljava/lang/Class<*>;)Lsun/reflect/ConstantPool;
+15 -1: arrayContentsEq
+7 -1: EXT_TAG
+31 -1: (Ljava/util/HashMap$TreeNode;)Z
+5 -1: cp737
+22 -1: java/util/zip/Checksum
+5 -1: names
+22 -1: ConcurrentHashMap.java
+7 -1: ([J[J)Z
+7 -1: WAITING
+31 -1: sun.launcher.resources.launcher
+14 -1: getThreadGroup
+8 -1: PutField
+12 -1: hugeCapacity
+9 -1: isPackage
+72 -1: (Ljava/lang/ThreadLocal<*>;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+23 7: sun/nio/ch/DirectBuffer
+13 -1: Checksum.java
+25 -1: (Ljava/nio/ByteBuffer;I)C
+51 -1: (Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+25 -1: (Ljava/nio/ByteBuffer;I)D
+7 -1: treeify
+25 -1: (Ljava/nio/ByteBuffer;I)F
+5 -1: setIn
+25 -1: (Ljava/nio/ByteBuffer;I)I
+20 -1: TRACE_METHOD_LINKAGE
+25 -1: (Ljava/nio/ByteBuffer;I)J
+7 -1: putIntB
+22 -1: createGarbageCollector
+50 -1: <T:Ljava/lang/Object;>(Ljava/lang/Class<TT;>;)[TT;
+25 -1: (Ljava/nio/ByteBuffer;I)S
+7 -1: putIntL
+19 -1: (B)Ljava/lang/Byte;
+14 -1: Hashtable.java
+29 -1: java/lang/ArrayStoreException
+11 -1: all_allowed
+16 -1: getLastRawOffset
+7 -1: inReady
+36 -1: java/lang/ThreadLocal$ThreadLocalMap
+40 -1: (ILjava/lang/String;Ljava/lang/String;)V
+23 -1: Ljava/lang/ThreadLocal;
+16 -1: classValueOrNull
+62 -1: (Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/MethodHandle;
+23 -1: preparedFieldLambdaForm
+22 -1: (Z)Ljava/lang/Boolean;
+14 -1: ThreadLocalMap
+27 -1: java/lang/StackTraceElement
+13 -1: getEntryCSize
+19 -1: java.security.debug
+53 -1: (Ljava/util/Collection<*>;Ljava/util/Collection<*>;)Z
+6 -1: LOCLEN
+40 -1: Ljava/lang/Class<Ljava/lang/Character;>;
+6 -1: (JJB)V
+66 -1: Ljava/util/Hashtable<Ljava/lang/String;Ljava/net/ContentHandler;>;
+31 -1: [[Ljava/lang/StackTraceElement;
+9 -1: putStatic
+16 -1: Asia/Ho_Chi_Minh
+15 -1: getDisplayNames
+13 -1: convertToAbbr
+23 -1: Method not implemented.
+15 -1: isCCLOverridden
+14 -1: doubleCapacity
+137 -1: (Ljava/lang/Class<*>;ZLjava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class<*>;)Ljava/util/List<Ljava/lang/invoke/MemberName;>;
+219 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceKeysTask;Ljava/util/function/Function;Ljava/util/function/BiFunction;)V
+7 -1: native 
+29 -1: (Ljava/lang/reflect/Field;Z)V
+18 -1: Ljava/util/Locale;
+31 -1: Ljava/util/concurrent/TimeUnit;
+16 -1: threadsSuspended
+7 -1: ([III)V
+20 -1: setMaxDelimCodePoint
+18 -1: contentClassPrefix
+13 -1: mappingOffset
+10 -1: toIndex = 
+47 -1: (Ljava/lang/CharSequence;)Ljava/io/PrintStream;
+12 -1: booleanValue
+13 -1: putMapEntries
+17 -1: defaultBundleName
+50 -1: (Ljava/util/concurrent/CountedCompleter;[B[BIIII)V
+10 -1: executable
+20 -1: java/time/ZoneOffset
+28 -1: java/lang/ref/FinalReference
+11 -1: newTreeNode
+7 -1: lookup2
+10 -1: TableStack
+59 -1: Ljava/util/concurrent/ConcurrentHashMap$ValuesView<TK;TV;>;
+11 -1: getAccessor
+9 -1: available
+18 -1: java/io/FileReader
+34 -1: java/security/ProtectionDomain$3$1
+16 -1: integer overflow
+11 -1: internTable
+28 -1: Ljava/util/HashMap$TreeNode;
+19 -1: | invocationCounter
+12 -1: findResource
+9 -1: isLoaded0
+5 -1: cp775
+24 -1: DIRECTIONALITY_UNDEFINED
+9 -1: isInvalid
+7 -1: lookupN
+35 -1: (Lsun/reflect/MethodAccessorImpl;)V
+6 -1: ENDSUB
+4 -1:  to 
+59 -1: ([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;
+10 -1: meta-index
+6 -1: INDENT
+9 -1: WEDNESDAY
+40 -1: ()Ljava/lang/annotation/RetentionPolicy;
+14 -1: getUsableSpace
+7 -1: TUESDAY
+51 -1: (Ljava/lang/Class;I)Ljava/lang/invoke/MethodHandle;
+12 -1: getSubjectDN
+21 -1: Ljava/io/InputStream;
+25 -1: (IC)Ljava/nio/CharBuffer;
+52 -1: (Ljava/nio/CharBuffer;)Ljava/util/function/Supplier;
+17 -1: ()[Ljava/net/URL;
+6 -1: search
+10 -1: Main-Class
+8 -1: ([CIIC)I
+16 -1: Certificate.java
+14 -1: spreadInvokers
+22 -1: sun/nio/cs/ISO_8859_15
+6 -1: accept
+18 -1: ReflectAccess.java
+13 -1: java/nio/Bits
+14 -1: linkToCallSite
+46 -1: Ljava/nio/charset/UnsupportedCharsetException;
+8 -1: ([CIIC)V
+9 -1: (TT;TV;)V
+26 -1: java/lang/OutOfMemoryError
+34 -1: policy        loading and granting
+76 -1: (Ljava/nio/CharBuffer;ILjava/nio/ByteBuffer;I)Ljava/nio/charset/CoderResult;
+13 -1: x-windows-949
+21 -1: Ljava/io/PrintStream;
+9 -1: initNames
+12 -1: testAnyFlags
+65 -1: (Ljava/lang/reflect/Method;)Ljava/lang/invoke/DirectMethodHandle;
+34 -1: (Ljava/util/List;)Ljava/util/List;
+10 -1: CacheEntry
+10 -1: hasAllPerm
+26 -1: java/nio/charset/Charset$1
+26 -1: java/nio/charset/Charset$2
+19 -1: ()Ljava/util/Stack;
+26 -1: java/nio/charset/Charset$3
+62 -1: (Ljava/lang/String;)Lsun/util/calendar/LocalGregorianCalendar;
+23 -1: ARRAY_FLOAT_INDEX_SCALE
+23 -1: (Ljava/lang/Object;IS)V
+13 -1: x-windows-950
+31 -1: Ljava/util/Hashtable$Entry<**>;
+87 -1: Ljava/util/WeakHashMap<Ljava/lang/ClassValue$Identity;Ljava/lang/ClassValue$Entry<*>;>;
+9 -1: permClass
+37 -1: (Ljava/security/ProtectionDomain$3;)V
+99 -1: <S::Lsun/reflect/generics/tree/Signature;>Lsun/reflect/generics/repository/AbstractRepository<TS;>;
+37 -1: ()Ljava/util/function/BinaryOperator;
+64 -1: java/util/Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+91 -1: (Ljava/util/ArrayPrefixHelpers$IntCumulateTask;Ljava/util/function/IntBinaryOperator;[III)V
+6 -1: getCrc
+25 -1: ByteArrayInputStream.java
+9 -1: SYNTHETIC
+52 -1: Ljava/lang/ref/PhantomReference<Ljava/lang/Object;>;
+246 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceKeysToDoubleTask;Ljava/util/function/ToDoubleFunction;DLjava/util/function/DoubleBinaryOperator;)V
+38 -1: java/lang/Throwable$WrappedPrintStream
+21 -1: Illegal load factor: 
+43 -1: Ljava/util/Deque<Ljava/util/zip/Inflater;>;
+3 -1: map
+6 -1: expand
+6 -1: access
+3 -1: max
+33 -1: impliesCreateAccessControlContext
+3 -1: may
+53 -1: java/util/concurrent/ConcurrentHashMap$ReduceKeysTask
+91 -1: Ljava/lang/Object;Ljava/security/PrivilegedExceptionAction<Lsun/misc/URLClassPath$Loader;>;
+60 -1: attempt to add a Permission to a readonly Permissions object
+21 -1: canonicalizeExtension
+11 -1: copyValueOf
+25 -1: (IJ)Ljava/nio/LongBuffer;
+112 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<-TV;+TU;>;Ljava/util/function/BiFunction<-TU;-TU;+TU;>;)TU;
+11 -1: DeqIterator
+11 -1: SpeciesData
+8 -1: getCause
+16 -1: aliases_UTF_16LE
+51 -1: (TT;TV;Ljava/util/function/BinaryOperator<TV;>;)TV;
+25 -1: (JF)Ljava/nio/ByteBuffer;
+16 -1: sun/misc/IOUtils
+32 -1: Ljava/util/Locale$FilteringMode;
+6 -1: .class
+13 -1: getPermission
+13 -1: startsWithLOC
+8 -1: Identity
+23 -1: ([BII)Ljava/lang/Class;
+15 -1: putByteVolatile
+36 -1: (Ljava/util/Deque;)Ljava/util/Queue;
+22 -1: (Ljava/lang/Object;S)V
+47 -1: java/util/concurrent/ConcurrentHashMap$BulkTask
+4 -1: n = 
+9 -1: (ITE;)TE;
+5 -1: zeroD
+18 -1: formatUnsignedLong
+29 -1:     default display locale = 
+23 -1: java/io/File$PathStatus
+5 -1: zeroF
+20 -1: Ljava/util/Set<TK;>;
+20 -1: (Ljava/util/List;I)V
+5 -1: zeroI
+5 -1: zeroJ
+7 -1: context
+39 -1: Ljava/nio/channels/WritableByteChannel;
+5 -1: zeroL
+34 -1: Lsun/util/calendar/CalendarSystem;
+24 -1: JVMTI_THREAD_STATE_ALIVE
+18 -1: (Ljava/util/Set;)V
+18 -1: (Ljava/util/Set;)Z
+42 -1: (TT;Ljava/lang/ref/ReferenceQueue<-TT;>;)V
+7 -1: entries
+30 -1: (Ljava/util/WeakHashMap;IIII)V
+15 -1: csisolatingreek
+38 -1: ([Ljava/lang/Class;)Ljava/lang/Object;
+12 -1: isMalformed3
+12 -1: isMalformed4
+5 -1: FJInt
+23 -1: java/util/LinkedHashMap
+20 -1: malformedInputAction
+12 -1: Charset.java
+5 -1: LLL_L
+42 -1: (Ljava/util/Collection;)Ljava/lang/Object;
+22 -1: makeMethodHandleInvoke
+3 -1: mdt
+7 -1: unicode
+12 -1: newInstance0
+10 -1: checkCerts
+34 -1: java/util/WeakHashMap$HashIterator
+23 -1: (Ljava/lang/Object;JI)I
+9 -1: hexDigits
+13 -1: javaToDosTime
+24 -1: (I)Ljava/nio/LongBuffer;
+6 -1: A_DATA
+12 -1: deepToString
+23 -1: (Ljava/lang/Object;JI)V
+91 -1: (JLjava/util/function/ToLongBiFunction<-TK;-TV;>;JLjava/util/function/LongBinaryOperator;)J
+23 -1: bad spread array length
+11 -1: readTimeout
+14 -1: toAbsolutePath
+8 -1: isFinite
+19 -1: currentLoadedClass0
+3 -1: \xef\xbf\xbd
+23 -1: (Ljava/nio/file/Path;)I
+8 -1: handlers
+21 -1: (Ljava/util/List;II)V
+89 -1: (Lsun/misc/URLClassPath$Loader;Ljava/lang/String;Ljava/net/URL;Ljava/net/URLConnection;)V
+8 -1: OVERFLOW
+8 -1: newTable
+8 -1: THURSDAY
+6 -1: notify
+12 -1: initialValue
+35 -1: (I)Ljava/util/LinkedList$Node<TE;>;
+18 -1: AsVarargsCollector
+26 -1: (Lsun/misc/JavaIOAccess;)V
+18 -1: ()Ljava/lang/Void;
+23 -1: (Ljava/nio/file/Path;)Z
+16 -1: MINUTE_IN_MILLIS
+67 -1: (Ljava/lang/Class;[Ljava/lang/Class;Z)Ljava/lang/invoke/MethodType;
+18 -1: Ljava/util/Vector;
+70 -1: (Ljava/lang/reflect/Constructor;[Ljava/lang/Object;)Ljava/lang/Object;
+40 -1: (Ljava/lang/Object;ILjava/lang/Object;)V
+25 -1: UnresolvedPermission.java
+14 -1: ReduceKeysTask
+21 -1: ()[Ljava/lang/Object;
+129 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;Ljava/io/Serializable;
+16 -1: ClassLoader.java
+46 -1: Ljava/util/Comparators$NaturalOrderComparator;
+17 -1: compareAndSwapInt
+22 -1: packageDefinitionValid
+41 -1: ([Ljava/lang/Object;[Ljava/lang/Object;)Z
+162 -1: (Ljava/util/List<Ljava/util/Locale$LanguageRange;>;Ljava/util/Collection<Ljava/lang/String;>;Ljava/util/Locale$FilteringMode;)Ljava/util/List<Ljava/lang/String;>;
+16 -1: sun.zip.zipFiles
+17 -1: java_runtime_name
+31 -1: (Ljava/lang/ClassValue$Entry;)V
+31 -1: (Ljava/lang/ClassValue$Entry;)Z
+30 -1: <T:Ljava/lang/Object;>(TT;)TT;
+39 -1: JavaSecurityProtectionDomainAccess.java
+24 -1: (I)Ljava/lang/Throwable;
+7 -1: FJShort
+9 -1: putFloatB
+19 -1: checkedNavigableSet
+25 -1: java/lang/invoke/Invokers
+18 -1: setIfModifiedSince
+14 -1: parameterTypes
+41 -1: (Ljava/lang/Object;Ljava/lang/Runnable;)V
+9 -1: putFloatL
+11 -1: getTypeCode
+5 -1: (ZZ)I
+24 -1: java/lang/ProcessBuilder
+9 -1: UNDERFLOW
+21 -1: VolatileCallSite.java
+24 -1: (C)Ljava/nio/CharBuffer;
+55 -1: java/util/concurrent/ConcurrentHashMap$ForEachValueTask
+26 -1: (Ljava/lang/String;[CII)[B
+18 -1: reduceKeysToDouble
+5 -1: (ZZ)Z
+23 -1: setCallSiteTargetNormal
+3 -1: min
+4 -1: ceil
+62 -1: (Ljava/lang/String;)Ljava/util/LinkedList<Ljava/lang/String;>;
+29 -1: (Ljava/util/AbstractList;II)V
+32 -1: Ljava/lang/Class$AnnotationData;
+21 -1: createFileExclusively
+64 -1: (Ljava/lang/ref/SoftReference;I)Ljava/lang/Class$ReflectionData;
+26 -1: java/lang/Short$ShortCache
+54 -1: (Ljava/net/URL;Ljava/io/File;)Ljava/net/URLConnection;
+29 -1: Lsun/nio/cs/Surrogate$Parser;
+58 -1: (Ljava/lang/Class;)Lsun/reflect/annotation/AnnotationType;
+8 -1: findForm
+53 -1: Ljava/lang/invoke/MethodType$ConcurrentWeakInternSet;
+39 -1: (Lsun/misc/Perf;Ljava/nio/ByteBuffer;)V
+16 -1: mergePermissions
+11 -1: totalMemory
+53 -1: java/lang/invoke/DirectMethodHandle$EnsureInitialized
+139 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/util/concurrent/ConcurrentMap<TK;TV;>;Ljava/io/Serializable;
+29 -1: java/util/HashMap$KeyIterator
+20 -1: STACK_TRACE_SENTINEL
+5 -1: order
+18 -1: java/lang/Runnable
+8 -1: GetField
+13 -1: Empty command
+7 -1: CONTROL
+9 -1: blockedOn
+12 -1: testAllFlags
+11 -1: getInflater
+16 -1: threadTerminated
+44 -1: (Ljava/lang/ThreadGroup;Ljava/lang/String;)V
+20 -1: java.runtime.version
+8 -1: peekLast
+23 -1: java/util/ArrayList$Itr
+21 -1: (Ljava/util/Locale;)V
+13 -1: isOptimizable
+8 -1: FairSync
+7 -1: CHINESE
+15 -1: initHelpMessage
+30 -1: ()Ljava/util/HashMap$TreeNode;
+29 -1: Ljava/lang/SecurityException;
+7 -1: charset
+35 -1: sun/security/util/SecurityConstants
+19 -1: sun.nio.cs.bugLevel
+8 2: Foo.java
+49 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;)V
+12 -1: EntrySetView
+37 -1: (Lsun/misc/JavaNetHttpCookieAccess;)V
+35 -1: Ljava/util/Hashtable$Entry<TK;TV;>;
+20 -1: NF_constructorMethod
+8 -1: getMonth
+38 -1: (Ljava/util/Iterator;Ljava/util/Map;)V
+14 -1: getIntVolatile
+6 -1: [name=
+8 -1: oop_size
+20 -1: Can't load library: 
+30 -1: ()Ljava/util/Spliterator<TV;>;
+33 -1: Lsun/reflect/ConstructorAccessor;
+61 -1: Ljava/lang/Number;Ljava/lang/Comparable<Ljava/lang/Integer;>;
+15 -1: printVmSettings
+33 -1: stack         include stack trace
+45 -1: ([Ljava/lang/Object;I)Ljava/util/Spliterator;
+37 -1: sun/reflect/generics/scope/ClassScope
+36 -1: java/io/UnsupportedEncodingException
+24 -1: (J)Ljava/nio/LongBuffer;
+11 -1: addressSize
+15 -1: ByteBuffer.java
+62 -1: (Ljava/lang/String;)Lsun/reflect/generics/tree/ClassSignature;
+9 -1: (TT;TT;)I
+25 -1: java/io/DefaultFileSystem
+15 -1: BaseLocale.java
+14 -1: BitSetIterator
+17 -1: AbstractList.java
+57 -1: Ljava/lang/ref/WeakReference<Ljava/lang/ThreadLocal<*>;>;
+178 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+9 -1: arguments
+26 -1: java/util/Locale$LocaleKey
+9 -1: setLength
+29 -1: sun/nio/cs/ISO_8859_1$Decoder
+9 -1: zipfs.jar
+24 -1: Ljava/util/zip/ZipCoder;
+14 -1: , new state = 
+93 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;IIIJLjava/util/concurrent/ConcurrentHashMap;)V
+39 -1: java/security/PrivilegedExceptionAction
+9 -1: dnsns.jar
+20 -1: iteratorBinarySearch
+14 -1: initializePath
+22 -1: DefaultFileSystem.java
+17 -1: Ljava/util/Deque;
+8 -1: DEFLATED
+11 -1: Can't load 
+9 -1: ArrayList
+21 -1: negativeZeroFloatBits
+41 -1: (Ljava/lang/String;ILjava/util/Locale;)[C
+14 -1: ANSI_X3.4-1968
+39 -1: sun/reflect/annotation/AnnotationType$1
+3 -1: mod
+62 -1: Ljava/nio/Buffer;Ljava/lang/Comparable<Ljava/nio/ByteBuffer;>;
+29 -1: interpretWithArgumentsTracing
+6 -1: getDay
+47 -1: sun/reflect/generics/repository/ClassRepository
+19 -1: refKindDoesDispatch
+20 -1: getAnnotationsByType
+14 -1: needsExpansion
+18 -1: lastIndexOfSubList
+26 -1: JavaUtilZipFileAccess.java
+59 -1: (Ljava/lang/CharSequence;)Ljava/lang/AbstractStringBuilder;
+12 -1: ptypesOffset
+8 -1: hashcode
+18 -1: ([Ljava/net/URL;)V
+8 -1: iso-ir-6
+7 -1: jzentry
+52 -1:               only dump output if specified codebase
+31 -1: lambda$comparingLong$6043328a$1
+5 -1: MARCH
+14 -1: ANSI_X3.4-1986
+14 -1: isMalformed3_2
+7 -1: IS_TYPE
+68 -1: Ljava/lang/Object;Ljava/lang/Comparable<Ljava/nio/charset/Charset;>;
+30 -1: protocol doesn't support input
+17 -1: getExtClassLoader
+14 -1: setProxiedHost
+73 -1: ()Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;>;
+16 -1: traceInterpreter
+17 -1: (Ljava/net/URL;)I
+5 -1: expm1
+18 -1: createInheritedMap
+66 -1: java/util/concurrent/ConcurrentHashMap$ForEachTransformedEntryTask
+17 -1: getTimeOfDayValue
+15 -1: zeroLengthArray
+20 -1: invalid permission: 
+6 -1: REPORT
+15 -1: isNumericString
+78 -1: (Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;
+6 -1: (TV;)Z
+25 -1: Lsun/misc/JavaLangAccess;
+29 -1: (I)Ljava/lang/reflect/Method;
+17 -1: (Ljava/net/URL;)V
+34 -1: ()Ljava/lang/Class$ReflectionData;
+50 -1: java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE
+10 -1: copyWith: 
+17 -1: (Ljava/net/URL;)Z
+32 -1: ()Ljava/util/stream/Stream<TE;>;
+22 -1: quickCheckMemberAccess
+29 -1: ()Lsun/net/www/MessageHeader;
+19 -1: getAssignedCombiner
+8 -1: ([JIIJ)I
+17 -1: formatUnsignedInt
+68 -1: <V:Ljava/lang/Object;>Ljava/util/AbstractMap<Ljava/lang/String;TV;>;
+34 -1: java/nio/ByteBufferAsDoubleBufferB
+32 -1: ([I)Ljava/util/stream/IntStream;
+9 -1: init_lock
+18 -1: must be resolved: 
+42 -1: ()Ljava/nio/channels/spi/SelectorProvider;
+8 -1: ([JIIJ)V
+33 -1: IncompatibleClassChangeError.java
+34 -1: java/nio/ByteBufferAsDoubleBufferL
+31 -1: ()Ljava/util/function/Function;
+43 -1: Ljava/lang/Enum<Ljava/io/File$PathStatus;>;
+17 -1: availableCharsets
+49 -1: java/util/ArraysParallelSortHelpers$FJChar$Sorter
+22 -1: permission=<classname>
+22 -1: getAnnotatedSuperclass
+20 -1: isObjectPublicMethod
+15 -1: Attempt to get 
+10 -1: createLong
+14 -1: HASH_INCREMENT
+32 -1: sun/management/ManagementFactory
+13 -1: separatorChar
+15 -1: bad field type 
+8 -1: november
+27 -1: (F)Ljava/lang/StringBuffer;
+3 -1: EAT
+3 -1: mst
+54 -1: (Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
+18 -1: Ljava/lang/Object;
+7 -1: ;:&=+$,
+12 -1: Handler.java
+7 -1: isDirty
+127 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedAction<TT;>;Ljava/security/AccessControlContext;[Ljava/security/Permission;)TT;
+14 -1: asTypeUncached
+5 -1: split
+200 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;Ljava/lang/reflect/Type;Lsun/reflect/annotation/TypeAnnotation$TypeAnnotationTarget;)Ljava/lang/reflect/AnnotatedType;
+47 -1: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+22 -1: sun/invoke/empty/Empty
+66 -1: (Ljava/util/Map;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/Map;
+18 -1: jvm_update_version
+32 -1: (Ljava/util/Map;)Ljava/util/Map;
+14 -1: cacheLoadLimit
+8 -1: javaHome
+52 -1: (Ljava/lang/reflect/Field;)Ljava/lang/reflect/Field;
+20 -1: [[Ljava/lang/Object;
+19 -1: isJavaLetterOrDigit
+11 -1: loadLibrary
+32 -1: java/io/StreamCorruptedException
+14 -1: setAccessible0
+27 -1: sun/nio/cs/UTF_16LE$Encoder
+60 -1: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
+8 -1: segments
+10 -1: UTF_8.java
+3 -1: ECT
+5 -1: cp813
+5 -1: cp819
+61 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/util/Comparator;)I
+5 -1: Cache
+4 -1: sinh
+32 -1: java/util/function/ToIntFunction
+10 -1: setFactory
+24 -1: Illegal mappings count: 
+16 -1: fileToEncodedURL
+38 -1: Ljava/lang/annotation/RetentionPolicy;
+27 -1: Ljava/net/SocketPermission;
+46 -1: (Ljava/lang/CharSequence;I)[Ljava/lang/String;
+11 -1: cardinality
+13 -1: getMonthValue
+64 -1: (Ljava/lang/invoke/MethodType;II)Ljava/lang/invoke/MethodHandle;
+6 -1: ENDTOT
+12 -1: getBytesUTF8
+9 -1: cacheLoad
+13 -1: packageAccess
+14 -1: sharedToString
+5 -1: merge
+29 -1: parameter type cannot be void
+27 -1: makePreparedFieldLambdaForm
+40 -1: Couldn't find 3-letter country code for 
+166 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/net/URL;Ljava/lang/ClassLoader;)V
+19 -1: (Ljava/util/Map;Z)V
+13 -1: setExecutable
+17 -1: objectFieldOffset
+57 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+128 -1: (Ljava/lang/Class<*>;ZLjava/lang/String;Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Ljava/util/List<Ljava/lang/invoke/MemberName;>;
+61 -1: java/util/concurrent/ConcurrentHashMap$MapReduceKeysToIntTask
+6 -1: asType
+25 -1: java/io/ObjectStreamField
+15 -1: jvmMajorVersion
+124 -1: (Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;[Ljava/security/Permission;)Ljava/lang/Object;
+23 -1: (Ljava/lang/Class<*>;)C
+6 -1: andNot
+15 -1: getResponseCode
+59 -1: (Ljava/lang/StringBuffer;)Ljava/lang/AbstractStringBuilder;
+23 -1: (Ljava/lang/Class<*>;)I
+7 -1: seeAllp
+44 -1: (Ljava/lang/ClassLoader;[Ljava/lang/Class;)V
+13 -1: loadFromCache
+35 -1: sun/nio/cs/HistoricallyNamedCharset
+38 -1: (Ljava/lang/Class;[Ljava/lang/Class;)V
+19 -1: INVOKER_METHOD_TYPE
+16 -1: putShortVolatile
+12 -1: Asia/Karachi
+8 -1: cyrillic
+12 -1: getISO2Table
+23 -1: (Ljava/lang/Class<*>;)V
+3 -1: 1.4
+15 -1: LongBuffer.java
+6 -1: (IFZ)V
+23 -1: (Ljava/lang/Class<*>;)Z
+10 -1: initOutput
+9 -1: CELLSBUSY
+39 -1: java/security/PrivilegedActionException
+31 -1: sun/util/calendar/CalendarUtils
+202 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;[Ljava/lang/reflect/Type;Lsun/reflect/annotation/TypeAnnotation$TypeAnnotationTarget;)[Ljava/lang/reflect/AnnotatedType;
+20 -1: Ljava/lang/Class<*>;
+5 -1: cp850
+25 -1: (JI)Ljava/nio/ByteBuffer;
+5 -1: cp852
+24 -1: Invalid parameter name "
+39 -1: ([CII)Ljava/lang/AbstractStringBuilder;
+5 -1: cp855
+11 -1: Deallocator
+5 -1: cp857
+5 -1: cp858
+7 -1: ([SI)[S
+37 -1: ([C)Ljava/lang/AbstractStringBuilder;
+27 -1: java/lang/SecurityException
+82 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;)V
+38 -1: (Ljava/lang/String;)Ljava/lang/String;
+7 -1: connect
+7 -1: isEmpty
+11 -1: replaceNode
+19 -1: SuppliedThreadLocal
+12 -1: asFixedArity
+12 -1: fromIndex = 
+19 -1: createMemoryManager
+9 -1: List.java
+8 -1: FEBRUARY
+21 -1: UnicodeLittleUnmarked
+6 -1: a null
+30 -1: ()Ljava/util/Spliterator<TT;>;
+5 -1: cp862
+17 -1: ZoneInfoFile.java
+5 -1: cp866
+8 -1: BulkTask
+53 -1: java/util/concurrent/locks/AbstractQueuedSynchronizer
+20 -1: FileInputStream.java
+12 -1: java.vm.info
+10 -1: newDecoder
+5 -1: (JB)V
+8 -1: filePath
+17 -1: spreadArrayChecks
+44 -1: ([Ljava/lang/Object;Ljava/util/Comparator;)V
+33 -1: java/util/Collections$AsLIFOQueue
+32 -1: Ljava/util/LinkedList$Node<TE;>;
+5 -1: cp874
+78 -1: (Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
+39 -1: (JLjava/util/function/Consumer<-TK;>;)V
+15 -1: appendCodePoint
+20 -1: primitiveReturnCount
+54 -1:               only dump output if specified permission
+20 -1: getGenericInterfaces
+41 -1: ([Ljava/lang/reflect/AccessibleObject;Z)V
+17 -1: nUnstartedThreads
+33 -1: (Ljava/lang/invoke/MemberName;Z)V
+24 -1: ARRAY_OBJECT_INDEX_SCALE
+40 -1: (Ljava/lang/String;ILjava/util/Locale;)I
+17 -1: java/io/Flushable
+22 -1: newConstructorAccessor
+26 -1: sun/misc/JavaUtilJarAccess
+6 -1: booted
+10 -1: setDoInput
+36 -1: (Ljava/lang/Class;)[Ljava/lang/Enum;
+19 -1: java/lang/Character
+52 -1: ([Ljava/net/URL;Ljava/net/URLStreamHandlerFactory;)V
+24 -1: (Ljava/nio/LongBuffer;)I
+16 -1: start > length()
+28 -1: (I)Ljava/lang/CharacterData;
+5 -1: val$c
+61 -1: (Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
+13 -1: resolveOrNull
+9 -1: L_ESCAPED
+27 -1: MapReduceValuesToDoubleTask
+15 -1: getPreparedForm
+33 -1: (I)[Ljava/util/WeakHashMap$Entry;
+54 -1: ()Ljava/util/stream/Stream<+Ljava/util/zip/ZipEntry;>;
+16 -1: bad method type 
+5 -1: val$s
+17 -1: Null charset name
+36 -1: java/lang/invoke/LambdaForm$Compiled
+24 -1: (Ljava/util/SortedMap;)V
+19 -1: java/time/LocalTime
+29 -1: not invocable, no method type
+21 -1: recalculateWordsInUse
+6 -1: val$id
+39 -1: sun/security/util/ManifestEntryVerifier
+60 -1: ([Ljava/lang/Class<*>;I)Ljava/lang/reflect/Constructor<TT;>;
+45 -1: java/util/ArrayPrefixHelpers$LongCumulateTask
+5 -1: OfInt
+11 -1: environment
+60 -1: ([Ljava/lang/Class<*>;[B)[[Ljava/lang/annotation/Annotation;
+7 -1: (JJJZ)V
+10 -1: BufferPool
+6 -1: isUTF8
+12 -1: threadLocals
+35 -1: (Ljava/lang/String;)[Ljava/net/URL;
+21 -1: Ljava/nio/LongBuffer;
+15 -1: copyConstructor
+25 -1: setCallSiteTargetVolatile
+15 -1: getNumericValue
+26 -1: Ljava/security/CodeSource;
+18 -1: Null output stream
+14 -1: cloneWithIndex
+23 -1: LOCAL_LISTEN_PERMISSION
+6 -1: (TT;)I
+46 -1: (Ljava/security/PublicKey;Ljava/lang/String;)V
+6 -1: setCrc
+26 -1: java/io/FilterOutputStream
+10 -1: access$000
+10 -1: access$001
+10 -1: access$002
+6 -1: (TT;)V
+78 -1: <T:Ljava/lang/Object;U:Ljava/lang/Object;>([TU;IILjava/lang/Class<+[TT;>;)[TT;
+41 -1: java/util/concurrent/atomic/AtomicInteger
+8 -1: renameTo
+40 -1: (Ljava/lang/Class<*>;)Ljava/lang/Object;
+17 -1: getRawAnnotations
+29 -1: java/lang/VirtualMachineError
+37 -1: java/lang/management/MemoryPoolMXBean
+25 -1: (II)Ljava/util/List<TE;>;
+6 -1: utf_16
+23 -1: (Ljava/lang/String;[B)V
+19 -1: MIN_ARRAY_SORT_GRAN
+25 -1: array length is not legal
+45 -1: java/util/concurrent/locks/ReentrantLock$Sync
+36 -1: Ljava/security/AccessControlContext;
+48 -1: sun/reflect/generics/repository/MethodRepository
+24 -1: MethodHandleStatics.java
+24 -1: addThreadDumpForMonitors
+64 -1: <T:Ljava/lang/Object;>(Ljava/util/Set<TT;>;)Ljava/util/Set<TT;>;
+58 -1: (Ljava/lang/String;[Ljava/lang/Object;Ljava/lang/Object;)Z
+37 -1: (III)Lsun/util/calendar/CalendarDate;
+9 -1: createURI
+15 -1: unreserveMemory
+52 -1: (Lsun/reflect/MethodInfo;)Ljava/lang/reflect/Method;
+66 -1: (Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+51 -1: (Ljava/lang/reflect/Constructor;)Ljava/lang/String;
+23 -1: inheritableThreadLocals
+63 -1: ()Ljava/util/Map<Ljava/lang/String;Ljava/lang/reflect/Method;>;
+16 -1: setContentLength
+16 -1: LOWERCASE_LETTER
+4 -1: size
+25 -1: java.launcher.opt.hotspot
+19 -1: buildAnnotatedTypes
+26 -1: JAVAFX_LAUNCHER_CLASS_NAME
+11 -1: getAliasMap
+19 -1: CheckedNavigableSet
+15 -1: getAbsolutePath
+11 -1: doubleValue
+6 -1: utf_32
+22 -1: IMPLEMENTATION_VERSION
+3 -1: ne1
+11 -1: contentType
+8 -1: canWrite
+11 -1: Object.java
+14 -1: America/Denver
+8 -1: fileName
+13 -1: allPermDomain
+27 -1: ()Ljava/util/Iterator<TE;>;
+31 -1: (Lsun/reflect/MethodAccessor;)V
+11 -1: asTypeCache
+13 -1: lineSeparator
+9 -1: JarLoader
+15 -1: replacementNode
+18 -1: getContentEncoding
+12 -1: invoke_LLL_L
+22 -1: ()Ljava/util/TimeZone;
+17 -1: Reference Handler
+33 -1: java/lang/invoke/MethodHandleImpl
+47 -1: ()Ljava/util/concurrent/ConcurrentHashMap$Node;
+12 -1: invoke_LLL_V
+8 -1: form << 
+23 -1: (Ljava/lang/Object;JJ)J
+15 -1: isHighSurrogate
+31 -1: (Ljava/util/Collection<+TV;>;)Z
+36 -1: ([Ljava/util/HashMap$Node<TK;TV;>;)V
+23 -1: (Ljava/lang/Object;JJ)V
+12 -1: utf_32be_bom
+40 -1: sun/util/calendar/LocalGregorianCalendar
+27 -1: [Ljava/security/CodeSigner;
+15 -1: afterNodeAccess
+13 -1: nextThreadNum
+18 -1: INTERNED_ARGUMENTS
+11 -1: getMillisOf
+18 -1: offsetByCodePoints
+11 -1: writeObject
+48 -1: (Ljava/util/Locale$Category;Ljava/util/Locale;)V
+3 -1: nfe
+41 -1: (Ljava/util/Properties;Ljava/io/Reader;)V
+50 -1: (Ljava/util/concurrent/CountedCompleter;[C[CIIII)V
+15 -1: implFlushBuffer
+33 -1: (I)[Ljava/lang/invoke/MemberName;
+12 -1: Unicode.java
+17 -1: DMH.invokeVirtual
+5 -1: setup
+51 -1: (Ljava/util/Collection;[Ljava/lang/reflect/Field;)V
+3 -1: EST
+7 -1: TREEBIN
+7 -1: getFile
+10 -1: isLeapYear
+18 -1: LinkedHashIterator
+14 -1: DISPLAY_SCRIPT
+25 -1: privateGetDeclaredMethods
+68 -1: (Ljava/util/function/Function;Ljava/lang/Object;Ljava/lang/Object;)I
+22 -1: ()Ljava/util/Iterator;
+21 -1: sun/management/Sensor
+15 -1: getAvailableIDs
+51 -1: Lsun/util/PreHashedMap<Ljava/nio/charset/Charset;>;
+8 -1: elot_928
+6 -1: LATIN0
+45 -1: ([Ljava/lang/Object;II[Ljava/lang/Object;II)V
+10 -1: [Unlocked]
+15 -1: internArguments
+6 -1: LATIN9
+33 -1: (II)Ljava/lang/invoke/MethodType;
+12 -1: Version.java
+17 -1: setConnectTimeout
+75 -1: (Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
+13 -1: highSurrogate
+12 -1: Africa/Cairo
+21 -1: synchronizedSortedMap
+21 -1:  in java.library.path
+45 -1: sun/reflect/generics/tree/FormalTypeParameter
+24 -1: UncaughtExceptionHandler
+14 -1: previousOrSame
+24 -1: java/security/Permission
+9 -1: x-ISCII91
+5 -1: L_HEX
+35 -1: java/lang/invoke/DirectMethodHandle
+35 -1: java/util/ArrayDeque$DeqSpliterator
+14 -1: java/util/List
+11 -1: toLowerCase
+24 -1: java/nio/charset/Charset
+10 -1: MIN_NORMAL
+110 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+13 -1: regionMatches
+17 -1: newMethodAccessor
+26 -1: (Ljava/net/InetAddress;B)V
+68 -1: (Ljava/util/zip/ZipFile;Ljava/lang/String;J)Ljava/util/zip/ZipEntry;
+22 -1: ()Ljava/io/FileSystem;
+19 -1: primitiveSimpleName
+5 -1: MOVED
+9 -1: STATE_RED
+13 -1: linkToSpecial
+19 -1: AnnotationType.java
+20 -1: (II)Ljava/util/List;
+252 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceMappingsToDoubleTask;Ljava/util/function/ToDoubleBiFunction;DLjava/util/function/DoubleBinaryOperator;)V
+12 -1: callSiteForm
+22 -1: isSiblingBindingBefore
+62 -1: <T:Ljava/lang/Object;>([TT;IITT;Ljava/util/Comparator<-TT;>;)I
+15 -1: buildEmptyNames
+11 -1: Thread.java
+30 -1: Ljava/lang/ref/Reference<TT;>;
+35 -1: sun/reflect/MethodAccessorGenerator
+152 -1: (Ljava/util/function/Function;Ljava/util/function/Function;Ljava/util/function/BinaryOperator;Ljava/util/function/Supplier;)Ljava/util/stream/Collector;
+5 -1: total
+242 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceValuesToLongTask;Ljava/util/function/ToLongFunction;JLjava/util/function/LongBinaryOperator;)V
+27 -1: javax/security/auth/Subject
+43 -1: JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
+17 -1: getSignerCertPath
+15 -1: registerNatives
+21 -1: sun/reflect/FieldInfo
+54 -1: (Ljava/nio/charset/Charset;Lsun/nio/cs/ISO_8859_1$1;)V
+17 -1: unwrapWithNoPrims
+17 -1: instanceof Long: 
+20 -1: hasRealParameterData
+23 -1: ()Ljava/time/LocalTime;
+14 -1: getAnnotations
+8 -1: optimize
+7 -1: setChar
+11 -1: OFFSET_MASK
+4 -1: TYPE
+177 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/function/BiFunction;Ljava/util/concurrent/atomic/AtomicReference;)V
+18 -1: removeShutdownHook
+27 -1: ()Ljava/security/Principal;
+29 -1: JAVAFX_APPLICATION_CLASS_NAME
+6 -1: digits
+37 -1: [Ljava/lang/reflect/Constructor<TT;>;
+45 -1: ()Ljava/lang/Thread$UncaughtExceptionHandler;
+7 -1: tryLock
+19 -1: java/net/Proxy$Type
+21 -1: setJavaSecurityAccess
+13 -1: tieBreakOrder
+3 -1: no 
+16 -1: Australia/Sydney
+13 -1: DAY_IN_MILLIS
+19 -1: ()Ljava/nio/Buffer;
+12 -1: Integer.java
+14 -1: isBmpCodePoint
+6 -1: daemon
+23 -1: Lsun/misc/JavaIOAccess;
+106 -1: <U:Ljava/lang/Object;>(JLjava/util/function/BiFunction<-TK;-TV;+TU;>;Ljava/util/function/Consumer<-TU;>;)V
+10 -1: getFloatAt
+15 -1: content/unknown
+52 -1: ()Ljava/util/Enumeration<+Ljava/util/zip/ZipEntry;>;
+123 -1: <T:Ljava/lang/Object;>(Ljava/lang/Class<*>;Lsun/reflect/annotation/AnnotationType;Lsun/reflect/annotation/AnnotationType;)Z
+4 -1: nsme
+12 -1: prefixLength
+9 -1: flagsMods
+95 -1: (BLjava/lang/invoke/MemberName;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MemberName;
+62 -1: (Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/LambdaForm;
+16 -1: Illegal mode: 0x
+24 -1: java/io/FileOutputStream
+41 -1: [Pp][Ee][Rr][Mm][Ii][Ss][Ss][Ii][Oo][Nn]=
+24 -1: java/security/CodeSource
+16 -1: DUMP_CLASS_FILES
+25 -1: ([C)Ljava/nio/CharBuffer;
+12 -1: bindArgument
+50 -1: Ljava/lang/ref/FinalReference<Ljava/lang/Object;>;
+21 -1: unmodifiableSortedMap
+10 -1: jarHandler
+73 -1: (Ljava/lang/Class;[Ljava/lang/reflect/Method;)[Ljava/lang/reflect/Method;
+67 -1: ()Ljava/util/Map<Ljava/lang/Thread;[Ljava/lang/StackTraceElement;>;
+15 -1: threadSeqNumber
+18 -1: AutoCloseable.java
+9 -1: holdsLock
+25 -1: (Ljava/lang/Object;JJJJ)V
+7 -1: (IJII)I
+15 -1: copyToLongArray
+58 -1: Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Package;>;
+84 -1: (Ljava/lang/invoke/MethodHandle;I[Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+32 -1: getExecutableTypeAnnotationBytes
+17 -1: streamHandlerLock
+35 -1: java/lang/IndexOutOfBoundsException
+15 -1: moveRootToFront
+28 -1: ()Ljava/nio/file/FileSystem;
+14 -1: content-length
+61 -1: (Ljava/lang/invoke/CallSite;Ljava/lang/invoke/MethodHandle;)V
+7 -1: csASCII
+18 -1: staticIsConsistent
+21 -1: sharedToGenericString
+8 -1: linkLast
+21 -1: isUnicodeExtensionKey
+7 -1: readInt
+7 -1: compile
+32 -1: ()Ljava/lang/reflect/Executable;
+4 -1: Big5
+20 -1: Ljava/util/Set<TE;>;
+18 -1: ExpiringCache.java
+44 -1: (Ljava/lang/String;[BII)Ljava/lang/Class<*>;
+18 -1: LinkedHashMap.java
+32 -1: Ljava/lang/UnsatisfiedLinkError;
+13 -1: parameterType
+28 -1: (ID)Ljava/lang/StringBuffer;
+15 -1: synchronizedSet
+9 -1: implClose
+6 -1: member
+14 -1: MH_INVOKE_MODS
+21 -1: forOutputStreamWriter
+37 -1: Lsun/misc/JavaIOFileDescriptorAccess;
+28 -1: java/lang/ProcessEnvironment
+17 -1: setNormalizedYear
+14 -1: isMalformed4_2
+14 -1: isMalformed4_3
+38 -1: (Ljava/lang/Object;)Ljava/lang/String;
+16 -1: getJavaAWTAccess
+12 -1: isPrivileged
+30 -1: java/util/Collections$EmptyMap
+17 -1: LinkedKeyIterator
+7 -1: vmcount
+27 -1: java/lang/ref/WeakReference
+5 -1: march
+13 -1: addOldMapping
+58 -1: (Ljava/lang/Object;Ljava/lang/Runnable;)Lsun/misc/Cleaner;
+56 -1: (ILjava/lang/String;)[Ljava/lang/invoke/LambdaForm$Name;
+65 -1: java/util/concurrent/ConcurrentHashMap$MapReduceEntriesToLongTask
+55 -1: (Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
+17 -1: getEnclosingClass
+35 -1: (I)Lsun/util/calendar/BaseCalendar;
+13 -1: binarySearch0
+25 -1: ([J)Ljava/nio/LongBuffer;
+19 -1: java/util/Map$Entry
+22 -1: java/util/HashMap$Node
+26 -1: sun/reflect/MethodAccessor
+8 -1: LASTYEAR
+7 -1: disable
+36 -1: sun/launcher/LauncherHelper$FXHelper
+6 -1: toPath
+10 -1: shortValue
+6 -1: remove
+59 -1: ([Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Process;
+55 -1: java/util/concurrent/ConcurrentHashMap$ValueSpliterator
+64 -1: (Ljava/util/Collection;Ljava/lang/Object;)Ljava/util/Collection;
+15 -1: asPrimitiveType
+16 -1: PrintStream.java
+10 -1: image/jpeg
+22 -1: specificToStringHeader
+7 -1: class "
+38 -1: java/util/Collections$CheckedSortedMap
+19 -1: SUPPRESSED_SENTINEL
+16 -1: getEnumConstants
+54 -1: (ILjava/lang/CharSequence;II)Ljava/lang/StringBuilder;
+36 -1: Ljava/lang/Class<Ljava/lang/Short;>;
+13 -1: toThreadState
+38 -1: (Ljava/lang/Class;)Ljava/lang/Package;
+24 -1: (C)Ljava/lang/Character;
+19 -1: UNTREEIFY_THRESHOLD
+4 -1: NCPU
+23 -1: ()Ljava/lang/Exception;
+42 -1: (ITK;TV;Ljava/util/HashMap$Node<TK;TV;>;)V
+15 -1: nothingToVerify
+15 -1: setInitialValue
+15 -1: getTimeInMillis
+12 -1: getDoubleAt0
+18 -1: parameterTypeCache
+86 -1: (Ljava/nio/file/WatchService;[Ljava/nio/file/WatchEvent$Kind;)Ljava/nio/file/WatchKey;
+49 -1: java/util/concurrent/ConcurrentHashMap$ValuesView
+13 -1: <all actions>
+7 -1: exitVM.
+34 -1: Ljava/lang/ClassNotFoundException;
+68 -1: (Ljava/util/Map;Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
+28 -1: getCalendarDateFromFixedDate
+28 -1: UnsafeFieldAccessorImpl.java
+27 -1: java/lang/RuntimePermission
+74 -1: Ljava/lang/Object;Ljava/lang/Comparable<Lsun/util/locale/BaseLocale$Key;>;
+62 -1: ()Ljava/util/Iterator<Ljava/nio/charset/spi/CharsetProvider;>;
+13 -1: LanguageRange
+239 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceValuesToIntTask;Ljava/util/function/ToIntFunction;ILjava/util/function/IntBinaryOperator;)V
+37 -1: DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+62 -1: (Ljava/lang/invoke/MethodType;II)Ljava/lang/invoke/MethodType;
+16 -1: DMH.invokeStatic
+11 -1: (TK;TV;)TV;
+7 -1: ([FI)[F
+14 -1: newPerfCounter
+35 -1: ([JI)Ljava/util/Spliterator$OfLong;
+30 -1: java/util/AbstractList$ListItr
+5 -1: cp912
+5 -1: cp914
+45 -1: (Ljava/io/BufferedWriter;Ljava/lang/String;)V
+6 -1: LOCNAM
+8 -1: launcher
+5 -1: cp915
+14 -1: standardString
+26 -1: ()Ljava/lang/Thread$State;
+10 -1: L_ALPHANUM
+8 -1: (C[CII)I
+9 -1: SEPTEMBER
+20 -1: java/text/DateFormat
+38 -1: Ljava/lang/CloneNotSupportedException;
+5 -1: cp920
+23 -1: getConstructorSignature
+16 -1: ReferenceHandler
+19 -1: America/Puerto_Rico
+5 -1: cp923
+10 -1: typeString
+30 -1: Self-suppression not permitted
+25 -1: (Ljava/io/OutputStream;)V
+9 -1: implReset
+12 -1: fullAddCount
+34 -1: java/lang/invoke/LambdaForm$Hidden
+25 -1: ()Lsun/misc/JavaIOAccess;
+9 -1: Math.java
+9 -1: getAndSet
+7 -1: failure
+14 -1: LINE_SEPARATOR
+6 -1: parent
+30 -1: java/lang/BootstrapMethodError
+8 -1: indexMap
+9 -1: ALL_KINDS
+23 -1: desiredAssertionStatus0
+39 -1: (ILjava/lang/Object;)Ljava/lang/Object;
+22 -1: RuntimePermission.java
+21 -1: getContextClassLoader
+14 -1: VARARGS_INVOKE
+8 -1: zoneinfo
+130 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MemberName;ILjava/lang/invoke/DirectMethodHandle$1;)V
+18 -1: java/lang/Readable
+11 -1: containsAll
+11 -1: newPosition
+57 -1: sun/reflect/InstantiationExceptionConstructorAccessorImpl
+13 -1: REVERSE_ORDER
+29 -1: Required array size too large
+6 -1: sunday
+44 -1: <T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;
+10 -1: toIntExact
+33 -1: ([BIILjava/nio/charset/Charset;)V
+14 -1: indexOfSubList
+15 -1: tryAcquireNanos
+31 -1: java/lang/InvalidClassException
+22 -1: SecureClassLoader.java
+12 -1: proxiedHosts
+7 -1: ([CII)I
+11 -1: toHexString
+30 -1: sun/util/calendar/ZoneInfoFile
+31 -1: Ljava/util/jar/Attributes$Name;
+10 -1: L_USERINFO
+25 -1: (IB)Ljava/nio/ByteBuffer;
+11 -1: parseDouble
+7 -1: ([CII)V
+13 -1: Asia/Shanghai
+5 -1: [...]
+57 -1: ([Ljava/lang/Class;[B)[[Ljava/lang/annotation/Annotation;
+19 -1: java/nio/LongBuffer
+15 -1: getCertificates
+9 -1: comparing
+83 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Class<*>;IILjava/lang/String;[B)V
+43 -1: Ljava/util/concurrent/atomic/AtomicInteger;
+23 -1: toFieldDescriptorString
+20 -1: Lsun/misc/MetaIndex;
+37 -1: java/util/Collections$UnmodifiableSet
+5 -1: (JC)V
+37 -1: nanosecond timeout value out of range
+26 -1: AbstractStringBuilder.java
+43 -1: java/lang/invoke/DirectMethodHandle$Special
+49 -1: ([Ljava/nio/file/LinkOption;)Ljava/nio/file/Path;
+15 -1: currentPosition
+14 -1: java/net/Proxy
+13 -1: asConstructor
+8 -1: userInfo
+14 -1: parseClassPath
+15 -1: legacyMergeSort
+34 -1: java/security/UnresolvedPermission
+97 -1: Lsun/util/locale/LocaleObjectCache<Lsun/util/locale/BaseLocale$Key;Lsun/util/locale/BaseLocale;>;
+9 -1: freeEntry
+19 -1: delimiterCodePoints
+34 -1: Should be non-empty if initialized
+23 -1: (I)Ljava/lang/Class<*>;
+11 -1: Reader.java
+26 -1: checkClassLoaderPermission
+27 -1: java/nio/DirectShortBufferS
+95 -1: Ljava/lang/Object;Ljava/security/PrivilegedExceptionAction<Lsun/misc/Launcher$ExtClassLoader;>;
+27 -1: java/nio/DirectShortBufferU
+20 -1: ()[Ljava/lang/Class;
+56 -1: ()[Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+19 -1: sun/nio/cs/UTF_16BE
+24 -1: java/util/AbstractList$1
+10 -1: ([CIIIII)V
+60 -1: Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/Object;>;
+37 -1: (Ljava/lang/invoke/LambdaForm$Name;)S
+9 -1: putDouble
+52 -1: ([Ljava/security/CodeSource;)Ljava/util/Enumeration;
+37 -1: (Ljava/lang/invoke/LambdaForm$Name;)Z
+22 -1: ()[Ljava/lang/Package;
+41 -1: java/lang/CharSequence$1CodePointIterator
+13 -1: auditSubclass
+24 -1: Ljava/util/jar/JarEntry;
+20 -1: findMethodHandleType
+15 -1: MAX_BUFFER_SIZE
+19 -1: FilePermission.java
+18 -1: WrappedPrintStream
+36 -1: (D)Ljava/lang/AbstractStringBuilder;
+11 -1: unfinalized
+10 -1: getFileURL
+37 -1: (Ljava/io/FileFilter;)[Ljava/io/File;
+54 -1: (Ljava/nio/ByteBuffer;I)Ljava/nio/charset/CoderResult;
+7 -1: ([ZI)[Z
+64 -1: (Ljava/security/CodeSource;)Ljava/security/PermissionCollection;
+6 -1: PUBLIC
+83 -1: (Ljava/util/jar/JarFile;Ljava/net/URL;Ljava/lang/String;)Ljava/security/CodeSource;
+17 -1: lockInterruptibly
+67 -1: ([Ljava/util/Hashtable$Entry;Ljava/lang/Object;Ljava/lang/Object;)V
+42 -1: java/util/ArraysParallelSortHelpers$FJChar
+21 -1: defaultCharBufferSize
+14 -1: unalignedKnown
+23 -1: ()Ljava/net/Proxy$Type;
+4 -1: TZDB
+14 -1: CharacterCache
+13 -1: lengthOfMonth
+13 -1: hasExtensions
+23 -1: Prefix string too short
+15 -1: Executable.java
+10 -1: forEachKey
+6 -1: getEra
+13 -1: appendEncoded
+21 -1: java/util/AbstractMap
+10 -1: access$100
+10 -1: access$102
+30 -1: javafx.application.Application
+46 -1: (Ljava/lang/Thread$UncaughtExceptionHandler;)V
+43 -1: Ljava/lang/invoke/LambdaForm$NamedFunction;
+101 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;IILjava/lang/String;[B)Ljava/lang/reflect/Field;
+9 -1: WILD_CHAR
+21 -1: SynchronizedSortedSet
+28 -1: (Ljava/util/Collection<*>;)Z
+29 -1: (I[C)Ljava/lang/StringBuffer;
+65 -1: (Ljava/lang/String;[Ljava/lang/Class;Z)Ljava/lang/reflect/Method;
+7 -1: putByte
+6 -1: H_MARK
+49 -1: (Ljava/lang/invoke/MemberName;)Ljava/lang/Object;
+98 -1: ([Ljava/lang/ClassValue$Entry<*>;ILjava/lang/ClassValue$Entry<*>;Z)Ljava/lang/ClassValue$Entry<*>;
+23 -1: array is not of length 
+52 -1: <T:Ljava/lang/Object;>(Ljava/util/List<TT;>;TT;TT;)Z
+41 -1: Ljava/util/Collections$EmptyListIterator;
+8 -1:         
+11 -1: updateCheck
+29 -1: getBootClassPathEntryForClass
+27 -1: sun/nio/cs/US_ASCII$Encoder
+10 -1: bindCaller
+18 -1: Ljava/util/BitSet;
+10 -1: checkRange
+77 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Class<*>;Ljava/lang/Void;)V
+7 -1: Classes
+6 -1: store0
+23 -1: java/lang/Thread$Caches
+25 -1: Ljava/lang/CharacterData;
+7 -1: (JI[C)V
+49 -1: (Ljava/util/LinkedList;Ljava/util/LinkedList$1;)V
+16 -1: getGcInfoBuilder
+12 -1: counterCells
+14 -1: memoryLimitSet
+7 -1: , nojit
+9 -1: sharpsMap
+7 -1: october
+13 -1: isProxiedHost
+9 -1: rawOffset
+18 -1: toJavaFormatString
+19 -1: sun.boot.class.path
+60 -1: (ILjava/lang/CharSequence;)Ljava/lang/AbstractStringBuilder;
+11 -1: spliterator
+13 -1: contentLength
+18 -1: unixTimeToFileTime
+31 -1: Lsun/reflect/LangReflectAccess;
+16 -1:  while Java has 
+79 -1: (JLjava/util/function/ToIntBiFunction;ILjava/util/function/IntBinaryOperator;)I
+12 -1: timeEndOfDay
+17 -1: getCustomTimeZone
+25 -1: Ljava/lang/ref/Reference;
+20 -1: ()Ljava/util/Locale;
+64 -1: (Ljava/util/HashMap<TK;TV;>;[Ljava/util/HashMap$Node<TK;TV;>;Z)V
+13 -1: MAX_JVM_ARITY
+72 -1: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/invoke/MethodType;
+11 -1: AsLIFOQueue
+84 -1: <T:Ljava/lang/Object;>(Ljava/util/List<TT;>;Ljava/lang/Object;)Ljava/util/List<TT;>;
+12 -1: mappingCount
+29 -1: (Ljava/io/FileOutputStream;)V
+50 -1: <T:Ljava/lang/Object;>(Ljava/util/List<-TT;>;TT;)V
+23 -1: Category cannot be NULL
+10 -1: normalized
+5 -1: CLASS
+28 -1: (IZ)Ljava/lang/StringBuffer;
+18 -1: java/lang/System$1
+18 -1: java/lang/System$2
+9 -1: getResult
+44 -1: ()Ljava/util/Collection<Ljava/lang/Thread;>;
+8 -1: isNative
+59 -1: Ljava/lang/Number;Ljava/lang/Comparable<Ljava/lang/Short;>;
+24 -1: [Ljava/lang/ThreadGroup;
+24 -1: (B)Ljava/nio/ByteBuffer;
+4 -1: READ
+44 -1: (Ljava/io/FilePermission;)Ljava/lang/String;
+93 -1: <E:Ljava/lang/Object;>Ljava/util/Collections$SynchronizedCollection<TE;>;Ljava/util/Set<TE;>;
+12 -1: compileClass
+12 -1: isProxyClass
+20 -1: isSystemDomainLoader
+74 -1: <T:Ljava/lang/Object;>(Ljava/util/List<TT;>;Ljava/util/Comparator<-TT;>;)V
+7 -1: getMask
+72 -1: (Ljava/lang/ClassLoader;Ljava/lang/SecurityManager;Ljava/lang/String;I)V
+20 -1: removeLastOccurrence
+64 -1: (Ljava/lang/reflect/Field;)Ljava/lang/invoke/DirectMethodHandle;
+57 -1: ()Ljava/util/Map<Ljava/lang/String;Ljava/lang/Class<*>;>;
+11 -1: parkBlocker
+40 -1: (Lsun/misc/JarIndex;Ljava/lang/String;)V
+33 -1: [Ljava/security/ProtectionDomain;
+14 -1: setContentType
+14 -1: getEnumeration
+18 -1: ProtectionDomain  
+76 -1: (Lsun/util/calendar/BaseCalendar$Date;)Lsun/util/calendar/BaseCalendar$Date;
+16 -1: setRequestMethod
+52 -1: (Ljava/util/List;Ljava/lang/Object;)Ljava/util/List;
+32 -1: Lsun/util/calendar/BaseCalendar;
+52 -1: (Ljava/net/URL;Ljava/lang/String;)Ljava/lang/String;
+5 -1: .:@[]
+7 -1: addLast
+21 -1: AnnotatedElement.java
+10 -1: defaultVal
+16 -1: getCanonicalPath
+17 -1: protection_domain
+9 -1: strictfp 
+19 -1: sun/nio/cs/UTF_16LE
+9 -1: readBytes
+18 -1: removeStaleEntries
+46 -1: java/util/Collections$UnmodifiableNavigableSet
+5 -1: cpath
+14 -1: COPY_THRESHOLD
+8 -1: permsMap
+8 -1: japanese
+33 -1: java/nio/charset/StandardCharsets
+47 -1: Lsun/reflect/DelegatingConstructorAccessorImpl;
+19 -1: NF_checkGenericType
+40 -1: java/util/Collections$UnmodifiableList$1
+4 -1: TERM
+48 -1: The following can be used with stack and domain:
+27 -1: ([BII)Ljava/nio/ByteBuffer;
+40 -1: Ljava/util/Vector<Ljava/lang/Class<*>;>;
+5 -1: digit
+7 -1: isFinal
+39 -1: (Ljava/lang/String;Ljava/lang/String;)I
+26 -1: memberDeclaringClassOrNull
+10 -1: ([CI[BII)I
+38 -1: (Ljava/lang/Class;I)Ljava/lang/Object;
+15 -1: isValidProtocol
+17 -1: (this Collection)
+11 -1: getTreeNode
+16 -1: ThreadLocal.java
+23 -1: java/nio/HeapLongBuffer
+39 -1: (Ljava/lang/String;Ljava/lang/String;)V
+12 -1: getNextEntry
+39 -1: (Ljava/lang/String;Ljava/lang/String;)Z
+28 -1: (C)Lsun/invoke/util/Wrapper;
+9 -1: readFloat
+21 -1: overrideFieldAccessor
+16 -1: fillInStackTrace
+16 -1: getDeclaredField
+5 -1: deflt
+8 -1: nextChar
+10 -1: primCounts
+22 -1: getAnnotatedInterfaces
+26 -1: ()Ljava/util/zip/Inflater;
+73 -1: <U:Ljava/lang/Object;>(JLjava/util/function/BiFunction<-TK;-TV;+TU;>;)TU;
+16 -1: traceMethodCalls
+10 -1: sun.nio.cs
+7 -1: marshal
+9 -1: ftypeKind
+77 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/Class;)Ljava/lang/invoke/MemberName;
+11 -1: sun/misc/VM
+14 -1: GuardWithCatch
+40 -1: (Ljava/lang/Object;)Ljava/util/Iterator;
+13 -1: subtractExact
+42 -1: (Ljava/lang/Object;ILjava/lang/Object;II)V
+10 -1: isInfinite
+18 -1: sun.util.calendar.
+14 -1: java/lang/Math
+16 -1: java/lang/String
+10 -1: encodePath
+14 -1: compactAndTrim
+11 -1: getVariants
+4 -1: from
+47 -1: (Ljava/lang/ThreadLocal<*>;Ljava/lang/Object;)V
+35 -1: serializeAgentPropertiesToByteArray
+16 -1: computeIfPresent
+9 -1: EMPTY_MAP
+28 -1: java/lang/InstantiationError
+68 -1: (Ljava/util/Comparator;Ljava/util/Comparator;)Ljava/util/Comparator;
+14 -1: getDisplayName
+14 -1: limitedContext
+23 -1: usagetracker.properties
+52 -1: java/util/concurrent/locks/ReentrantLock$NonfairSync
+7 -1: public 
+17 -1: srcBegin > srcEnd
+48 -1: (ILjava/util/List;)Ljava/lang/invoke/MethodType;
+21 -1: java/lang/ThreadDeath
+9 -1: gregorian
+111 -1: (Ljava/util/HashMap;[Ljava/util/HashMap$Node;ILjava/lang/Object;Ljava/lang/Object;)Ljava/util/HashMap$TreeNode;
+52 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;III)V
+12 -1: generateFile
+20 -1: appendParameterTypes
+22 -1: sun/misc/FileURLMapper
+13 -1: defaultDomain
+25 -1: (I)Ljava/time/ZoneOffset;
+21 -1: getBooleanAttributes0
+39 -1: (Ljava/lang/String;)Lsun/misc/Resource;
+43 -1: Ljava/lang/Thread$UncaughtExceptionHandler;
+23 -1: getTypeAnnotationBytes0
+8 -1: ELOT_928
+32 -1: sun/nio/cs/FastCharsetProvider$1
+34 -1: Ljava/nio/BufferOverflowException;
+14 -1: AppClassLoader
+10 -1: protected 
+12 -1: isAnnotation
+16 -1: PerfCounter.java
+51 -1: Ljava/util/Map<Ljava/io/File;Lsun/misc/MetaIndex;>;
+160 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+11 -1: setLeapYear
+16 -1: parseContextSpec
+16 -1: setFieldAccessor
+8 -1: writeInt
+16 -1: java/lang/Number
+33 -1: java/util/AbstractMap$SimpleEntry
+9 -1: nextTable
+8 -1: getQuery
+14 -1: putOrderedLong
+93 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
+52 -1: (Ljava/lang/String;)Lsun/reflect/generics/tree/Tree;
+85 -1: (ILjava/lang/Object;Ljava/lang/Object;Ljava/util/concurrent/ConcurrentHashMap$Node;)V
+9 -1: singleton
+9 -1: destroyed
+15 -1: iso_8859-2:1987
+12 -1: comparingInt
+29 -1: [Ljava/lang/OutOfMemoryError;
+39 -1: (Ljava/lang/String;Ljava/lang/Object;)V
+27 -1: ([Ljava/util/Enumeration;)V
+36 -1: Ljava/nio/charset/CodingErrorAction;
+16 -1: getCanonicalName
+41 -1: (Ljava/nio/LongBuffer;)Ljava/util/BitSet;
+15 -1: DISPLAY_COUNTRY
+32 -1: getFunctionalInterfaceMethodName
+66 -1: (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V
+24 -1: getUnresolvedPermissions
+66 -1: ([Ljava/lang/ClassValue$Entry<*>;I)Ljava/lang/ClassValue$Entry<*>;
+41 -1: ()Lsun/reflect/annotation/AnnotationType;
+7 -1: afIndex
+7 -1: csascii
+20 -1: ()Ljava/util/Vector;
+16 -1: EntrySpliterator
+53 -1: (Ljava/lang/Throwable;I)Ljava/lang/StackTraceElement;
+81 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;
+20 -1: classAssertionStatus
+7 -1: EXECUTE
+21 -1: ()Ljava/lang/Runtime;
+6 -1: cesu-8
+7 -1: offset 
+23 -1: Ljava/lang/SafeVarargs;
+34 -1: (Ljava/util/LinkedHashMap$Entry;)V
+8 -1: entryFor
+8 -1: getCache
+46 -1: (Ljava/lang/Object;I)Ljava/lang/reflect/Field;
+4 -1: skip
+8 -1: (II[CI)V
+4 -1: vart
+12 -1: InnerClasses
+68 -1: (Ljava/util/Map;Ljava/lang/Class;[Ljava/lang/String;)Ljava/util/Map;
+19 -1: currentClassLoader0
+34 -1: getDefaultUncaughtExceptionHandler
+11 -1: String.java
+117 -1: (Ljava/lang/ThreadLocal<*>;ILjava/lang/ThreadLocal$ThreadLocalMap$Entry;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+7 -1: january
+31 -1: (ILjava/lang/String;IIIIIIIII)V
+24 -1: Lsun/misc/JavaAWTAccess;
+5 -1: .path
+15 -1: [Ljava/io/File;
+11 -1: Writer.java
+8 -1: , Size: 
+159 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/function/Function;Ljava/util/function/Consumer;)V
+32 -1: java/lang/invoke/LambdaForm$Name
+51 -1: (Ljava/util/ArrayList;Ljava/util/AbstractList;III)V
+7 -1: getZone
+14 -1: JIS_X0212-1990
+21 -1: (Ljava/util/Set<*>;)Z
+149 -1: (Lsun/util/locale/provider/LocaleServiceProviderPool$LocalizedObjectGetter;Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
+21 -1: Illegal Load factor: 
+35 -1: ()Ljava/lang/invoke/MethodTypeForm;
+22 -1: ([Z)Ljava/lang/String;
+7 -1: setName
+48 -1: <T:Ljava/lang/Object;>(TT;Ljava/lang/String;)TT;
+9 -1: INTERFACE
+22 -1: ARRAY_CHAR_INDEX_SCALE
+19 -1: java/nio/ByteBuffer
+23 -1: Ljava/io/ExpiringCache;
+7 -1: streams
+44 -1: java/lang/invoke/DirectMethodHandle$Accessor
+36 -1: ([Ljava/security/ProtectionDomain;)V
+16 -1: afterNodeRemoval
+9 -1: prevIndex
+49 -1: java/util/concurrent/ConcurrentHashMap$KeySetView
+22 -1: getEnumConstantsShared
+17 -1: java/lang/Integer
+12 -1: getRawOffset
+36 -1: ()Ljava/nio/file/attribute/FileTime;
+7 -1: offsets
+10 -1: ] throw =>
+3 -1: [[B
+10 -1: hostsEqual
+18 -1: compareComparables
+35 -1: sun/reflect/ConstructorAccessorImpl
+8 -1: december
+36 -1: Invalid binary time-zone data: TZDB:
+24 -1: synchronizedNavigableMap
+72 -1: sun/util/locale/provider/LocaleServiceProviderPool$LocalizedObjectGetter
+19 -1: parseCustomTimeZone
+88 -1: (Ljava/lang/Class<*>;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/DirectMethodHandle;
+9 -1: findClass
+6 -1: OBJECT
+3 -1: GBK
+110 -1: (JLjava/util/function/ToLongFunction<Ljava/util/Map$Entry<TK;TV;>;>;JLjava/util/function/LongBinaryOperator;)J
+6 -1: UTF_16
+17 -1: <all permissions>
+13 -1: lookupCharset
+28 -1: ConstructorAccessorImpl.java
+62 -1: java/util/concurrent/ConcurrentHashMap$MapReduceKeysToLongTask
+30 -1: Ljava/lang/ClassCastException;
+56 -1: ()Ljava/util/Spliterator<Ljava/util/Map$Entry<TK;TV;>;>;
+11 -1: invokerType
+23 -1: java/lang/StringBuilder
+12 -1: deleteCharAt
+11 -1: CR_OVERFLOW
+14 -1: toExternalForm
+3 -1: out
+34 -1: Ljava/net/URLStreamHandlerFactory;
+15 -1: encodeArrayLoop
+30 -1: ()Ljava/util/Enumeration<TK;>;
+27 -1: java/io/SyncFailedException
+10 -1: checkedSet
+16 -1: checkedSortedSet
+22 -1: java/util/zip/ZipEntry
+43 -1: java/util/LinkedHashMap$LinkedValueIterator
+22 -1: UnmodifiableCollection
+32 -1: java/nio/ByteBufferAsCharBufferB
+11 -1: blockerLock
+27 -1: checkExtensionsDependencies
+11 -1: fromIndex: 
+32 -1: java/nio/ByteBufferAsCharBufferL
+6 -1: UTF_32
+30 -1: java/util/Hashtable$Enumerator
+92 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Map<+TK;+TV;>;)Ljava/util/Map<TK;TV;>;
+4 -1: tail
+5 -1: (BB)C
+16 -1: isValidSignature
+9 -1: addMillis
+9 -1: peekFirst
+86 -1: <E:Ljava/lang/Object;>(Ljava/util/Set<TE;>;Ljava/lang/Class<TE;>;)Ljava/util/Set<TE;>;
+5 -1: (BB)I
+15 -1: jvmMicroVersion
+28 -1: [Ljava/util/Hashtable$Entry;
+15 -1: iso_8859-5:1988
+14 -1: HOUR_IN_MILLIS
+67 -1: (Ljava/util/PrimitiveIterator$OfInt;I)Ljava/util/Spliterator$OfInt;
+5 -1: (BB)S
+21 -1: UnmodifiableSortedMap
+79 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/util/concurrent/ConcurrentHashMap;)V
+56 -1: Ljava/util/Stack<Ljava/lang/ClassLoader$NativeLibrary;>;
+5 -1: (BB)Z
+10 -1: treeifyBin
+8 -1: isOpaque
+27 -1: java.launcher.ergo.message1
+27 -1: java.launcher.ergo.message2
+101 -1: Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Cloneable;Ljava/lang/Comparable<Ljava/util/Date;>;
+31 -1: (Ljava/io/ObjectOutputStream;)V
+3 -1: GET
+13 -1: matchLocation
+13 -1: WrappedMember
+63 -1: NoSuchMethodException:\n  could not find proper constructor for 
+14 -1: gssloginconfig
+70 -1: (Ljava/util/LinkedList$Node<TE;>;TE;Ljava/util/LinkedList$Node<TE;>;)V
+57 -1: (Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;
+11 -1: toByteArray
+49 -1: java/util/ArraysParallelSortHelpers$FJByte$Sorter
+13 -1: no protocol: 
+940 -1: aaaarababkaeaveafafrakakaamamhanargararaasasmavavaayaymazazebabakbebelbgbulbhbihbibisbmbambnbenbobodbrbrebsboscacatcechechchacocoscrcrecscescuchucvchvcycymdadandedeudvdivdzdzoeeeweelellenengeoepoesspaetesteueusfafasfffulfifinfjfijfofaofrfrafyfrygaglegdglaglglggngrngugujgvglvhahauhehebhihinhohmohrhrvhthathuhunhyhyehzheriainaidindieileigiboiiiiiikipkinindioidoisislititaiuikuiwhebjajpnjiyidjvjavkakatkgkonkikikkjkuakkkazklkalkmkhmknkankokorkrkaukskaskukurkvkomkwcorkykirlalatlbltzlgluglilimlnlinlolaoltlitlulublvlavmgmlgmhmahmimrimkmkdmlmalmnmonmomolmrmarmsmsamtmltmymyananaunbnobndndenenepngndonlnldnnnnononornrnblnvnavnynyaocociojojiomormororiososspapanpipliplpolpspusptporququermrohrnrunroronrurusrwkinsasanscsrdsdsndsesmesgsagsisinskslkslslvsmsmosnsnasosomsqsqisrsrpsssswstsotsusunsvsweswswatatamteteltgtgkththatitirtktuktltgltntsntotontrturtstsotttattwtwitytahuguigukukrururduzuzbvevenvivievovolwawlnwowolxhxhoyiyidyoyorzazhazhzhozuzul
+42 -1: java/util/LinkedHashMap$LinkedHashIterator
+39 -1: java/util/ArrayDeque$DescendingIterator
+15 -1: MODIFIER_LETTER
+21 -1: (Lsun/misc/Cleaner;)Z
+12 -1: PACKAGE_NAME
+14 -1: getMappedValue
+10 -1: interrupt0
+8 -1: LF_LIMIT
+17 -1: getDeclaringClass
+42 -1: (ZILjava/lang/String;)Ljava/lang/Class<*>;
+57 -1: (Ljava/lang/management/ThreadInfo;[Ljava/lang/Object;[I)V
+15 -1: java/nio/Bits$1
+61 -1: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
+28 -1: java/lang/ref/ReferenceQueue
+33 -1: [Ljava/security/cert/Certificate;
+44 -1: (Ljava/util/Hashtable;I)Ljava/util/Iterator;
+24 -1: java/security/CodeSigner
+19 -1: Non-positive length
+24 -1: [Ljava/util/Enumeration;
+38 -1: ()Ljava/security/PermissionCollection;
+16 -1: checkGenericType
+56 -1: java/util/concurrent/ConcurrentHashMap$ReduceEntriesTask
+7 -1: getYear
+5 -1: atime
+19 -1: Ljava/util/HashMap;
+125 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<Ljava/util/Map$Entry<TK;TV;>;+TU;>;Ljava/util/function/Consumer<-TU;>;)V
+22 -1: STOP_THREAD_PERMISSION
+46 -1: (Ljava/util/Enumeration;)Ljava/util/ArrayList;
+16 -1: getPathSeparator
+10 -1: getMembers
+8 -1: getIntAt
+26 -1: java/io/File$TempDirectory
+48 -1: java/lang/invoke/MethodHandleImpl$GuardWithCatch
+25 -1: CaseInsensitiveComparator
+8 -1: pollLast
+21 -1: GET_POLICY_PERMISSION
+23 -1: uninitialized call site
+75 -1: (Ljava/util/function/Function;Ljava/util/Comparator;)Ljava/util/Comparator;
+9 -1: directory
+51 -1: (JLjava/util/function/BiFunction<-TV;-TV;+TV;>;)TV;
+41 -1: (Ljava/lang/ThreadLocal$ThreadLocalMap;)V
+42 -1: (Ljava/lang/Throwable;Ljava/lang/String;)V
+26 -1: (FLjava/lang/Appendable;)V
+5 -1: stop0
+9 -1: substring
+64 -1: (ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)V
+5 -1: (JD)V
+9 -1: getShortB
+10 -1: nextOrSame
+24 -1: [ interpretWithArguments
+6 -1: GB2312
+32 -1: java/nio/BufferOverflowException
+23 -1: sun/nio/cs/ArrayEncoder
+4 -1: tanh
+9 -1: getShortL
+55 -1: (JLjava/util/function/BiFunction;)Ljava/util/Map$Entry;
+10 -1: getMessage
+12 -1: findTreeNode
+38 -1: DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+23 -1: [Ljava/lang/Comparable;
+17 -1: getCallSiteTarget
+55 -1: (Ljava/nio/ByteBuffer;II)Ljava/nio/charset/CoderResult;
+19 -1: java/util/ArrayList
+17 -1: java/io/DataInput
+13 -1: getPrincipals
+52 -1: <E:Ljava/lang/Object;>(TE;)Ljava/util/Iterator<TE;>;
+44 -1: sun/reflect/generics/tree/ClassTypeSignature
+6 -1: loaded
+20 -1: ()Ljava/lang/Object;
+36 -1: Ljava/util/concurrent/ConcurrentMap;
+13 -1: classValueMap
+33 -1: java/lang/SystemClassLoaderAction
+6 -1: loader
+31 -1: java/lang/annotation/Annotation
+5 -1: colon
+11 -1: Vector.java
+24 -1: CharacterDataLatin1.java
+12 -1: setUseCaches
+22 -1: getTypeAnnotationBytes
+9 -1: readShort
+24 -1: longPrimitiveReturnCount
+5 -1: get16
+34 -1: setDefaultUncaughtExceptionHandler
+17 -1: cachedInputStream
+29 -1: java/util/LinkedHashMap$Entry
+17 -1: java/lang/Boolean
+50 -1: ()[Lsun/reflect/generics/tree/FormalTypeParameter;
+14 -1: AnnotationData
+21 -1: Ljava/net/Proxy$Type;
+13 -1: invokeVirtual
+14 -1: Parameter.java
+21 -1: getDayOfWeekDateAfter
+92 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+56 -1: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+46 -1: sun/util/locale/provider/LocaleProviderAdapter
+29 -1: Ljava/lang/StackTraceElement;
+47 -1: (TK;Ljava/util/function/Function<-TK;+TV;>;)TV;
+32 -1: enableContextClassLoaderOverride
+68 -1: (Ljava/lang/AbstractStringBuilder;)Ljava/lang/AbstractStringBuilder;
+51 -1: Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
+9 -1: addAndGet
+5 -1: store
+7 -1: ([JII)V
+15 -1: signatureReturn
+18 -1: NF_reinvokerTarget
+22 -1: ()Ljava/nio/file/Path;
+25 -1: (C)Ljava/lang/Appendable;
+7 -1: expires
+18 -1: initializeInvokers
+19 -1: application/java-vm
+13 -1: stopOrSuspend
+13 -1: rawOffsetDiff
+6 -1: (JJZ)V
+9 -1: findValue
+5 -1: get32
+10 -1: asSubclass
+6 -1: forJRE
+3 -1: GMT
+7 -1: delete0
+69 -1: ([Ljava/security/cert/Certificate;[Ljava/security/cert/Certificate;)Z
+75 -1: (Ljava/util/LinkedList$Node;Ljava/lang/Object;Ljava/util/LinkedList$Node;)V
+6 -1: setEra
+24 -1: ()Ljava/util/Comparator;
+10 -1: access$200
+10 -1: access$202
+20 -1: retrieveDisplayNames
+3 -1: pae
+24 -1: java/lang/Byte$ByteCache
+7 -1: VM.java
+9 -1: TRANSIENT
+6 -1: setErr
+16 -1: jdkUpdateVersion
+10 -1: isResolved
+35 -1: sun/misc/JavaIOFileDescriptorAccess
+4 -1: char
+13 -1: Readable.java
+19 -1: UnixFileSystem.java
+43 -1: (Ljava/lang/ThreadLocal;)Ljava/lang/Object;
+40 -1: (Ljava/lang/String;[Ljava/lang/String;)V
+7 -1: profile
+11 -1: , version: 
+25 -1: PermissionCollection.java
+13 -1: setNormalized
+10 -1: access$210
+24 -1: (Ljava/lang/String;IJZ)J
+19 -1: isAnnotationPresent
+85 -1: (Ljava/util/Map;Ljava/lang/Class;Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
+19 -1: DMH.invokeInterface
+157 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/concurrent/ConcurrentHashMap$CollectionView<TK;TV;TV;>;Ljava/util/Collection<TV;>;Ljava/io/Serializable;
+94 -1: <E:Ljava/lang/Object;>Ljava/util/Collections$UnmodifiableCollection<TE;>;Ljava/util/List<TE;>;
+41 -1: java/lang/StringIndexOutOfBoundsException
+29 -1: java/net/UnknownHostException
+11 -1: (BBBBBBBB)J
+4 -1: iioe
+12 -1: (TK;TV;Z)TV;
+5 -1: ERROR
+31 -1: (Ljava/io/File;Ljava/io/File;)I
+32 -1: [Ljava/lang/invoke/MethodHandle;
+27 -1: lambda$comparing$77a9974f$1
+13 -1: toLowerCaseEx
+61 -1: (Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MemberName;)V
+66 -1: (ILjava/lang/Object;Ljava/lang/Class;)Ljava/util/HashMap$TreeNode;
+43 -1: java/util/concurrent/ConcurrentHashMap$Node
+23 -1: latestUserDefinedLoader
+24 -1: buildAnnotatedSuperclass
+19 -1: compareToIgnoreCase
+31 -1: (Ljava/io/File;Ljava/io/File;)Z
+40 -1: (I[C)[Ljava/lang/invoke/LambdaForm$Name;
+16 -1: ROTATE_THRESHOLD
+18 -1: getClassAtIfLoaded
+37 -1: java/lang/IllegalThreadStateException
+5 -1: get64
+12 -1: writeReplace
+14 -1: DAYS_PER_CYCLE
+4 -1: _get
+6 -1: nChars
+26 -1: ()Ljava/net/SocketAddress;
+27 -1: setUncaughtExceptionHandler
+6 -1: jzfile
+42 -1: All subclasses should override this method
+3 2: Foo
+56 -1: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+136 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedExceptionAction<TT;>;Ljava/security/AccessControlContext;[Ljava/security/Permission;)TT;
+3 -1: pdt
+44 -1: sun/util/locale/LocaleObjectCache$CacheEntry
+20 -1: java/util/Comparator
+9 -1: suspended
+11 -1: removeEntry
+10 -1: SPACE_FREE
+12 -1: processQueue
+9 -1: java.home
+5 -1: valid
+23 -1: printEnclosedStackTrace
+4 -1: push
+5 -1: guard
+23 -1: javaNetHttpCookieAccess
+36 -1: (Ljava/security/cert/Certificate;)[B
+9 -1: isWrapped
+12 -1: CharIterator
+26 -1: sun.io.useCanonPrefixCache
+42 -1: (Lsun/misc/Cleaner;Ljava/lang/Throwable;)V
+7 -1: prepare
+8 -1: parseInt
+13 -1: Invokers.java
+63 -1: (Ljava/net/URLClassLoader;)Ljava/security/AccessControlContext;
+18 -1: defaultWriteObject
+5 -1: class
+15 -1: EnclosingMethod
+23 -1: ([BI)Ljava/lang/String;
+16 -1: rangeCheckForAdd
+11 -1: getTimeImpl
+15 -1: arrayIndexScale
+5 -1: scalb
+5 -1: scale
+45 -1: (Ljava/lang/String;J)Ljava/util/zip/ZipEntry;
+8 -1: ([FIIF)I
+16 -1: runAllFinalizers
+27 -1: ()Lsun/net/ProgressMonitor;
+15 -1: MemberName.java
+27 -1: [Ljava/lang/reflect/Member;
+6 -1: length
+14 -1: genericInvoker
+8 -1: ([FIIF)V
+34 -1: Ljava/nio/file/attribute/FileTime;
+6 -1: number
+70 -1: (Ljava/lang/StringBuilder;Ljava/lang/String;)Ljava/lang/StringBuilder;
+12 -1: printLocales
+38 -1: java/lang/invoke/MethodHandleStatics$1
+8 -1: private 
+20 -1: invalid actions mask
+10 -1:  not found
+13 -1: parseClassSig
+22 -1: getAllAvailableLocales
+175 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/function/Function;Ljava/util/concurrent/atomic/AtomicReference;)V
+8 -1: ([BII)[B
+35 -1: (Ljava/util/HashMap$Node<TK;TV;>;)V
+132 -1: (Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V
+8 -1: ([BII)[C
+20 -1: DECIMAL_DIGIT_NUMBER
+40 -1: (Ljava/lang/String;[Ljava/lang/Object;)Z
+7 -1: ([CCI)I
+64 -1: (TV;)Ljava/util/concurrent/ConcurrentHashMap$KeySetView<TK;TV;>;
+8 -1: aliasMap
+8 -1: checkfpx
+44 -1: java/util/Comparators$NaturalOrderComparator
+48 -1: (Ljava/lang/ClassLoader;)Ljava/lang/ClassLoader;
+12 -1: Name is null
+10 -1: invoke_L_L
+8 -1: URL.java
+51 -1: (JILjava/time/ZoneOffset;)Ljava/time/LocalDateTime;
+25 -1: Lsun/invoke/util/Wrapper;
+19 -1: LauncherHelper.java
+10 -1: invoke_L_V
+5 -1: index
+30 -1: sun/security/x509/X509CertImpl
+8 -1: addClass
+46 -1: (I)Ljava/lang/invoke/LambdaForm$NamedFunction;
+20 -1: refKindIsConstructor
+10 -1: getFieldAt
+5 -1: log10
+13 -1: GetPerfAction
+15 -1: isLetterOrDigit
+27 -1: hasCheckedSpecialAttributes
+25 -1: MapReduceEntriesToIntTask
+17 -1: probeHomeLocation
+9 -1: image/png
+19 -1: checkSpreadArgument
+12 -1: LinkedKeySet
+13 -1: removeMapping
+39 -1: sun/security/util/SecurityConstants$AWT
+9 -1: MAX_RADIX
+28 -1: (F)Ljava/lang/StringBuilder;
+11 -1: ([C[B[I[I)Z
+36 -1: (Ljava/lang/Class;)Ljava/lang/Class;
+32 -1: java/lang/invoke/MagicLambdaImpl
+6 -1: monday
+16 -1: closeClassLoader
+41 -1: (Ljava/util/concurrent/locks/Condition;)I
+8 -1: reversed
+27 -1: sun/util/calendar/Gregorian
+49 -1: (Lsun/nio/cs/FastCharsetProvider;)Ljava/util/Map;
+42 -1: (Ljava/lang/String;Ljava/lang/Throwable;)V
+18 -1: java/util/Calendar
+8 -1: vmtarget
+17 -1: TREEIFY_THRESHOLD
+41 -1: (Ljava/util/concurrent/locks/Condition;)Z
+9 -1: deadChild
+8 -1: EntrySet
+5 -1: log1p
+58 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap;)V
+9 -1: pageCount
+14 -1: slotToArgTable
+24 -1: toMethodDescriptorString
+25 -1: ([B)Ljava/nio/ByteBuffer;
+21 -1: twoToTheDoubleScaleUp
+32 -1: sun/misc/URLClassPath$FileLoader
+40 -1: (Ljava/util/List<Ljava/lang/String;>;Z)V
+6 -1: cache1
+6 -1: cache2
+27 -1: Ljava/net/URLStreamHandler;
+20 -1: Detect premature EOF
+94 -1: (Ljava/io/OutputStream;Ljava/lang/Object;Ljava/nio/charset/Charset;)Lsun/nio/cs/StreamEncoder;
+12 -1: NF_checkBase
+20 -1: (Ljava/nio/Buffer;)V
+45 -1: <E:Ljava/lang/Object;>Ljava/util/Vector<TE;>;
+4 -1: Sync
+12 -1: H_UNRESERVED
+32 -1: (Ljava/util/Map;)Ljava/util/Set;
+32 -1: (Ljava/util/Map$Entry<TK;TV;>;)Z
+25 -1: java/util/Locale$Category
+8 -1: receiver
+9 -1: MAX_VALUE
+4 -1: .RSA
+25 -1: Ljava/net/URLClassLoader;
+15 -1: Terminator.java
+26 -1: (Ljava/lang/String;TV;)TV;
+4 -1: null
+76 -1: (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+9 -1: checkCast
+39 -1: ()Ljava/lang/AssertionStatusDirectives;
+15 -1: declaredMethods
+5 -1: clazz
+21 -1:    Retention policy: 
+20 -1: spreadArgElementType
+9 -1: WORD_MASK
+27 -1: ([IILjava/io/InputStream;)I
+11 -1: getMethodAt
+31 -1: (Ljava/net/URL;Ljava/net/URL;)Z
+13 -1: getLocaleName
+14 -1: isEnumConstant
+41 -1: (Ljava/lang/String;)Ljava/nio/CharBuffer;
+16 -1: newInvokeSpecial
+26 -1: (Ljava/nio/ByteBuffer;IS)V
+22 -1: sun/misc/JavaNioAccess
+184 -1: (Ljava/security/DomainCombiner;Ljava/lang/Class;Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;[Ljava/security/Permission;)Ljava/security/AccessControlContext;
+96 -1: (Ljava/lang/invoke/MethodHandle;ILjava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;
+5 -1: ([S)I
+30 -1: java/security/AccessController
+37 -1: sun/misc/Launcher$SharedArchiveLoader
+4 -1: pack
+5 -1: ([S)V
+51 -1: failure       before throwing exception, dump stack
+10 -1: dayOfMonth
+6 -1: CENSIG
+28 -1: java/util/function/Predicate
+26 -1: Malformed \\uxxxx encoding.
+9 -1: initIndex
+11 -1: invoke_LL_L
+23 -1: ConcurrentWeakInternSet
+14 -1: java/lang/Void
+42 -1: java/lang/String$CaseInsensitiveComparator
+38 -1: Ljava/lang/invoke/LambdaForm$Compiled;
+34 -1: java/util/Collections$SingletonSet
+142 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/invoke/CallSite;
+35 -1: too many bootstrap method arguments
+17 -1: maxDelimCodePoint
+13 -1: previousIndex
+3 -1: pop
+6 -1: CENSIZ
+7 -1: ([Z[Z)Z
+11 -1: invoke_LL_V
+3 -1: pos
+33 -1: java/nio/file/WatchEvent$Modifier
+3 -1: pow
+12 -1: nextClearBit
+15 -1: Dictionary.java
+27 -1: sun/reflect/CallerSensitive
+13 -1: signatureType
+10 -1: dstSavings
+13 -1: UnicodeLittle
+16 -1: America/New_York
+82 -1: (Lsun/util/locale/BaseLocale;Lsun/util/locale/LocaleExtensions;)Ljava/util/Locale;
+25 -1: referenceKindIsConsistent
+62 -1: Ljava/nio/Buffer;Ljava/lang/Comparable<Ljava/nio/LongBuffer;>;
+4 -1: INTS
+11 -1: LOAD_FACTOR
+40 -1: sun/reflect/DelegatingMethodAccessorImpl
+16 -1: accumulateAndGet
+21 -1: (B)Ljava/lang/String;
+6 -1: UNSAFE
+13 -1: resolveOrFail
+21 -1: MapReduceMappingsTask
+5 -1: arity
+77 -1: (Ljava/io/FileDescriptor;ZZLjava/lang/Object;)Ljava/nio/channels/FileChannel;
+5 -1: value
+61 -1: Ljava/util/concurrent/ConcurrentHashMap$EntrySetView<TK;TV;>;
+6 -1: forJar
+52 -1: <T:Ljava/lang/Object;>Ljava/lang/ref/Reference<TT;>;
+21 -1: CREATE_ACC_PERMISSION
+28 -1: sun/misc/NativeSignalHandler
+11 -1: defineClass
+5 -1: match
+93 -1: (Ljava/util/zip/ZipFile;Ljava/util/zip/ZipFile$ZipFileInputStream;Ljava/util/zip/Inflater;I)V
+11 -1: Double.java
+30 -1: America/Argentina/Buenos_Aires
+8 -1: previous
+37 -1: (Ljava/io/Writer;Ljava/lang/String;)V
+9 -1: Synthetic
+18 -1: isVMAnonymousClass
+62 -1: ([Ljava/lang/Object;Ljava/lang/Object;Ljava/util/Comparator;)I
+22 -1: (JI)Ljava/lang/String;
+49 -1: (Ljava/lang/CharSequence;II)Ljava/io/PrintStream;
+52 -1: ([Ljava/lang/Thread;)[[Ljava/lang/StackTraceElement;
+12 -1: setDayOfWeek
+11 -1: getManifest
+30 -1: java/util/Locale$FilteringMode
+54 -1: (Ljava/lang/String;)Lsun/util/calendar/CalendarSystem;
+12 -1: nextHashCode
+19 -1: ()Ljava/io/Console;
+42 -1: AccessControlContext invoking the Combiner
+19 -1: shouldBeInitialized
+17 -1: invocationCounter
+21 -1: IMPLEMENTATION_VENDOR
+7 -1: chararr
+60 -1: (Ljava/lang/String;)Ljava/util/Iterator<Ljava/lang/String;>;
+11 -1: asCollector
+52 -1: (ILjava/lang/CharSequence;)Ljava/lang/StringBuilder;
+9 -1: exception
+22 -1: newInstanceCallerCache
+20 -1: nativeLibraryContext
+24 -1: MODIFY_THREAD_PERMISSION
+4 -1: WRAP
+19 -1: Method name is null
+32 -1: sun/invoke/util/ValueConversions
+7 -1: APP_TAG
+24 -1: (Ljava/util/Hashtable;)I
+23 -1: METHOD_FORMAL_PARAMETER
+18 -1: inflationThreshold
+24 -1: java/io/DeleteOnExitHook
+3 -1: pst
+13 -1: BITS_PER_WORD
+25 -1: getConstructorAnnotations
+17 -1: CheckedCollection
+24 -1: (Ljava/util/Hashtable;)V
+7 -1: inClass
+5 -1: getFD
+8 -1: readLong
+19 -1: aliases_ISO_8859_13
+19 -1: invokeWithArguments
+19 -1: aliases_ISO_8859_15
+42 -1: ()Ljava/util/concurrent/ConcurrentHashMap;
+8 -1: expandTo
+23 -1: java/text/MessageFormat
+8 -1: classID0
+11 -1: replaceWith
+21 -1: Invalid port number :
+65 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)V
+19 -1: isGregorianLeapYear
+16 -1: asSpreaderChecks
+11 -1: withInitial
+10 -1: X-UTF-32BE
+57 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
+12 -1: wrong type: 
+57 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z
+17 -1: sun/misc/Resource
+14 -1: getReadTimeout
+8 -1: safeTrim
+38 -1: DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+14 -1: isElementIndex
+23 -1: FilterOutputStream.java
+6 -1: (IJI)V
+3 -1: put
+57 -1: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
+43 -1: Expecting an absolute path of the library: 
+8 -1: checkRef
+53 -1: (Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;
+74 -1: (Ljava/lang/Class<*>;[Ljava/lang/reflect/Field;)[Ljava/lang/reflect/Field;
+11 -1: user.script
+10 -1: H_ALPHANUM
+17 -1: getCalendarSystem
+48 -1: Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;
+17 -1: EnsureInitialized
+82 -1: (Ljava/lang/ThreadLocal$ThreadLocalMap;Ljava/lang/ThreadLocal;Ljava/lang/Object;)V
+243 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceMappingsToIntTask;Ljava/util/function/ToIntBiFunction;ILjava/util/function/IntBinaryOperator;)V
+26 -1: getAnnotatedExceptionTypes
+10 -1: validIndex
+6 -1: ([CC)I
+8 -1: overflow
+5 -1: getID
+93 -1: (Ljava/io/InputStream;Ljava/lang/Object;Ljava/nio/charset/Charset;)Lsun/nio/cs/StreamDecoder;
+22 -1: java/util/StringJoiner
+9 -1: putFields
+18 -1: USE_SHARED_ARCHIVE
+8 -1: thursday
+8 -1: nanoTime
+59 -1: (Lsun/reflect/annotation/AnnotationType;Ljava/lang/Class;)V
+69 -1: (Ljava/nio/charset/CoderResult$Cache;I)Ljava/nio/charset/CoderResult;
+36 -1: (J)Ljava/lang/AbstractStringBuilder;
+16 -1: java/util/Arrays
+6 -1: ([CC)V
+25 -1: registerAsParallelCapable
+4 -1: slot
+24 -1: java/net/URLConnection$1
+6 -1: koi8-r
+19 -1:  should be of type 
+46 -1: java/util/concurrent/ConcurrentHashMap$TreeBin
+6 -1: koi8-u
+34 -1: data type scale not a power of two
+53 -1: Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;
+21 -1: AccessibleObject.java
+53 -1: <E:Ljava/lang/Object;>()Ljava/util/NavigableSet<TE;>;
+88 -1: (Ljava/util/List;Ljava/util/Collection;Ljava/util/Locale$FilteringMode;)Ljava/util/List;
+17 -1: getAnnotationType
+36 -1: Ljava/util/HashMap$TreeNode<TK;TV;>;
+14 -1: declaringClass
+10 -1: read,write
+5 -1: getId
+10 -1: BIG_ENDIAN
+20 -1: PolymorphicSignature
+16 -1: comparingByValue
+67 -1: (ILjava/lang/invoke/MethodType;)[Ljava/lang/invoke/LambdaForm$Name;
+19 -1: java/util/Hashtable
+20 -1: getUnicodeLocaleKeys
+27 -1: ()Ljava/util/LinkedHashMap;
+51 -1: (Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;
+30 -1: java/util/HashMap$HashIterator
+22 -1: (IZ)Ljava/lang/String;
+5 -1: yield
+34 -1: java/lang/Throwable$SentinelHolder
+62 -1: (Ljava/lang/invoke/MethodType;ZI)Ljava/lang/invoke/LambdaForm;
+5 -1: (FD)F
+17 -1: java/util/SubList
+24 -1: (Ljava/io/PrintStream;)V
+7 -1: LF.zero
+25 -1: java/util/StringTokenizer
+15 -1: ISO8859_15_FDIS
+11 -1: powerOfTwoD
+11 -1: powerOfTwoF
+22 -1: WeakHashMapSpliterator
+15 -1: refKindIsGetter
+12 -1: setRawOffset
+11 -1: setProperty
+23 -1: (Ljava/lang/Object;IB)V
+45 -1: (ILjava/lang/Object;)Ljava/util/HashMap$Node;
+13 -1: applyAsDouble
+83 -1: (Lsun/misc/URLClassPath$FileLoader;Ljava/lang/String;Ljava/net/URL;Ljava/io/File;)V
+19 -1: MethodAccessor.java
+9 -1: WALL_TIME
+7 -1: INVOKES
+13 -1: java.ext.dirs
+9 -1: getStatic
+56 -1: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;
+42 -1: (Ljava/util/function/UnaryOperator<TE;>;)V
+27 -1: java/lang/Class$MethodArray
+10 -1: H_USERINFO
+19 -1: PostVMInitHook.java
+7 -1: running
+32 -1: Warning: passing argument as-is 
+13 -1: EntryIterator
+22 -1: NF_checkSpreadArgument
+46 -1: ([DLjava/util/function/IntToDoubleFunction;I)V
+7 -1: .<init>
+13 -1: mappingLength
+20 -1: implOnMalformedInput
+53 -1: (Ljava/lang/String;ILjava/lang/reflect/Executable;I)V
+26 -1: cannot make variable arity
+18 -1: SharedSecrets.java
+27 -1: (Ljava/io/InputStream;IZ)[B
+9 -1: Asia/Gaza
+55 -1: Ljava/util/Map<Ljava/lang/String;Ljava/lang/Class<*>;>;
+5 -1: NTLM 
+19 -1: defaultCenturyStart
+18 -1: addElapsedTimeFrom
+38 -1: (Lsun/misc/Cleaner;)Lsun/misc/Cleaner;
+44 -1: (Ljava/io/OutputStream;ZLjava/lang/String;)V
+22 -1: (Ljava/lang/Object;B)V
+6 1: [LBar;
+7 -1: classes
+23 -1: java/net/URLClassLoader
+17 -1: sun/misc/Launcher
+163 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;)[Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+12 -1: updateAndGet
+90 -1: (Ljava/net/URL;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+9 -1: increment
+27 -1: (Ljava/lang/CharSequence;)V
+16 -1: Ljava/io/Reader;
+27 -1: java/io/PushbackInputStream
+6 -1: (JFZ)V
+17 -1: getAppClassLoader
+35 -1: sun/reflect/generics/tree/Signature
+9 -1: elementAt
+27 -1: (Ljava/lang/CharSequence;)Z
+10 -1: readDouble
+37 -1: ([B)Ljava/nio/charset/CharsetEncoder;
+46 -1: (Ljava/lang/ThreadGroup;Ljava/lang/Runnable;)V
+4 -1: park
+36 -1: java/lang/NegativeArraySizeException
+49 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Z
+121 -1: <T:Ljava/lang/Object;U::Ljava/lang/Comparable<-TU;>;>(Ljava/util/function/Function<-TT;+TU;>;)Ljava/util/Comparator<TT;>;
+101 -1: (Ljava/lang/annotation/Annotation;Ljava/lang/annotation/Annotation;)Ljava/lang/annotation/Annotation;
+12 -1: .$|()[{^?*+\\
+6 -1: manRef
+3 -1: 437
+15 -1: newStringUnsafe
+15 -1: constantPoolOop
+10 -1: getPackage
+24 -1: FastCharsetProvider.java
+18 -1: getAnnotationBytes
+187 -1: (Ljava/security/DomainCombiner;Ljava/lang/Class<*>;Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;[Ljava/security/Permission;)Ljava/security/AccessControlContext;
+33 -1: Cannot suppress a null exception.
+27 -1: sun/nio/cs/StandardCharsets
+33 -1: (BB)Ljava/lang/invoke/MemberName;
+61 -1: ([Ljava/lang/ClassValue$Entry;ILjava/lang/ClassValue$Entry;)I
+10 -1: X-UTF-32LE
+5 -1: toMap
+89 -1: (Ljava/lang/Class<*>;Ljava/util/List<Ljava/lang/Class<*>;>;)Ljava/lang/invoke/MethodType;
+46 -1: ([Ljava/lang/Object;IILjava/util/Comparator;)V
+66 -1: ([Ljava/lang/reflect/Constructor;)[Ljava/lang/reflect/Constructor;
+22 -1: ()Ljava/nio/ByteOrder;
+20 -1: isMethodHandleInvoke
+25 -1: sun/net/www/URLConnection
+89 -1: Ljava/util/concurrent/ConcurrentHashMap<Ljava/lang/String;Ljava/lang/invoke/LambdaForm;>;
+49 -1: (Ljava/nio/charset/Charset;FFLjava/lang/String;)V
+17 -1: MIN_LOW_SURROGATE
+23 -1: AbstractCollection.java
+19 -1: (Ljava/util/Date;)I
+19 -1: (Ljava/util/Date;)J
+12 -1: cldrdata.jar
+4 -1: path
+77 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;IILjava/lang/String;[B)V
+6 -1: MS1250
+37 -1: setJavaSecurityProtectionDomainAccess
+11 -1: isDelimiter
+5 -1: char0
+6 -1: MS1251
+5 -1: char1
+16 -1: getJavaNetAccess
+6 -1: MS1252
+6 -1: MS1253
+6 -1: MS1254
+51 -1: (Ljava/lang/Class;)Ljava/security/ProtectionDomain;
+6 -1: MS1257
+93 -1: (Ljava/lang/String;Ljava/nio/ByteBuffer;Ljava/security/ProtectionDomain;)Ljava/lang/Class<*>;
+10 -1: access$300
+5 -1: (JZ)C
+19 -1: (Ljava/util/Date;)Z
+5 -1: (JZ)D
+26 -1: java/lang/Character$Subset
+10 -1: access$302
+5 -1: (JZ)F
+9 -1: emptyList
+5 -1: (JZ)I
+5 -1: (JZ)J
+23 -1: (Ljava/lang/Runnable;)V
+27 -1: java/lang/invoke/MemberName
+29 -1: ()Ljava/util/Comparator<TT;>;
+18 -1: retrieveDirectives
+7 -1: ([F[F)Z
+40 -1: (Lsun/misc/URLClassPath;Ljava/net/URL;)V
+5 -1: (JZ)S
+40 -1: (Ljava/util/function/IntUnaryOperator;)I
+5 -1: (JZ)V
+16 -1: parseAnnotations
+21 -1: (C)Ljava/lang/String;
+73 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(TK;TV;)Ljava/util/Map<TK;TV;>;
+15 -1: charset encoder
+17 -1: getDomainCombiner
+9 -1: EmptyList
+15 -1: java.vm.version
+19 -1: getResourceAsStream
+94 -1: Ljava/lang/ThreadLocal<Ljava/lang/ref/SoftReference<Ljava/lang/StringCoding$StringEncoder;>;>;
+26 -1: java/util/HashMap$TreeNode
+22 -1: (Ljava/util/HashMap;)V
+23 -1: sun/misc/URLClassPath$1
+65 -1: ([Ljava/net/URL;Ljava/lang/ClassLoader;)Ljava/net/URLClassLoader;
+20 -1: Hashtable Enumerator
+23 -1: sun/misc/URLClassPath$2
+10 -1: Array.java
+8 -1: FT_LIMIT
+24 -1: ()[Ljava/lang/Throwable;
+23 -1: sun/misc/URLClassPath$3
+14 -1: java/io/Writer
+5 -1: chars
+76 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>()Ljava/util/NavigableMap<TK;TV;>;
+6 -1:  final
+5 -1: error
+34 -1: java/lang/ApplicationShutdownHooks
+29 -1: Lsun/launcher/LauncherHelper;
+30 -1: ()Ljava/util/Enumeration<TE;>;
+47 -1: (Ljava/util/List;)Ljava/lang/invoke/MethodType;
+9 -1: scriptKey
+5 -1: BYTES
+12 -1: getException
+69 -1: (Ljava/lang/Class<*>;Ljava/lang/Object;)Ljava/lang/invoke/MethodType;
+14 -1: Illegal Load: 
+189 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$ReduceValuesTask;Ljava/util/function/BiFunction;)V
+66 -1: java/util/concurrent/ConcurrentHashMap$MapReduceMappingsToLongTask
+29 -1: getJavaIOFileDescriptorAccess
+11 -1: toCodePoint
+15 -1: setCreationTime
+18 -1: NULL_CAUSE_MESSAGE
+8 -1: elements
+32 -1: ()Ljava/nio/charset/CoderResult;
+8 -1: utf-32be
+7 -1: addDate
+4 -1: Cast
+23 -1: sun/misc/JavaLangAccess
+8 -1: 0{1,12}$
+27 -1: (Ljava/util/ArrayList;III)V
+11 -1: lastIndexOf
+14 -1: getCodeSources
+53 -1: (Lsun/util/calendar/CalendarDate;Ljava/lang/String;)V
+17 -1: cachedConstructor
+7 -1: forName
+74 -1: (Ljava/util/function/ToLongFunction;Ljava/lang/Object;Ljava/lang/Object;)I
+47 -1: (Ljava/lang/Object;)Lsun/reflect/FieldAccessor;
+8 -1: getDebug
+18 -1: currentClassLoader
+49 -1: Illegal leading minus sign on unsigned string %s.
+20 -1: toLowerCaseCharArray
+38 -1: java/util/concurrent/ConcurrentHashMap
+8 -1: isHidden
+92 -1: (Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V
+29 -1: java/lang/ArithmeticException
+26 -1: (Ljava/io/OutputStream;Z)V
+66 -1: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/RuntimeException;
+38 -1: Ljava/util/Map<Ljava/lang/String;TT;>;
+16 -1: getFindClassTime
+34 -1: ([J)Ljava/util/Spliterator$OfLong;
+24 -1: UnmodifiableNavigableSet
+32 -1: java/lang/ClassNotFoundException
+3 -1: \\n 
+6 -1: SEALED
+14 -1: Flushable.java
+3 -1: HST
+24 -1: (Ljava/lang/Object;JII)Z
+13 -1: toSecondOfDay
+16 -1: thenComparingInt
+26 -1: java/lang/NoSuchFieldError
+18 -1: java/util/Locale$1
+25 -1: [Ljava/util/HashMap$Node;
+75 -1: ([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+11 -1: x-mswin-936
+32 -1: java/lang/management/MemoryUsage
+25 -1: (JS)Ljava/nio/ByteBuffer;
+25 -1: java/lang/ref/Finalizer$1
+25 -1: java/lang/ref/Finalizer$2
+21 -1: (Ljava/util/BitSet;)V
+25 -1: java/lang/ref/Finalizer$3
+83 -1: <T:Ljava/lang/Object;>(Ljava/util/Collection<+TT;>;Ljava/util/Comparator<-TT;>;)TT;
+24 -1: sun/nio/ch/Interruptible
+21 -1: (Ljava/util/BitSet;)Z
+72 -1: ([Ljava/security/ProtectionDomain;Ljava/security/AccessControlContext;)V
+54 -1: Ljava/util/AbstractSet<Ljava/util/Map$Entry<TK;TV;>;>;
+34 -1: getConstructorParameterAnnotations
+4 -1: name
+92 -1: <E:Ljava/lang/Enum<TE;>;>Ljava/lang/Object;Ljava/lang/Comparable<TE;>;Ljava/io/Serializable;
+11 -1: FORM_OFFSET
+13 -1: getAliasTable
+5 -1: (DD)D
+23 -1: reflectionFactoryAccess
+221 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceValuesTask;Ljava/util/function/Function;Ljava/util/function/BiFunction;)V
+59 -1: (Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;
+6 -1: DELETE
+10 -1: returnType
+5 -1: (DD)I
+51 -1: ()Lsun/reflect/generics/repository/FieldRepository;
+8 -1: delegate
+12 -1: OTHER_LETTER
+18 -1: getTransitionIndex
+3 -1: HUP
+10 -1: (IIII[CI)V
+10 -1: ISO_8859-1
+17 -1: ArrayEncoder.java
+10 -1: ISO_8859-2
+34 -1: java/lang/reflect/AnnotatedElement
+10 -1: ISO_8859-4
+27 -1: sun/nio/cs/UTF_16LE$Decoder
+10 -1: ISO_8859-5
+13 -1: prefetchWrite
+9 -1: getFloatB
+10 -1: ISO_8859-7
+37 -1: (I)Ljava/lang/invoke/LambdaForm$Name;
+10 -1: ISO_8859-9
+10 -1: getActions
+11 -1: negateExact
+10 -1: isAbstract
+9 -1: getFloatL
+29 -1: java/lang/ClassValue$Identity
+14 -1: java/io/Reader
+8 -1: getOwner
+24 -1: java/lang/AssertionError
+17 -1: MethodHandle.java
+19 -1: classRedefinedCount
+10 -1: cachedYear
+15 -1: getAndIncrement
+26 -1: java.protocol.handler.pkgs
+14 -1: cleanSomeSlots
+27 -1: java/util/Spliterator$OfInt
+31 -1: getRawExecutableTypeAnnotations
+20 -1: ensureInitialization
+7 -1: os.arch
+57 -1: (Ljava/security/cert/CertPath;Ljava/security/Timestamp;)V
+21 -1: UNSAFE_COPY_THRESHOLD
+20 -1: toUnsignedBigInteger
+82 -1: (Ljava/util/concurrent/locks/Condition;)Ljava/util/Collection<Ljava/lang/Thread;>;
+15 -1: Reflection.java
+12 -1: decryptBlock
+3 -1: \\r 
+8 -1: newArray
+8 -1: Category
+36 -1: java/lang/reflect/GenericDeclaration
+22 -1: (Ljava/lang/String;Z)V
+8 -1: suspend0
+10 -1: getSigners
+22 -1: (Ljava/lang/String;Z)Z
+31 -1: Unable to create temporary file
+117 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue<TT;>;Ljava/lang/ClassValue$Entry<TT;>;)Ljava/lang/ClassValue$Entry<TT;>;
+17 -1: channelsAvailable
+9 -1: Date.java
+13 -1: toIndex < 0: 
+18 -1: mark > position: (
+11 -1: loadConvert
+4 -1: july
+42 -1: (Ljava/math/BigInteger;)Ljava/lang/String;
+6 -1: enable
+47 -1: (Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;
+6 -1: unpack
+13 -1: setDayOfMonth
+19 -1: name can't be empty
+16 -1: getExtensionKeys
+15 -1: getAndDecrement
+36 -1: Ljava/lang/ClassValue$ClassValueMap;
+38 -1: (Ljava/lang/Class;Ljava/lang/String;)V
+11 -1: csISOlatin0
+9 -1: retention
+23 -1: system protocol handler
+9 -1: nullsLast
+15 -1: refKindIsStatic
+3 -1:  (\n
+48 -1: sun/launcher/LauncherHelper$ResourceBundleHolder
+29 -1: ()Ljava/util/LinkedList<TE;>;
+11 -1: csISOlatin9
+31 -1: ([CII)Ljava/lang/StringBuilder;
+29 -1: (II)Ljava/lang/StringBuilder;
+7 -1: pdcache
+4 -1: june
+12 -1: ;/?:@&=+$,[]
+141 -1: ([Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/invoke/LambdaForm$Name;Ljava/lang/invoke/LambdaForm$Name;)[Ljava/lang/invoke/LambdaForm$Name;
+32 -1: ()[Ljava/util/WeakHashMap$Entry;
+110 -1: (Ljava/lang/Class<*>;ILjava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+81 -1: (Lsun/reflect/annotation/AnnotationType;Lsun/reflect/annotation/AnnotationType;)Z
+46 -1: String value %s exceeds range of unsigned int.
+6 -1: close0
+6 -1: (JDZ)V
+160 -1: <T:Ljava/lang/Object;>Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/reflect/GenericDeclaration;Ljava/lang/reflect/Type;Ljava/lang/reflect/AnnotatedElement;
+12 -1: LinkedValues
+24 -1: java/nio/HeapCharBufferR
+23 -1: jvmVersionInfoAvailable
+16 -1: classLoaderDepth
+33 -1: (Lsun/nio/ch/DirectBuffer;IIIII)V
+32 -1: java/nio/file/attribute/FileTime
+50 -1: java/util/concurrent/ConcurrentHashMap$CounterCell
+73 -1: (Lsun/misc/URLClassPath$JarLoader;Lsun/misc/JarIndex;)Lsun/misc/JarIndex;
+60 -1: (Ljava/net/URL;Ljava/lang/String;)Ljava/security/CodeSource;
+25 -1: Ljava/lang/ref/Finalizer;
+12 -1: utf-32be-bom
+40 -1: (Ljava/lang/String;ILjava/lang/Object;)V
+9 -1: THROW_UCS
+23 -1: java/util/AbstractMap$1
+23 -1: java/util/AbstractMap$2
+10 -1: x-utf-32be
+4 -1: (S)B
+60 -1: (Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/LambdaForm;
+20 -1: ResourceBundleHolder
+4 -1: (S)I
+13 -1: getSuppressed
+17 -1: jdk_micro_version
+4 -1: (S)J
+9 -1: isNumeric
+10 -1: variantKey
+8 -1: utf-32le
+47 -1: java/util/concurrent/ConcurrentHashMap$MapEntry
+25 -1: ()Ljava/lang/Class<-TT;>;
+6 -1: closed
+4 -1: (S)S
+15 -1: setStandardTime
+10 -1: ShortCache
+4 -1: (S)V
+40 -1: sun/net/www/MessageHeader$HeaderIterator
+17 -1: jdk_major_version
+8 -1: FXHelper
+6 -1: CENTIM
+19 -1: java/security/Guard
+46 -1: java.lang.invoke.MethodHandle.DUMP_CLASS_FILES
+4 -1: ENUM
+27 -1: Ljava/lang/SecurityManager;
+39 -1: ([Ljava/lang/Class;[Ljava/lang/Class;)Z
+11 -1: getFieldAt0
+12 -1: user.variant
+28 -1: (Ljava/io/DataInputStream;)V
+44 -1: ([JLjava/util/function/LongBinaryOperator;)V
+7 -1: getRoot
+3 -1:  + 
+16 -1: identityHashCode
+25 -1: java/security/Permissions
+16 -1: Ljava/net/Proxy;
+23 -1: java/io/ExpiringCache$1
+5 -1:  more
+10 -1: formatList
+49 -1: (Ljava/lang/String;)Lsun/launcher/LauncherHelper;
+29 -1: Relative path in absolute URI
+11 -1: checkMapped
+8 -1: Checksum
+8 -1: " Radix:
+9 -1: getAndAdd
+9 -1: implReady
+16 -1: SynchronizedList
+30 -1: [Ljava/lang/StackTraceElement;
+5 -1: right
+13 -1: UTF_16BE.java
+4 -1: HEAD
+11 -1: isInvocable
+6 -1: ENDCOM
+15 -1: getPropertiesEx
+6 -1: Unsafe
+7 -1: IBM-819
+37 -1: : 0 <= i2 && i2 < names.length: 0 <= 
+19 -1: filterAndAddHeaders
+22 -1: nativeParkEventPointer
+18 -1: checkPositionIndex
+13 -1: invalid url: 
+25 -1:  out of range from input 
+9 -1: loadClass
+12 -1: encodingName
+9 -1: x-JIS0208
+38 -1: (Ljava/lang/Class;Ljava/lang/Object;)Z
+28 -1: (I)Ljava/lang/reflect/Field;
+17 -1: getJvmVersionInfo
+6 -1: LIJFDV
+21 -1: (D)Ljava/lang/String;
+7 -1: oomeMsg
+30 -1: java/io/InvalidObjectException
+25 -1: java/io/FilterInputStream
+32 -1: Ljava/net/ContentHandlerFactory;
+13 -1: toUnsignedInt
+17 -1: reconstitutionPut
+37 -1: (Ljava/lang/Object;)Ljava/lang/Class;
+14 -1: getContentType
+43 -1: java/util/Collections$SynchronizedSortedSet
+24 -1: (II)Ljava/nio/file/Path;
+25 -1: JAVAFX_APPLICATION_MARKER
+29 -1: (IC)Ljava/lang/StringBuilder;
+13 -1: java/util/Set
+10 -1: clearError
+64 -1: (Ljava/lang/invoke/MethodType;[I)Ljava/lang/invoke/MethodHandle;
+25 -1: java/io/FileInputStream$1
+8 -1: getFirst
+36 -1: (Lsun/reflect/ConstructorAccessor;)V
+84 -1: (Ljava/util/NavigableMap;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/NavigableMap;
+42 -1: (Ljava/lang/CharSequence;)Ljava/io/Writer;
+52 -1: ([Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+6 -1: (IFI)V
+62 -1: <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Queue<TE;>;
+17 -1: getHeaderFieldInt
+16 -1: CheckedSortedMap
+39 -1: (ZILjava/lang/String;)Ljava/lang/Class;
+10 -1: getterName
+10 -1: Asia/Tokyo
+4 -1: Node
+7 -1: rotate1
+13 -1: Stream closed
+7 -1: rotate2
+9 -1: checkExec
+17 -1: NF_checkExactType
+18 -1: ReverseComparator2
+18 -1: arrayElementGetter
+97 -1: (Ljava/util/ArrayPrefixHelpers$DoubleCumulateTask;Ljava/util/function/DoubleBinaryOperator;[DII)V
+9 -1: iso8859-1
+9 -1: iso8859-2
+9 -1: iso8859-4
+9 -1: iso8859-5
+9 -1: iso8859-7
+16 -1:  getPermissions 
+9 -1: iso8859-9
+9 -1: fromClass
+17 -1:  with modifiers "
+8 -1: isBooted
+24 -1: getCommonPoolParallelism
+10 -1: initialize
+47 -1: <T:Ljava/lang/Object;>(TT;)Ljava/util/Set<TT;>;
+17 -1: checkElementIndex
+14 -1: openConnection
+47 -1: (Ljava/lang/Thread;Lsun/nio/ch/Interruptible;)V
+12 -1: isAuthorized
+17 -1: ReduceEntriesTask
+7 -1: command
+24 -1: ArithmeticException.java
+24 -1: ensureOpenOrZipException
+67 -1: (Lsun/util/calendar/CalendarDate;I)Lsun/util/calendar/CalendarDate;
+39 -1: Ljava/lang/invoke/MethodHandles$Lookup;
+31 -1: Enclosing constructor not found
+34 -1: ()Lsun/util/calendar/BaseCalendar;
+25 -1: (JLjava/lang/Object;JJJ)V
+12 -1:  > toIndex: 
+22 -1: LocaleObjectCache.java
+19 -1: sun/misc/Launcher$1
+31 -1: java/util/HashMap$EntryIterator
+8 -1: contains
+60 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;
+53 -1: (I[Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+19 -1: java/io/PrintStream
+42 -1: java/lang/Math$RandomNumberGeneratorHolder
+100 -1: <K:Ljava/lang/Object;>(I)Ljava/util/concurrent/ConcurrentHashMap$KeySetView<TK;Ljava/lang/Boolean;>;
+14 -1: getCapturedArg
+14 -1: getCodeSigners
+20 -1: mark() not supported
+56 -1: (Lsun/misc/URLClassPath;I)Lsun/misc/URLClassPath$Loader;
+20 -1: java/lang/StrictMath
+14 -1: annotationType
+3 -1: IET
+4 -1: lang
+13 -1: JarEntry.java
+9 -1: ([CIIII)I
+9 -1: canEncode
+5 -1: extra
+30 -1: java/lang/ref/ReferenceQueue$1
+37 -1: java/nio/channels/ReadableByteChannel
+73 -1: (Ljava/util/Map$Entry<Ljava/lang/String;Ljava/io/ExpiringCache$Entry;>;)Z
+24 -1: java/io/BufferedReader$1
+10 -1: x-utf-32le
+16 -1: methodDescriptor
+25 -1: (IJ)Ljava/nio/ByteBuffer;
+18 -1: getSystemResources
+46 -1: (Ljava/lang/String;I)Ljava/util/regex/Pattern;
+46 -1: (Ljava/net/URL;)Lsun/misc/URLClassPath$Loader;
+20 -1: calendars.properties
+25 -1: implOnUnmappableCharacter
+12 -1: signers_name
+40 -1: (ZILjava/util/Locale;)Ljava/lang/String;
+8 -1: (TE;)TE;
+50 -1: ()Lsun/util/locale/provider/LocaleProviderAdapter;
+11 -1: key is null
+7 -1: encrypt
+21 -1: millisUntilExpiration
+55 -1: Unable to parse property sun.reflect.inflationThreshold
+9 -1: checkExit
+5 -1: SHORT
+43 -1: java/util/Collections$UnmodifiableSortedSet
+10 -1: ISO8859_15
+16 -1: verifyParameters
+24 -1: buildAnnotatedInterfaces
+15 -1: refKindIsSetter
+45 -1: (JLjava/util/function/BiConsumer<-TK;-TV;>;)V
+23 -1: (Ljava/lang/Object;IC)V
+90 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue$Entry<TT;>;)Ljava/lang/ClassValue$Entry<TT;>;
+30 -1: (Ljava/net/URL;)Ljava/net/URI;
+60 -1: (BLjava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Object;)V
+43 -1: (Ljava/util/Collection;Ljava/lang/Object;)I
+44 -1: (Ljava/net/URLConnection;)Ljava/lang/Object;
+17 -1: Stream not marked
+11 -1: targetCheck
+127 -1: (Ljava/lang/Class<*>;ILjava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;
+11 -1: debugString
+112 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;
+43 -1: (Ljava/util/Collection;Ljava/lang/Object;)V
+15 -1: NF_staticOffset
+22 -1: CASE_INSENSITIVE_ORDER
+6 -1: unpark
+29 -1: (Ljava/lang/CharSequence;II)I
+59 -1: Ljava/util/concurrent/ConcurrentHashMap$KeySetView<TK;TV;>;
+19 -1: defaultFormatLocale
+7 -1: combine
+58 -1: (Ljava/util/Locale$LocaleKey;)Lsun/util/locale/BaseLocale;
+29 -1: (Ljava/lang/CharSequence;II)V
+35 -1: sun/util/calendar/BaseCalendar$Date
+57 -1: Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;
+75 -1: ([Ljava/lang/reflect/Member;[Ljava/lang/String;)[Ljava/lang/reflect/Member;
+15 -1: MethodType_init
+5 -1: (JF)V
+20 -1: AUTOSELECT_FILTERING
+12 -1: invokeStatic
+18 -1: readFileDescriptor
+22 -1: java/lang/Terminator$1
+72 -1: (Ljava/lang/Object;Ljava/util/function/UnaryOperator;)Ljava/lang/Object;
+17 -1: EMPTY_STACK_TRACE
+13 -1: isSamePackage
+32 -1: ()Ljava/security/DomainCombiner;
+10 -1: decodeLoop
+30 -1: DIRECTIONALITY_EUROPEAN_NUMBER
+112 -1: (Ljava/util/List<Ljava/util/Locale$LanguageRange;>;Ljava/util/Collection<Ljava/lang/String;>;)Ljava/lang/String;
+33 -1: (Ljava/util/function/Predicate;)Z
+35 -1: logincontext  login context results
+17 -1: sun/nio/cs/UTF_16
+13 -1: SingletonList
+5 -1:  end=
+7 -1: getURLs
+17 -1: traceInstructions
+22 -1: generateCustomizedCode
+9 -1: NO_CHANGE
+11 -1: Number.java
+49 -1: <T:Ljava/lang/Object;>(ITT;)Ljava/util/List<TT;>;
+19 -1: checkSpecifyHandler
+8 -1: setValue
+30 -1: (Ljava/net/URL;)Ljava/net/URL;
+22 -1: (Ljava/lang/Object;C)V
+19 -1: Negative capacity: 
+24 -1: ArrayStoreException.java
+52 -1: (Ljava/lang/StringBuffer;II)Ljava/lang/StringBuffer;
+14 -1: linkMethodImpl
+42 -1: java/util/InvalidPropertiesFormatException
+4 -1: last
+19 -1: getLocalizedMessage
+65 -1: (Ljava/text/MessageFormat;[Ljava/lang/String;)[Ljava/lang/String;
+61 -1: Ljava/lang/Object;Ljava/util/Enumeration<Ljava/lang/Object;>;
+40 -1: (I[CII)Ljava/lang/AbstractStringBuilder;
+27 -1: java.launcher.opt.datamodel
+29 -1: (Ljava/lang/reflect/Method;)V
+19 -1: SPECIFICATION_TITLE
+123 -1: (Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;ILjava/lang/Class;)Lsun/reflect/SerializationConstructorAccessorImpl;
+32 -1: (I[CII)Ljava/lang/StringBuilder;
+29 -1: (Ljava/lang/reflect/Method;)Z
+23 -1: (Z[B)Ljava/lang/String;
+27 -1: sun/nio/cs/Surrogate$Parser
+32 -1: (Ljavax/security/auth/Subject;)Z
+29 -1: ()Ljava/lang/invoke/Invokers;
+7 -1: getPool
+7 -1: textOut
+12 -1: getEntryTime
+14 -1: classModifiers
+47 -1: (Ljava/util/Locale$Category;)Ljava/util/Locale;
+32 -1: getInheritedAccessControlContext
+4 -1: rcbt
+37 -1: (Ljava/lang/Class<*>;Ljava/io/File;)Z
+25 -1: AccessControlContext.java
+22 -1: FileURLConnection.java
+12 -1: NaturalOrder
+34 -1: sun/util/calendar/CalendarSystem$1
+94 -1: ([Ljava/lang/reflect/Method;Ljava/lang/String;[Ljava/lang/Class<*>;)Ljava/lang/reflect/Method;
+17 -1: No enum constant 
+7 -1: ([DII)V
+8 -1: register
+23 -1: FINAL_QUOTE_PUNCTUATION
+27 -1: ACCESS_CLIPBOARD_PERMISSION
+15 -1: verifyConstants
+20 -1: (Ljava/io/Writer;I)V
+45 -1: (Ljava/lang/String;)Ljava/lang/reflect/Field;
+24 -1: linkMethodHandleConstant
+43 -1: (Ljava/io/OutputStream;Ljava/lang/String;)V
+125 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Comparator<-TV;>;)Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
+14 -1: ALL_PERMISSION
+12 -1: createObject
+10 -1: CRC32.java
+14 -1: reservedMemory
+22 -1: ensureCapacityInternal
+11 -1: FormatData_
+9 -1: maxMemory
+27 -1: (I)Ljava/util/ListIterator;
+8 -1: UTF-16BE
+27 -1: AbstractSequentialList.java
+10 -1: access$400
+16 -1: Locale settings:
+10 -1: access$402
+12 -1: HashSet.java
+24 -1: java/lang/Long$LongCache
+30 -1: [Ljava/lang/reflect/Parameter;
+11 -1: single_step
+45 -1: (Ljava/lang/String;)Lsun/security/util/Debug;
+97 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;)Ljava/lang/invoke/SimpleMethodHandle;
+16 -1: indexOfBangSlash
+7 -1: region=
+26 -1: ([BII)Ljava/lang/Class<*>;
+8 -1: bitCount
+3 -1: INT
+67 -1: <T:Ljava/lang/Object;>([TT;Ljava/util/function/IntFunction<+TT;>;)V
+35 -1: newGetFloatIllegalArgumentException
+11 -1: ([DII[DII)V
+22 -1: makePreparedLambdaForm
+3 -1:  < 
+35 -1: sun/management/GarbageCollectorImpl
+4 -1: (*)*
+7 -1: getPort
+18 -1: java/io/FileSystem
+7 -1: getNode
+38 -1: (Ljava/lang/Object;I)Ljava/lang/Class;
+36 -1: $SwitchMap$java$util$Locale$Category
+18 -1: securityCheckCache
+5 -1: cdate
+10 -1: childValue
+19 -1: getMainClassFromJar
+70 -1: <T:Ljava/lang/Enum<TT;>;>(Ljava/lang/Class<TT;>;Ljava/lang/String;)TT;
+20 -1: unsuspendSomeThreads
+29 -1: sun.classloader.findClassTime
+11 -1: plusSeconds
+3 -1:  = 
+4 -1: Lock
+7 -1: regions
+38 -1: ()Ljava/lang/reflect/Constructor<TT;>;
+25 -1: parseParameterAnnotations
+20 -1: getSystemGMTOffsetID
+33 -1: [Cc][Oo][Dd][Ee][Bb][Aa][Ss][Ee]=
+37 -1: (Ljava/lang/String;I)Ljava/lang/Byte;
+10 -1: permission
+78 -1: (Ljava/lang/reflect/Constructor;)Lsun/reflect/generics/scope/ConstructorScope;
+28 -1: (Lsun/misc/JavaLangAccess;)V
+26 -1: GET_CLASSLOADER_PERMISSION
+24 -1: (J)Ljava/nio/ByteBuffer;
+20 -1: getUnresolvedActions
+49 -1: (I[BIILsun/security/util/ManifestEntryVerifier;)V
+5 -1: (ZJ)V
+14 -1: isClassOnlyJar
+35 -1: ()[Ljava/util/HashMap$Node<TK;TV;>;
+23 -1: ()Ljava/util/SortedMap;
+29 -1: HistoricallyNamedCharset.java
+30 -1: no leading reference parameter
+8 -1: csCESU-8
+3 -1:  > 
+13 -1: invoke_LLLL_L
+109 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/NavigableMap<TK;+TV;>;)Ljava/util/NavigableMap<TK;TV;>;
+13 -1: invoke_LLLL_V
+46 -1: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;
+5 -1: offer
+12 -1: isoLanguages
+61 -1: (Ljava/io/OutputStream;Ljava/lang/String;Ljava/lang/String;)V
+44 -1: sun/reflect/BootstrapConstructorAccessorImpl
+12 -1: BaseIterator
+58 -1: (IZ[Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/String;
+23 -1: initializeOSEnvironment
+62 -1: ([Ljava/security/cert/Certificate;)[Ljava/security/CodeSigner;
+3 -1:  >>
+13 -1: searchEntries
+7 -1: setDate
+3 -1: red
+3 -1: ref
+10 -1: EMPTY_LIST
+3 -1: rem
+78 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractCollection<TE;>;Ljava/util/List<TE;>;
+9 -1: scanToken
+6 -1: greek8
+9 -1: basicType
+12 -1: getFromClass
+43 -1: averageCharsPerByte exceeds maxCharsPerByte
+8 -1: isDaemon
+7 -1: nonNull
+17 -1: Invalid default: 
+45 -1: (Lsun/misc/URLClassPath;Ljava/lang/String;Z)V
+18 -1: java/lang/String$1
+11 -1: copyMethods
+15 -1: sun/misc/Signal
+5 -1: float
+18 -1: StreamDecoder.java
+19 -1: no such constructor
+14 -1: bad arity for 
+14 -1: divideUnsigned
+10 -1: CODING_END
+3 -1: IST
+14 -1: HeaderIterator
+9 -1: september
+20 -1: makeVarargsCollector
+6 -1: L_PATH
+45 -1: (Ljava/lang/String;)Ljava/io/File$PathStatus;
+24 -1: URI scheme is not "file"
+85 -1: (Ljava/lang/Class<TT;>;Ljava/lang/Class<TV;>;Ljava/lang/String;Ljava/lang/Class<*>;)V
+27 -1: java/util/function/Supplier
+17 -1: checkedCollection
+8 -1: MapEntry
+81 -1: (Ljava/lang/invoke/MethodHandle;ILjava/util/List;)Ljava/lang/invoke/MethodHandle;
+34 -1: java/security/ProtectionDomain$Key
+14 -1: List length = 
+39 -1: ([Ljava/lang/Object;)Ljava/lang/String;
+87 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;
+7 -1: unparse
+28 -1: jarFileHasClassPathAttribute
+40 -1: (Lsun/misc/JavaIOFileDescriptorAccess;)V
+30 -1: (Ljava/lang/reflect/Field;ZZ)V
+22 -1: GetPropertyAction.java
+8 -1: RUNNABLE
+10 -1: exprString
+13 -1: getAnnotation
+19 -1: class can't be null
+22 -1: defaultAssertionStatus
+8 -1: getName0
+16 -1: quoteReplacement
+15 -1: getMemberVMInfo
+42 -1: (Ljava/lang/Class<*>;)Ljava/lang/Class<*>;
+16 -1: cachedLambdaForm
+16 -1: addFinalRefCount
+12 -1: getMethodAt0
+8 -1: ([ZII)[Z
+44 -1: (Ljava/lang/Object;TV;Ljava/lang/Object;)TV;
+4 -1: [TT;
+29 -1: Ljava/lang/invoke/LambdaForm;
+28 -1: java/util/DualPivotQuicksort
+61 -1: ()Ljava/util/concurrent/ConcurrentHashMap$KeySetView<TK;TV;>;
+17 -1: registerDirectory
+8 -1: jarFiles
+69 -1: (Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/String;
+54 -1: [Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+15 -1: getDefaultValue
+39 -1: sun/util/calendar/ZoneInfoFile$Checksum
+20 -1: DISABLE_JAR_CHECKING
+12 -1: CONTENT_TYPE
+46 -1: array type not assignable to trailing argument
+60 -1: <T:Ljava/lang/Object;>([TT;II)Ljava/util/stream/Stream<TT;>;
+47 -1: java.lang.invoke.MethodHandle.COMPILE_THRESHOLD
+9 -1: toInstant
+152 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/NavigableMap<TK;TV;>;Ljava/lang/Class<TK;>;Ljava/lang/Class<TV;>;)Ljava/util/NavigableMap<TK;TV;>;
+7 -1: L_ALPHA
+29 -1: java/lang/AbstractMethodError
+29 -1: java/util/jar/Attributes$Name
+15 -1: LOCALE_SETTINGS
+19 -1: (J)Ljava/lang/Long;
+4 -1: jar:
+17 -1: ensureInitialized
+13 -1: LAST_MODIFIED
+40 -1: ([Ljava/lang/String;)[Ljava/lang/String;
+7 -1: shuffle
+70 -1: (Lsun/util/locale/LanguageTag;)Lsun/util/locale/InternalLocaleBuilder;
+19 -1: isPackageAccessible
+17 -1: compileToBytecode
+11 -1: getPackages
+237 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceKeysToIntTask;Ljava/util/function/ToIntFunction;ILjava/util/function/IntBinaryOperator;)V
+53 -1: java/util/concurrent/ConcurrentHashMap$KeySpliterator
+26 -1: setURLStreamHandlerFactory
+47 -1: access        print all checkPermission results
+22 -1: sun/reflect/MethodInfo
+75 -1: (Ljava/lang/String;ZLjava/util/Set<Ljava/lang/String;>;)Lsun/misc/Resource;
+6 -1: KOI8-R
+14 -1: Character.java
+5 -1: (SS)I
+8 -1: unshared
+73 -1: (Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
+19 -1: replacementTreeNode
+10 -1: BA_REGULAR
+8 -1: UTF-16LE
+44 -1: (Ljava/lang/Class<*>;[Ljava/lang/Class<*>;)V
+22 -1: InputStreamReader.java
+17 -1: getInvocationType
+23 -1: getDeclaredConstructors
+48 -1: [Lsun/reflect/generics/tree/FormalTypeParameter;
+67 -1: (Ljava/util/Comparator;Ljava/util/Map$Entry;Ljava/util/Map$Entry;)I
+6 -1: koi8_r
+14 -1: ofTotalSeconds
+16 -1: content-encoding
+6 -1: koi8_u
+10 -1: getEncoded
+6 -1: ()[TT;
+43 -1: ([ILjava/util/function/IntUnaryOperator;I)V
+18 -1: getSecurityContext
+13 -1: LF_GEN_LINKER
+78 -1: (BLjava/lang/invoke/MemberName;Ljava/lang/Class;)Ljava/lang/invoke/MemberName;
+49 -1: (Ljava/util/HashMap;[Ljava/util/HashMap$Node;II)V
+19 -1: LinkedEntryIterator
+23 -1: Warning: JIT compiler "
+7 -1: static 
+100 -1: (Ljava/lang/Class;ZLjava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/util/List;
+79 -1: <T:Ljava/lang/Object;>(Ljava/util/Collection<+TT;>;)Ljava/util/Collection<TT;>;
+10 -1: iso-ir-100
+10 -1: iso-ir-101
+13 -1: toUpperString
+31 -1: ()Ljava/util/Spliterator$OfInt;
+43 -1: Ljava/lang/StringIndexOutOfBoundsException;
+19 -1: Lsun/misc/JarIndex;
+7 -1: Version
+90 -1: (Ljava/lang/String;Ljava/nio/ByteBuffer;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
+10 -1: getHandler
+45 -1: (ILjava/lang/Object;)Ljava/lang/StringBuffer;
+28 -1: getDeclaredAnnotationsByType
+46 -1: ([Ljava/lang/Class;Ljava/lang/StringBuilder;)V
+53 -1: ()Ljava/util/Enumeration<Ljava/security/Permission;>;
+15 -1: addAllNonStatic
+10 -1: iso-ir-110
+14 -1:     Using VM: 
+17 -1: casReflectionData
+26 -1: (Lsun/util/PreHashedMap;)I
+24 -1: removeByNameAndSignature
+4 -1: OS X
+85 -1: (Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)Z
+16 -1: JarEntryIterator
+38 -1: Ljava/lang/Class<Ljava/lang/Integer;>;
+37 -1: Ljava/lang/Class<Ljava/lang/Double;>;
+28 -1: ([Ljava/util/HashMap$Node;)V
+34 -1: java/lang/reflect/GenericArrayType
+14 -1: annotationData
+26 -1: (Lsun/util/PreHashedMap;)V
+22 -1: checkPackageDefinition
+30 -1: ACCUMULATED_DAYS_IN_MONTH_LEAP
+12 -1: lowestOneBit
+64 -1: (Ljava/lang/ThreadLocal$ThreadLocalMap;Ljava/lang/ThreadLocal;)V
+16 -1: asReadOnlyBuffer
+11 -1: getRealName
+17 -1: StringCoding.java
+10 -1: iso-ir-126
+11 -1: isSurrogate
+8 -1: setError
+138 -1: <T:Ljava/lang/Object;U:Ljava/lang/Object;>(Ljava/util/function/Function<-TT;+TU;>;Ljava/util/Comparator<-TU;>;)Ljava/util/Comparator<TT;>;
+8 -1: (TK;)TK;
+4 -1: java
+136 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedAction<TT;>;Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;)TT;
+36 -1: ()Lsun/util/locale/LocaleExtensions;
+12 -1: doubleStream
+28 -1: ()Ljava/util/SimpleTimeZone;
+7 -1: :@&=+$,
+94 -1: Ljava/lang/ThreadLocal<Ljava/lang/ref/SoftReference<Ljava/lang/StringCoding$StringDecoder;>;>;
+64 -1: (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
+19 -1: getSystemTimeZoneID
+18 -1: ReentrantLock.java
+8 -1: emptyMap
+16 -1: getSavedProperty
+249 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceEntriesToDoubleTask;Ljava/util/function/ToDoubleFunction;DLjava/util/function/DoubleBinaryOperator;)V
+14 -1: KeySpliterator
+13 -1: findResources
+14 -1: forWrapperType
+8 -1: floorMod
+12 -1: isoCountries
+10 -1: CheckedSet
+21 -1: AbstractCalendar.java
+12 -1: IS_INVOCABLE
+45 -1: (Ljava/lang/Class;)Lsun/reflect/ConstantPool;
+19 -1: checkSecurityAccess
+13 -1: Invalid index
+28 -1: STACK_TRACE_ELEMENT_SENTINEL
+88 -1: (ILjava/lang/Object;Ljava/lang/Object;)Ljava/util/concurrent/ConcurrentHashMap$TreeNode;
+130 -1: (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+14 -1: aliases_IBM437
+10 -1: iso-ir-144
+10 -1: iso-ir-148
+35 -1: ()Ljava/nio/charset/CharsetDecoder;
+95 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;
+16 -1: UnmodifiableList
+40 -1: ()Ljava/util/concurrent/locks/Condition;
+9 -1: Path.java
+80 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/util/Map;
+36 -1: Ljava/lang/Class<Ljava/lang/Float;>;
+124 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;)Ljava/lang/Object;
+20 -1: privateGetParameters
+24 -1: sun/nio/cs/StreamDecoder
+12 -1: getFreeSpace
+8 -1: US-ASCII
+22 -1: negativeZeroDoubleBits
+9 -1: putObject
+13 -1: linkToVirtual
+35 -1: Ljava/lang/Class<Ljava/lang/Long;>;
+15 -1: detectedCharset
+26 -1: java/lang/reflect/Modifier
+22 -1: JAVAFX_LAUNCH_MODE_JAR
+32 -1: java/net/URLStreamHandlerFactory
+7 -1: IBM-923
+80 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/String;
+13 -1: TRANSFERINDEX
+34 -1: (Lsun/nio/cs/StandardCharsets$1;)V
+23 -1: ()Ljava/io/InputStream;
+16 -1: ()Ljava/io/File;
+41 -1: (Ljava/lang/String;)Ljava/nio/ByteBuffer;
+22 -1: sun/reflect/Reflection
+23 -1: java/lang/AutoCloseable
+25 -1: BootstrapMethodError.java
+19 -1: EnclosingMethodInfo
+13 -1: transferIndex
+18 -1: java/lang/Compiler
+4 -1: zero
+29 -1: java/util/Arrays$NaturalOrder
+9 -1: language=
+37 -1: Ljava/util/ArrayList<Ljava/net/URL;>;
+73 -1: ()Ljava/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject;
+16 -1: balanceInsertion
+82 -1: (Ljava/lang/StringBuffer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+11 -1: asIntBuffer
+27 -1: (Ljava/util/LinkedList;II)V
+13 -1: ofEpochSecond
+19 -1: sunjce_provider.jar
+21 -1: (F)Ljava/lang/String;
+32 -1:  >> does not contain binding << 
+21 -1: declaredPublicMethods
+5 -1: FIELD
+17 -1: getPrimitiveClass
+127 -1: (Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl;Ljava/lang/Class;Ljava/lang/String;)V
+21 -1: replaceParameterTypes
+73 -1: Ljava/util/Map<Ljava/lang/Class<*>;Ljava/security/PermissionCollection;>;
+21 -1: (Ljava/lang/Double;)I
+5 -1: floor
+4 -1: halt
+14 -1: newConstructor
+48 -1: (Ljava/util/function/BiFunction<-TK;-TV;+TV;>;)V
+17 -1: packageAccessLock
+15 -1: America/Phoenix
+19 -1: Incoming arguments:
+11 -1: V_Monotonic
+14 -1: decrementExact
+15 -1: updatePositions
+14 -1: toLocaleString
+12 -1: appendEscape
+7 -1: DISPLAY
+27 -1: sun/nio/cs/US_ASCII$Decoder
+13 -1: LITTLE_ENDIAN
+6 -1: isNull
+13 -1: TempDirectory
+6 -1: LM_JAR
+39 -1: JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
+10 -1: isCompiled
+36 -1: (Ljava/lang/AbstractStringBuilder;)Z
+3 -1: run
+17 -1: START_PUNCTUATION
+33 -1: Ljava/util/Stack<Ljava/net/URL;>;
+49 -1: (Ljava/lang/String;)Ljava/lang/invoke/LambdaForm;
+28 -1: java/security/DomainCombiner
+53 -1: (Ljava/lang/String;Ljava/util/Map;)Ljava/time/ZoneId;
+81 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/Class;)[Ljava/lang/reflect/AnnotatedType;
+43 -1: java/lang/management/GarbageCollectorMXBean
+11 -1: toTitleCase
+12 -1: getHoldCount
+4 -1: ()[B
+4 -1: ()[C
+4 -1: ()[J
+20 -1: (Ljava/io/File;IZZ)Z
+18 -1: fileTimeToUnixTime
+23 -1: java/nio/HeapCharBuffer
+30 -1: Ljava/lang/ref/ReferenceQueue;
+6 -1: rt.jar
+69 -1: (Ljava/util/function/ToIntFunction<-TT;>;)Ljava/util/Comparator<TT;>;
+21 -1: java/lang/ThreadLocal
+25 -1: Ljava/lang/reflect/Field;
+44 -1: (Ljava/lang/String;Ljava/lang/Throwable;ZZ)V
+93 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/MethodHandle;
+22 -1: getDayOfWeekDateBefore
+37 -1: [Lsun/reflect/generics/tree/TypeTree;
+83 -1: <E:Ljava/lang/Object;>(Ljava/util/Map<TE;Ljava/lang/Boolean;>;)Ljava/util/Set<TE;>;
+10 -1: readFields
+42 -1: (Ljava/net/URL;)Ljava/security/CodeSource;
+44 -1: (Ljava/lang/String;IIJ)Ljava/nio/ByteBuffer;
+27 -1: Ljava/util/Collection<TE;>;
+13 -1: checkResource
+7 -1: rename0
+51 -1: (C)Ljava/lang/invoke/BoundMethodHandle$SpeciesData;
+47 -1: sun/reflect/generics/repository/FieldRepository
+11 -1: readBoolean
+134 -1: (ILjava/lang/Object;Ljava/lang/Object;Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$TreeNode;)V
+13 -1: getZoneOffset
+17 -1: getJdkVersionInfo
+21 -1: sun/misc/MessageUtils
+23 -1: defaultAllowArraySyntax
+31 -1: java/util/concurrent/locks/Lock
+24 -1: java/lang/reflect/Method
+7 -1: toUpper
+17 -1: sun/misc/Signal$1
+51 -1: (JLjava/util/function/BiFunction<-TK;-TK;+TK;>;)TK;
+28 -1: (Ljava/lang/ref/Reference;)Z
+8 -1: nthreads
+26 -1: MapReduceEntriesToLongTask
+27 -1: (Ljava/util/NavigableSet;)V
+10 -1: savedProps
+25 -1: Lsun/security/util/Debug;
+12 -1: CR_MALFORMED
+13 -1: com.sun.proxy
+17 -1: CharSequence.java
+24 -1: (ILjava/lang/String;II)Z
+13 -1: findNextValue
+108 -1: <K::Ljava/lang/Comparable<-TK;>;V:Ljava/lang/Object;>()Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
+5 -1: (FF)F
+9 -1: typeClass
+5 -1: (FF)I
+11 -1: segmentMask
+7 -1: (JJJJ)V
+14 -1: aliases_CESU_8
+85 -1: (Ljava/lang/Class;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/DirectMethodHandle;
+15 -1: getCalendarDate
+21 -1: getDeclaredAnnotation
+8 -1: ([BIIB)I
+15 -1: stripExtensions
+14 -1: getISO3Country
+5 -1: short
+47 -1: String value %s exceeds range of unsigned long.
+34 -1: ()Ljava/security/ProtectionDomain;
+8 -1: ([BIIB)V
+23 -1: (Ljava/lang/Object;ID)V
+47 -1: (Ljava/lang/String;Ljava/nio/charset/Charset;)V
+29 -1: RuntimeVisibleTypeAnnotations
+24 -1: (Ljava/io/InputStream;)V
+39 -1: (Ljava/lang/Class;Ljava/lang/String;Z)V
+16 -1: convertPrimitive
+8 -1: (TK;)TV;
+24 -1: (Ljava/io/InputStream;)Z
+6 -1: start 
+243 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceEntriesToLongTask;Ljava/util/function/ToLongFunction;JLjava/util/function/LongBinaryOperator;)V
+9 -1: asSpecial
+20 -1: java/text/Normalizer
+17 -1: DAYS_0000_TO_1970
+9 -1: toCharset
+20 -1: REPLACEALL_THRESHOLD
+20 -1: sun/net/util/URLUtil
+16 -1: findLoadedClass0
+14 -1: localedata.jar
+6 -1: Parser
+6 -1: start0
+4 -1: hash
+83 -1: (Ljava/lang/Class;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+29 -1: Ljava/lang/invoke/MemberName;
+8 -1: BOOT_TAG
+22 -1: MH_LINKER_ARG_APPENDED
+14 -1: comparingByKey
+47 -1: ([Ljava/lang/String;)Ljava/lang/ProcessBuilder;
+6 -1: start=
+18 -1: StringBuilder.java
+7 -1: getLong
+12 -1: copyElements
+16 -1: highResFrequency
+11 -1: toGMTString
+10 -1: ISO_8859_1
+10 -1: ISO_8859_2
+6 -1: result
+10 -1: ISO_8859_4
+10 -1: ISO_8859_5
+10 -1: ISO_8859_7
+15 -1: unmodifiableSet
+10 -1: ISO_8859_9
+25 -1: NoClassDefFoundError.java
+42 -1: (Ljava/lang/String;)Ljava/util/LinkedList;
+14 -1: parallelPrefix
+22 -1: ARRAY_LONG_INDEX_SCALE
+6 -1: resume
+36 -1: Ljava/lang/invoke/LambdaForm$Hidden;
+50 -1: java/util/Collections$UnmodifiableRandomAccessList
+130 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/function/Consumer;)V
+6 -1: getInt
+13 -1: getCachedYear
+21 -1: CONNECTOR_PUNCTUATION
+73 -1: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;ILjava/lang/Class;)V
+24 -1: [Lsun/util/calendar/Era;
+22 -1: (Ljava/lang/Object;D)V
+74 -1: (Ljava/security/AccessControlContext;)Ljava/security/AccessControlContext;
+109 -1: <T:Ljava/lang/Object;>(Ljava/lang/Class<*>;Ljava/lang/Class$AnnotationData;Ljava/lang/Class$AnnotationData;)Z
+6 -1: ([CZ)V
+74 -1: (Ljava/util/HashMap$Node;Ljava/util/HashMap$Node;)Ljava/util/HashMap$Node;
+19 -1: TRADITIONAL_CHINESE
+125 -1: (Ljava/lang/Throwable$PrintStreamOrWriter;[Ljava/lang/StackTraceElement;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
+18 -1: unknown protocol: 
+57 -1: (Ljava/lang/reflect/Method;Lsun/reflect/MethodAccessor;)V
+13 -1: writeComments
+9 -1: Negotiate
+14 -1: Closeable.java
+10 -1: asSpreader
+122 -1: (Ljava/nio/file/WatchService;[Ljava/nio/file/WatchEvent$Kind;[Ljava/nio/file/WatchEvent$Modifier;)Ljava/nio/file/WatchKey;
+17 -1: jvm_minor_version
+9 -1: getDouble
+25 -1: Ljava/io/File$PathStatus;
+19 -1: averageCharsPerByte
+22 -1: getConstructorAccessor
+61 -1: (Ljava/lang/String;)Ljava/lang/management/MemoryManagerMBean;
+45 -1: (Ljava/lang/String;)Ljava/util/regex/Pattern;
+25 -1: (JC)Ljava/nio/ByteBuffer;
+20 -1: exclusiveOwnerThread
+85 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue<TT;>;Ljava/lang/ClassValue$Entry<TT;>;)V
+17 -1: getExtensionValue
+14 -1: getLoadAverage
+17 -1: GET_PD_PERMISSION
+6 -1: METHOD
+23 -1: sun/nio/cs/ISO_8859_1$1
+23 -1: (I[Ljava/lang/Object;)I
+4 1: zzz1
+13 -1: createWrapper
+4 1: zzz2
+4 1: zzz3
+33 -1:  greater than Character.MAX_RADIX
+37 -1: DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+6 -1: BRIDGE
+20 -1: canonicalizeLanguage
+13 -1: setPermission
+46 -1: (Ljava/io/OutputStream;)Ljava/io/OutputStream;
+3 -1: 646
+14 -1: java/lang/Long
+55 -1: java/util/concurrent/ConcurrentHashMap$SearchValuesTask
+38 -1: (IC)Ljava/lang/invoke/LambdaForm$Name;
+37 -1: (Ljava/lang/Class;)Ljava/lang/String;
+17 -1: javaUtilJarAccess
+23 -1: registerMethodsToFilter
+34 -1: (Ljava/nio/charset/Charset;[CII)[B
+11 -1: % VERSION 2
+37 -1: ([DI)Ljava/util/Spliterator$OfDouble;
+16 -1:     Stack Size: 
+52 -1: (Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
+17 -1: putDoubleVolatile
+10 -1: access$500
+10 -1: access$502
+28 -1: malformed input around byte 
+13 -1: LF_INVSPECIAL
+32 -1: Non-positive averageCharsPerByte
+14 -1: NF_fieldOffset
+10 -1: access$508
+48 -1: <T:Ljava/lang/Object;>(TT;)Ljava/util/List<TT;>;
+17 -1: defaultReadObject
+17 -1: java/util/TimSort
+13 -1: resolveClass0
+92 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;[Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+20 -1: setLangReflectAccess
+30 -1: java/lang/reflect/TypeVariable
+56 -1: <T:Ljava/lang/Object;>([TT;)Ljava/util/Spliterator<TT;>;
+8 -1: VOLATILE
+10 -1: Big5-HKSCS
+23 -1: (Ljava/util/Locale$1;)V
+15 -1: ISO_8859-1:1987
+14 -1: no such method
+10 -1: null value
+8 -1: checkURL
+22 -1: ARRAY_BYTE_INDEX_SCALE
+27 -1: (Ljava/lang/ClassLoader;Z)V
+22 -1: java/lang/reflect/Type
+25 -1: java/net/JarURLConnection
+36 -1: java/util/WeakHashMap$KeySpliterator
+26 -1: ()Lsun/misc/JavaAWTAccess;
+50 -1: (I[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+9 -1: toDegrees
+12 -1: lowSurrogate
+19 -1: getEnclosingMethod0
+7 -1: bytearr
+35 -1: (Ljava/util/List;Ljava/util/List;)I
+25 -1: [Ljava/lang/reflect/Type;
+34 -1: javaSecurityProtectionDomainAccess
+21 -1: java.launcher.X.usage
+37 -1: sun/util/locale/InternalLocaleBuilder
+33 -1: ()Ljava/lang/invoke/MethodHandle;
+3 -1: scl
+19 -1: synthesizeAllParams
+68 -1: Ljava/util/Map<Ljava/lang/String;[Ljava/security/cert/Certificate;>;
+6 -1: vclass
+35 -1: (Ljava/util/List;Ljava/util/List;)V
+59 -1: Ljava/lang/Number;Ljava/lang/Comparable<Ljava/lang/Float;>;
+13 -1: CallSite.java
+10 1: Bar loaded
+21 -1: ARRAY_INT_BASE_OFFSET
+49 -1: Ljava/util/concurrent/ConcurrentHashMap$TreeNode;
+32 -1: [Ljava/lang/reflect/Constructor;
+4 -1: type
+34 -1: <T:Ljava/lang/Object;>([TT;II)[TT;
+25 -1: BufferedOutputStream.java
+23 -1: java/util/zip/ZipFile$1
+24 -1: ()Ljava/lang/ClassValue;
+50 -1: (Ljava/util/concurrent/CountedCompleter;[F[FIIII)V
+16 -1: getQueuedThreads
+26 -1: getJavaNetHttpCookieAccess
+8 -1: setExtra
+8 -1: implRead
+20 -1: linkMethod => throw 
+76 -1: (Ljava/util/function/ToDoubleFunction;Ljava/lang/Object;Ljava/lang/Object;)I
+11 -1: KeyIterator
+39 -1: Ljava/util/List<Ljava/lang/Throwable;>;
+3 -1: " "
+36 -1: Ljava/lang/IllegalArgumentException;
+11 -1: checkBounds
+30 -1: sun/nio/cs/FastCharsetProvider
+11 -1: toLongArray
+107 -1: (Ljava/lang/Class<*>;Ljava/lang/String;Ljava/lang/Class<*>;IILjava/lang/String;[B)Ljava/lang/reflect/Field;
+8 -1:  (build 
+39 -1: (Ljava/nio/Buffer;ILjava/nio/Buffer;I)V
+31 -1: [Ljava/lang/reflect/Executable;
+3 -1: set
+21 -1: PhantomReference.java
+41 -1: java/util/Collections$CheckedNavigableMap
+53 -1: Can not make a java.lang.Class constructor accessible
+12 -1: ([CII[CIII)I
+55 -1: Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Void;>;
+12 -1: MICROSECONDS
+11 -1: writeBuffer
+52 -1:               and domain that didn't have permission
+37 -1: java/nio/channels/WritableByteChannel
+26 -1: getRawClassTypeAnnotations
+15 -1: putCharVolatile
+33 -1: java/security/InvalidKeyException
+19 -1: Ljava/io/Closeable;
+83 -1: Lsun/util/locale/LocaleObjectCache<Ljava/util/Locale$LocaleKey;Ljava/util/Locale;>;
+10 -1: SetFromMap
+24 -1: JavaFX-Application-Class
+13 -1: asShortBuffer
+10 -1: getReifier
+15 -1: isPositionIndex
+18 -1: SignalHandler.java
+3 -1: JST
+28 -1: (Ljava/io/FileDescriptor;I)I
+28 -1: getStackAccessControlContext
+16 -1: updateByteBuffer
+27 -1: ()Ljava/net/ContentHandler;
+25 -1: (JD)Ljava/nio/ByteBuffer;
+39 -1: ()Lsun/misc/JavaIOFileDescriptorAccess;
+107 -1: (Ljava/lang/ThreadLocal$ThreadLocalMap;Ljava/lang/ThreadLocal;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+42 -1: sun/misc/PerfCounter$WindowsClientCounters
+8 -1: addExact
+28 -1: (Ljava/io/FileDescriptor;I)V
+36 -1: ([Ljava/lang/String;)Ljava/util/Map;
+21 -1: ()Ljava/lang/Process;
+4 -1: UTF8
+5 -1: mkdir
+10 -1: transient 
+3 -1: sgp
+15 -1: balanceDeletion
+161 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/net/URL;)Ljava/lang/Package;
+15 -1: SynchronizedMap
+40 -1: sun.misc.URLClassPath.disableJarChecking
+92 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractSet<TE;>;Ljava/util/Set<TE;>;Ljava/io/Serializable;
+17 -1: removeEldestEntry
+35 -1: (I)Ljava/lang/Class$AnnotationData;
+24 -1: Ljava/util/Locale$Cache;
+13 -1: STANDARD_TIME
+17 -1: sun/nio/cs/MS1252
+99 -1: <K:Ljava/lang/Object;>()Ljava/util/concurrent/ConcurrentHashMap$KeySetView<TK;Ljava/lang/Boolean;>;
+23 -1: java/util/LinkedHashSet
+9 -1: iso8859_1
+9 -1: iso8859_2
+9 -1: iso8859_4
+66 -1: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)[TA;
+9 -1: iso8859_5
+9 -1: iso8859_7
+9 -1: iso8859_9
+21 -1: Ljava/util/Formatter;
+6 -1: isPath
+21 -1: makeReferenceIdentity
+24 -1: sun/net/ApplicationProxy
+23 -1: ClassCastException.java
+11 -1: MethodArray
+12 -1: SingletonMap
+41 -1: java/util/ArrayPrefixHelpers$CumulateTask
+7 -1: seconds
+20 -1: ClassRepository.java
+14 -1: allocateMemory
+24 -1: java.launcher.jar.error1
+24 -1: java.launcher.jar.error2
+24 -1: java.launcher.jar.error3
+45 -1: (Ljava/lang/String;Ljava/util/jar/Manifest;)Z
+3 -1: sin
+7 -1: (J[II)I
+3 -1: Itr
+18 -1: findBootstrapClass
+10 -1: getElement
+15 -1: ISO_8859-4:1988
+34 -1: newGetLongIllegalArgumentException
+7 -1: pending
+17 -1: isNotContinuation
+6 -1: EXTSIG
+13 -1: searchMethods
+32 -1: Lsun/misc/JavaUtilZipFileAccess;
+33 -1: ([Ljava/lang/reflect/Parameter;)V
+31 -1: defaultUncaughtExceptionHandler
+89 -1: (Ljava/nio/file/WatchService;[Ljava/nio/file/WatchEvent$Kind<*>;)Ljava/nio/file/WatchKey;
+5 -1: ASCII
+28 -1: ()Lsun/reflect/ConstantPool;
+20 -1: isJavaIdentifierPart
+6 -1: EXTSIZ
+34 -1: Lsun/misc/JavaNetHttpCookieAccess;
+34 -1: ClassLoader object not initialized
+7 -1: CHECKED
+16 -1: encodeBufferLoop
+37 -1: (Ljava/time/Instant;)Ljava/util/Date;
+24 -1: (Ljava/util/Map$Entry;)Z
+50 -1: java/util/concurrent/ConcurrentHashMap$KeyIterator
+31 -1: ()[Ljava/lang/ClassValue$Entry;
+31 -1: java/lang/IllegalStateException
+43 -1: (Ljava/lang/Appendable;Ljava/util/Locale;)V
+6 -1: CENVEM
+53 -1: Ljava/util/ArrayList<Lsun/misc/URLClassPath$Loader;>;
+17 -1: getHeaderFieldKey
+71 -1: (Ljava/lang/CharSequence;Ljava/text/Normalizer$Form;)Ljava/lang/String;
+6 -1: CENVER
+17 -1: cleanStaleEntries
+9 -1: linkFirst
+57 -1: (Ljava/util/Comparator<-TT;>;)Ljava/util/Comparator<TT;>;
+8 -1: val$file
+27 -1: Invalid parameter modifiers
+6 -1: append
+57 -1: ()Lsun/reflect/generics/repository/ConstructorRepository;
+65 -1: java/util/concurrent/ConcurrentHashMap$MapReduceMappingsToIntTask
+39 -1: (Ljava/lang/String;)Ljava/lang/Integer;
+25 -1: lambda$parallelSetAll$191
+25 -1: lambda$parallelSetAll$192
+25 -1: lambda$parallelSetAll$193
+23 -1: INSERTIONSORT_THRESHOLD
+17 -1: java/time/Instant
+25 -1: lambda$parallelSetAll$194
+14 -1: dynamicInvoker
+9 -1: iso646-us
+8 -1: position
+29 -1: java/nio/channels/FileChannel
+27 -1: java/util/stream/Collectors
+64 -1: (Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;
+10 -1: INDEX_NAME
+15 -1: getCommentBytes
+67 -1: (Ljava/io/FileOutputStream;Ljava/lang/String;)Ljava/io/PrintStream;
+22 -1: privateGetPublicFields
+32 -1: java/util/BitSet$1BitSetIterator
+12 -1: PERF_MODE_RO
+89 -1: ([Ljava/lang/ClassValue$Entry;ILjava/lang/ClassValue$Entry;Z)Ljava/lang/ClassValue$Entry;
+30 -1: java/security/PrivilegedAction
+18 -1: host can't be null
+26 -1: package name can't be null
+12 -1: PERF_MODE_RW
+10 -1: isEnqueued
+18 -1: argSlotToParameter
+37 -1: (II)Ljava/lang/AbstractStringBuilder;
+5 -1: tabAt
+53 -1: (Ljava/lang/Object;)Ljava/lang/AbstractStringBuilder;
+11 -1: PATH_OFFSET
+18 -1: unicodebigunmarked
+15 -1: ConditionObject
+6 -1: KOREAN
+13 -1: isNamePresent
+24 -1: ()Ljava/lang/Class<TE;>;
+14 -1: isStandardTime
+8 -1: ([IIII)I
+9 -1: WeakEntry
+12 -1: javaIOAccess
+17 -1: key can't be null
+129 -1: Ljava/lang/Object;Ljava/lang/Comparable<Ljava/nio/file/Path;>;Ljava/lang/Iterable<Ljava/nio/file/Path;>;Ljava/nio/file/Watchable;
+8 -1:  handler
+8 -1: ([IIII)V
+10 -1: atBugLevel
+18 -1: makeGuardWithCatch
+18 -1: currentLoadedClass
+11 -1: getCodeBase
+67 -1: <T:Ljava/lang/Object;>(Ljava/util/List<+TT;>;)Ljava/util/List<TT;>;
+12 -1: JarFile.java
+19 -1: (C)Ljava/io/Writer;
+22 -1: createURLStreamHandler
+23 -1: sun/nio/cs/ArrayDecoder
+13 -1: setAccessible
+18 -1: stripOffParameters
+101 -1: ([Ljava/security/ProtectionDomain;[Ljava/security/ProtectionDomain;)[Ljava/security/ProtectionDomain;
+18 -1: Ljava/util/Random;
+16 -1: Pacific/Honolulu
+13 -1: useOldMapping
+65 -1: (Ljava/lang/invoke/LambdaForm$NamedFunction;[Ljava/lang/Object;)V
+14 -1: filterArgument
+12 -1: LF_MH_LINKER
+25 -1: isDirectMemoryPageAligned
+49 -1: (Ljava/util/BitSet;)Ljava/util/function/Supplier;
+54 -1: (Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;TV;)V
+16 -1: java/time/ZoneId
+4 -1: zfot
+18 -1: isSameClassPackage
+6 -1: julian
+8 -1: (TT;)TT;
+22 -1: java/util/jar/Manifest
+7 -1: charOut
+16 -1: getOffsetsByWall
+19 -1: Illegal replacement
+139 -1: <E:Ljava/lang/Object;>Ljava/util/AbstractList<TE;>;Ljava/util/List<TE;>;Ljava/util/RandomAccess;Ljava/lang/Cloneable;Ljava/io/Serializable;
+96 -1: <T:Ljava/lang/Object;>(Ljava/lang/reflect/Constructor<TT;>;)Ljava/lang/reflect/Constructor<TT;>;
+15 -1: Annotation.java
+24 -1: (Ljava/lang/Class<*>;)[B
+6 -1: CODING
+34 -1: ([Ljava/lang/ClassValue$Entry;II)V
+6 -1: IGNORE
+62 -1: (Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
+29 -1: specificToGenericStringHeader
+12 -1: helpTransfer
+8 -1: fastTime
+62 -1: (Ljava/net/URLConnection;[Ljava/lang/Class;)Ljava/lang/Object;
+18 -1: Unhandled signal: 
+8 -1: isStrict
+15 -1: ISO_8859-7:1987
+13 -1: getWeekLength
+14 -1: jvmBuildNumber
+40 -1: (Ljava/lang/String;)Ljava/util/Iterator;
+6 -1: short0
+6 -1: short1
+73 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedExceptionAction<TT;>;)TT;
+10 -1: removeNode
+8 -1: setFloat
+18 -1: cspc862latinhebrew
+11 -1: setTimeZone
+34 -1: java/lang/reflect/AccessibleObject
+25 -1: MapReduceKeysToDoubleTask
+25 -1: java/lang/ref/Reference$1
+24 -1: java/nio/HeapByteBufferR
+15 -1: jdkMicroVersion
+117 -1: (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/Class;[Ljava/lang/Class;IILjava/lang/String;[B[B[B)V
+8 -1: (TT;)TV;
+16 -1: Permissions.java
+22 -1: Ljava/util/Comparator;
+17 -1: getDaylightSaving
+25 -1: ([BIILjava/lang/String;)V
+9 -1: stillborn
+11 -1: maxPosition
+28 -1: java/util/ArrayPrefixHelpers
+73 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>()Ljava/util/SortedMap<TK;TV;>;
+14 -1: useCanonCaches
+5 -1: clean
+16 -1: checkPermission2
+34 -1: sun.misc.launcher.useSharedArchive
+13 -1: shutdownHooks
+5 -1: clear
+240 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$MapReduceKeysToLongTask;Ljava/util/function/ToLongFunction;JLjava/util/function/LongBinaryOperator;)V
+67 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<-TV;+TU;>;)TU;
+6 -1: cp1250
+6 -1: cp1251
+6 -1: cp1252
+13 -1: getZipMessage
+6 -1: cp1253
+28 -1: (J)Ljava/lang/ref/Reference;
+6 -1: cp1254
+54 -1: (ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;
+6 -1: cp1257
+10 -1: deepEquals
+17 -1: WRITE_BUFFER_SIZE
+13 -1: copyFromArray
+40 -1: java/util/Collections$ReverseComparator2
+36 -1: sun/reflect/generics/visitor/Reifier
+19 -1: averageBytesPerChar
+13 -1: javaAWTAccess
+6 -1: cp5346
+61 -1: Ljava/util/Map<Ljava/lang/String;Ljava/nio/charset/Charset;>;
+6 -1: cp5347
+6 -1: cp5348
+6 -1: cp5349
+5 -1: field
+23 -1: ()Ljava/nio/LongBuffer;
+103 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/WrongMethodTypeException;
+37 -1: (I)Ljava/lang/Character$UnicodeBlock;
+11 -1: offsetAfter
+79 -1: Ljava/util/HashMap<Ljava/security/CodeSource;Ljava/security/ProtectionDomain;>;
+27 -1: invocationHandlerReturnType
+17 -1: POSITIVE_INFINITY
+11 -1: maybeRebind
+3 -1: str
+18 -1: setSecurityManager
+9 -1: signature
+18 -1: corrupted jar file
+89 -1: <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;Ljava/io/Serializable;
+87 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+6 -1: CENATT
+6 -1: cp5350
+12 -1: AF_GETSTATIC
+38 -1: (TE;Ljava/util/LinkedList$Node<TE;>;)V
+8 -1: isLoaded
+6 -1: CENATX
+6 -1: cp5353
+18 -1: Africa/Addis_Ababa
+35 -1: sun/usagetracker/UsageTrackerClient
+11 -1: toUpperCase
+22 -1: java/util/zip/Inflater
+10 -1: iso_8859-1
+10 -1: iso_8859-2
+3 -1: sum
+7 -1: x-Johab
+10 -1: iso_8859-4
+10 -1: iso_8859-5
+85 -1: (Ljava/security/DomainCombiner;Ljava/lang/Class;)Ljava/security/AccessControlContext;
+11 -1: activeCount
+49 -1: (Ljava/lang/ClassLoader;Ljava/lang/ClassLoader;)Z
+51 -1: (Ljava/util/List;Ljava/lang/Class;)Ljava/util/List;
+10 -1: iso_8859-7
+19 -1: appendVmErgoMessage
+10 -1: iso_8859-9
+14 -1: getClassLoader
+6 -1: (CJJ)Z
+15 -1: Lsun/misc/Perf;
+7 -1: getTree
+27 -1: Ljava/text/Normalizer$Form;
+11 -1: ISO-2022-JP
+69 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;)Ljava/lang/Object;
+50 -1: java/lang/invoke/DirectMethodHandle$StaticAccessor
+15 -1: fxLauncherClass
+35 -1: (Ljava/net/URL;Ljava/lang/String;)V
+16 -1: getAndAccumulate
+35 -1: (Ljava/net/URL;Ljava/lang/String;)Z
+32 -1: Non-positive averageBytesPerChar
+35 -1: Ljava/lang/Class<Ljava/lang/Void;>;
+15 -1: CLASS_MODIFIERS
+12 -1: checkedQueue
+13 -1: enumConstants
+10 -1: getFactory
+95 -1: Ljava/util/concurrent/ConcurrentMap<TK;Lsun/util/locale/LocaleObjectCache$CacheEntry<TK;TV;>;>;
+13 -1: Africa/Harare
+57 -1: (JLjava/util/TimeZone;)Lsun/util/calendar/Gregorian$Date;
+11 -1: ISO-2022-KR
+19 -1: $assertionsDisabled
+13 -1: PROXY_PACKAGE
+17 -1: copyFromLongArray
+81 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/LinkedHashMap$Entry<TK;TV;>;
+11 -1: checkDelete
+38 -1: sun/management/ManagementFactoryHelper
+7 -1: UTC1900
+20 -1: getBootstrapResource
+23 -1: ()Ljava/lang/Throwable;
+16 -1: CALLER_SENSITIVE
+26 -1: checkSystemClipboardAccess
+32 -1: Can't set default locale to NULL
+16 -1: fxLauncherMethod
+4 -1:  >= 
+8 -1: provider
+9 -1: Finalizer
+78 -1: (Ljava/io/FileDescriptor;ZZZLjava/lang/Object;)Ljava/nio/channels/FileChannel;
+13 -1: emptyIterator
+15 -1: getZipFileCount
+21 -1: isJavaIdentifierStart
+9 -1: connected
+11 -1: (ITK;TV;I)V
+16 -1: America/Honolulu
+22 -1: SynchronizedCollection
+28 -1: java/util/zip/ZipConstants64
+29 -1: inheritedAccessControlContext
+29 -1: ()[Ljava/security/CodeSigner;
+85 -1: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/sun/management/GcInfo;)V
+25 -1: (Ljava/nio/CharBuffer;Z)V
+15 -1: java/io/Console
+101 -1: (Ljava/lang/Class<*>;Lsun/reflect/annotation/AnnotationType;Lsun/reflect/annotation/AnnotationType;)Z
+9 -1: | resolve
+81 -1: (BLjava/lang/invoke/MemberName;Ljava/lang/Class<*>;)Ljava/lang/invoke/MemberName;
+33 -1: (Ljava/nio/charset/Charset;FF[B)V
+49 -1: (Ljava/lang/Class;Z)Ljava/lang/invoke/MethodType;
+66 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
+29 -1: ([Ljava/util/HashMap$Node;I)V
+13 -1: filterMethods
+4 -1: jcal
+61 -1: (Ljava/util/List<Ljava/lang/Class<*>;>;)[Ljava/lang/Class<*>;
+6 -1: which=
+46 -1: (Ljava/math/BigInteger;)Ljava/math/BigInteger;
+4 -1: date
+18 -1: internalMemberName
+6 -1: (JJI)Z
+30 -1: [Ljava/lang/invoke/LambdaForm;
+60 -1: <T:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;
+15 -1: ReservationNode
+42 -1: java/lang/ThreadLocal$ThreadLocalMap$Entry
+6 -1: setIn0
+4 -1: sort
+8 -1: ibm00858
+110 -1: (Ljava/lang/String;Ljava/nio/ByteBuffer;IILjava/security/ProtectionDomain;Ljava/lang/String;)Ljava/lang/Class;
+28 -1: Ljava/lang/ClassValue$Entry;
+22 -1: ensureExplicitCapacity
+6 -1: rotate
+14 -1: closeRequested
+30 -1: ([CII)Ljava/lang/StringBuffer;
+10 -1: LM_UNKNOWN
+15 -1: Comparable.java
+13 -1: getByteBuffer
+9 -1: getScheme
+15 -1: done with meta!
+17 -1: checkForTypeAlias
+7 -1: getKeys
+7 -1: SIG_DFL
+30 -1: Ljava/nio/charset/CoderResult;
+16 -1: returnTypesMatch
+19 -1: getClassAccessFlags
+18 -1: JavaNioAccess.java
+9 -1: setDouble
+23 -1: Ljava/util/zip/ZipFile;
+83 -1: (JLjava/util/function/ToIntFunction<-TK;>;ILjava/util/function/IntBinaryOperator;)I
+11 -1: ACCESS_READ
+15 -1: nativeByteOrder
+5 -1: hours
+7 -1: toArray
+7 -1: Encoder
+12 -1: resolveClass
+29 -1: (Ljava/io/FileDescriptor;JJ)V
+14 -1: redefinedCount
+8 -1: getTotal
+11 -1: iso_8859-13
+11 -1: iso_8859-15
+9 -1: expected 
+18 -1: getDeclaredMethods
+11 -1: elementData
+6 -1: intern
+10 -1: countryKey
+6 -1: setInt
+39 -1: Could not create extension class loader
+24 -1: SELF_SUPPRESSION_MESSAGE
+14 -1: argToSlotTable
+42 -1: Ljava/util/HashMap<TE;Ljava/lang/Object;>;
+5 -1:  \t\n\r\x0c
+4 -1: read
+12 -1: Objects.java
+7 -1: aliases
+29 -1: sun/reflect/LangReflectAccess
+6 -1: prefix
+15 -1: superInterfaces
+10 -1: getDoInput
+30 -1: java/nio/CharBufferSpliterator
+6 -1: KOI8_R
+12 -1: Asia/Kolkata
+6 -1: KOI8_U
+6 -1: LOCSIG
+15 -1: UA-Java-Version
+92 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/HashMap<TK;TV;>;Ljava/util/Map<TK;TV;>;
+14 -1: CertificateRep
+17 -1: getSystemResource
+85 -1: (JLjava/util/function/ToLongFunction<-TV;>;JLjava/util/function/LongBinaryOperator;)J
+27 -1: java/lang/reflect/Parameter
+5 -1: quote
+8 -1: not MH: 
+46 -1: java/util/Collections$UnmodifiableCollection$1
+6 -1: putVal
+6 -1: LOCSIZ
+6 -1: Atomic
+3 -1: 737
+38 -1: java/lang/UnsupportedClassVersionError
+27 -1: ()Ljava/lang/StringBuilder;
+41 -1: sun/net/www/protocol/jar/JarURLConnection
+60 -1: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;
+59 -1: <T:Ljava/lang/Object;>(TT;TT;Ljava/util/Comparator<-TT;>;)I
+54 -1: java/util/concurrent/locks/AbstractOwnableSynchronizer
+7 -1: getHost
+36 -1: (F)Ljava/lang/AbstractStringBuilder;
+69 -1: <U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)Ljava/lang/Class<+TU;>;
+4 -1: Form
+103 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/SortedMap<TK;+TV;>;)Ljava/util/SortedMap<TK;TV;>;
+6 -1: spread
+8 -1: addHours
+13 -1: contentEquals
+47 -1: (Ljava/lang/String;Ljava/security/Permission;)V
+12 -1: newCondition
+23 -1: (Ljava/lang/Object;IZ)V
+26 -1: (Ljava/util/LinkedList;I)V
+13 -1: ConstantValue
+18 -1: URLConnection.java
+12 -1: Boolean.java
+75 -1: ([Ljava/net/URL;Ljava/lang/ClassLoader;Ljava/net/URLStreamHandlerFactory;)V
+21 -1: EMPTY_THROWABLE_ARRAY
+153 -1: (Ljava/util/Map<Ljava/lang/Class<*>;[Ljava/lang/String;>;Ljava/lang/Class<*>;[Ljava/lang/String;)Ljava/util/Map<Ljava/lang/Class<*>;[Ljava/lang/String;>;
+18 -1: getUnresolvedCerts
+13 -1: Negative time
+28 -1: java/util/WeakHashMap$KeySet
+8 -1: slashify
+16 -1: isOtherLowercase
+17 -1: putObjectVolatile
+5 -1: ERASE
+12 -1: filterFields
+40 -1: Ljava/lang/ReflectiveOperationException;
+12 -1: VM settings:
+57 -1: (ILjava/lang/Object;)Ljava/util/HashMap$TreeNode<TK;TV;>;
+10 -1: access$600
+11 -1: ] return =>
+13 -1: user.timezone
+23 -1: USER_AGENT_JAVA_VERSION
+27 -1: (Ljava/util/HashMap$Node;)V
+19 -1: filterNTLMResponses
+28 -1: (Lsun/misc/VMNotification;)V
+37 -1: ()[[Ljava/lang/annotation/Annotation;
+45 -1: ()Lcom/sun/management/DiagnosticCommandMBean;
+3 -1: tan
+31 -1: getDirectlyAndIndirectlyPresent
+7 -1: prepend
+35 -1: (I)Lsun/util/calendar/CalendarDate;
+8 -1: val$dirs
+4 -1: test
+28 -1: Non-positive maxCharsPerByte
+83 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Map<TK;TV;>;
+12 -1: JAVA_VERSION
+24 -1: ([Ljava/lang/Thread;IZ)I
+70 -1: (Ljava/lang/invoke/LambdaForm$Name;)Ljava/lang/invoke/LambdaForm$Name;
+57 -1: <T:Ljava/lang/Object;>([TT;Ljava/util/Comparator<-TT;>;)V
+42 -1: (Ljava/lang/Class<*>;[I)Ljava/lang/Object;
+27 -1: java/lang/SecurityManager$1
+32 -1: java/security/SignatureException
+27 -1: java/lang/SecurityManager$2
+4 -1: .jar
+20 -1: parameterAnnotations
+31 -1: DIRECTIONALITY_BOUNDARY_NEUTRAL
+21 -1: hasClassPathAttribute
+17 -1: checkParentAccess
+35 -1: java/security/PermissionsEnumerator
+6 -1: FORMAT
+92 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<Ljava/util/Map$Entry<TK;TV;>;+TU;>;)TU;
+3 -1: 775
+11 -1: PROBE_LIMIT
+111 -1: (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;
+11 -1: AF_PUTFIELD
+22 -1: (Ljava/lang/Object;Z)V
+20 -1: getGenericReturnType
+9 -1: val$extcl
+13 -1: inClassLoader
+37 -1: sun.urlClassLoader.readClassBytesTime
+35 -1: (JLjava/util/function/BiConsumer;)V
+28 -1: getContentHandlerPkgPrefixes
+10 -1: getChannel
+78 -1: <T:Ljava/lang/Object;>(Ljava/util/List<+TT;>;TT;Ljava/util/Comparator<-TT;>;)I
+16 -1: parseMemberValue
+4 -1: regn
+47 -1: ([Ljava/lang/Object;III)Ljava/util/Spliterator;
+11 -1:  but found 
+6 -1: adjust
+11 -1: isLowerCase
+29 -1: sun/reflect/ReflectionFactory
+98 -1: <E:Ljava/lang/Object;>(Ljava/util/SortedSet<TE;>;Ljava/lang/Class<TE;>;)Ljava/util/SortedSet<TE;>;
+18 -1: [Ljava/lang/Error;
+5 -1: entry
+14 -1: refreshVersion
+8 -1: (IIIII)V
+22 -1: unmodifiableCollection
+6 -1: putAll
+22 -1: offsetByCodePointsImpl
+26 -1: (Ljava/lang/String;[BII)[C
+46 -1: (Ljava/net/URLClassLoader;Ljava/lang/String;)V
+4 -1: /LF=
+9 -1: Bits.java
+30 -1: [Ljava/util/WeakHashMap$Entry;
+19 -1: getLastModifiedTime
+44 -1: [Ljava/lang/Thread$UncaughtExceptionHandler;
+11 -1: getZoneInfo
+6 -1: lookup
+19 -1: MapReduceValuesTask
+18 -1: isVarargsCollector
+38 -1: java/util/jar/JarFile$JarEntryIterator
+11 -1: getJarIndex
+9 -1: getByName
+42 -1: (Ljava/lang/Object;JLjava/lang/Object;JJ)V
+71 -1: (Ljava/lang/invoke/LambdaForm$Name;I)Ljava/lang/invoke/LambdaForm$Name;
+30 -1: java/net/ContentHandlerFactory
+54 -1: (Ljava/lang/Class<*>;I)Ljava/lang/invoke/MethodHandle;
+12 -1: getSignature
+9 -1: parseLong
+25 -1: DEBUG_METHOD_HANDLE_NAMES
+15 -1: runFinalization
+13 -1: 0000000000000
+28 -1: ()[Ljava/lang/reflect/Field;
+37 -1: ([Ljava/lang/ClassValue$Entry<*>;II)V
+13 -1: gcInfoBuilder
+64 -1: (JLjava/util/function/BiFunction;Ljava/util/function/Consumer;)V
+5 -1: cnfe1
+8 -1: setShort
+28 -1: (C)Ljava/lang/StringBuilder;
+44 -1: (Ljava/nio/LongBuffer;)Ljava/nio/LongBuffer;
+70 -1: (Ljava/lang/String;[BIILjava/security/CodeSource;)Ljava/lang/Class<*>;
+33 -1: java/lang/TypeNotPresentException
+5 -1: \n    
+20 -1: acquireInterruptibly
+21 -1: (I)Ljava/lang/String;
+24 -1: (Ljava/io/PrintWriter;)V
+16 -1: convertArguments
+32 -1: Ljava/net/MalformedURLException;
+15 -1: linkToInterface
+39 -1: java/lang/Throwable$PrintStreamOrWriter
+10 -1: iso8859_13
+13 -1: hasPrimitives
+10 -1: iso8859_15
+145 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Class<*>;)Ljava/lang/invoke/CallSite;
+8 -1: equalPDs
+28 -1: (Ljava/io/FileDescriptor;J)V
+7 -1: newLine
+43 -1: (Ljava/lang/Class<*>;I)Ljava/lang/Class<*>;
+8 -1: addEntry
+30 -1: java/util/WeakHashMap$EntrySet
+14 -1: USE_OLDMAPPING
+39 -1: (Ljava/io/DataInput;)Ljava/lang/String;
+12 -1: LF_EX_LINKER
+27 -1: java/lang/invoke/MethodType
+23 -1: JavaSecurityAccess.java
+23 -1: isLocalOrAnonymousClass
+19 -1: Expanded arguments:
+18 -1: sun/nio/cs/Unicode
+40 -1: ()Ljava/nio/charset/spi/CharsetProvider;
+23 -1: ([BLjava/lang/String;)V
+7 -1: default
+13 -1: highestOneBit
+9 -1: isDefault
+28 -1: (IF)Ljava/lang/StringBuffer;
+31 -1: ()Ljava/util/ListIterator<TE;>;
+4 -1: base
+23 -1: newPermissionCollection
+7 -1: version
+15 -1: Permission.java
+41 -1: java/lang/invoke/LambdaForm$NamedFunction
+8 -1: isQueued
+24 -1: ([Ljava/lang/Class<*>;)I
+64 -1: java/util/concurrent/ConcurrentHashMap$MapReduceEntriesToIntTask
+16 -1: checkInitialized
+37 -1: java/lang/ClassLoader$ParallelLoaders
+5 -1: ([B)I
+23 -1: Lsun/misc/URLClassPath;
+9 -1: usr_paths
+10 -1: Queue.java
+43 -1: (Ljava/io/File;Ljava/nio/charset/Charset;)V
+64 -1: (Ljava/lang/invoke/MethodTypeForm;)Ljava/lang/invoke/MemberName;
+3 -1: tid
+23 -1: JarIndex-Version: 1.0\n\n
+33 -1: (I)Ljava/nio/charset/CoderResult;
+5 -1: ([B)V
+10 -1: isInstance
+25 -1: unmappableCharacterAction
+11 -1: queueLength
+5 -1: ([B)Z
+10 -1: freeMemory
+47 -1: java/util/ArrayPrefixHelpers$DoubleCumulateTask
+52 -1: (Ljava/util/Map;Ljava/lang/Class;Ljava/lang/Class;)V
+41 -1: Ljava/util/Collections$ReverseComparator;
+16 -1: copyToShortArray
+206 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>([Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;ILjava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;)Z
+38 -1: sun/launcher/LauncherHelper$SizePrefix
+17 -1: ACCESS_PERMISSION
+17 -1: ReverseComparator
+30 -1: ()Ljava/lang/ClassValue$Entry;
+17 -1: AF_PUTSTATIC_INIT
+6 -1: (IIB)I
+19 -1: java/nio/file/Files
+35 -1: (Z)[Ljava/lang/reflect/Constructor;
+20 -1: INVALID_FIELD_OFFSET
+17 -1: initializeHeaders
+10 -1: management
+10 -1: targetType
+61 -1: (Ljava/util/SortedSet;Ljava/lang/Class;)Ljava/util/SortedSet;
+5 -1: ascii
+8 -1: validate
+78 -1: Ljava/util/concurrent/ConcurrentHashMap<Ljava/lang/String;Ljava/lang/Object;>;
+25 -1: sun/nio/cs/UTF_16$Decoder
+36 -1: sun/management/DiagnosticCommandImpl
+24 -1: unmodifiableNavigableMap
+18 -1: canonicalizeScript
+29 -1: Lsun/misc/JavaSecurityAccess;
+74 -1: ([JLjava/util/function/IntToLongFunction;)Ljava/util/function/IntConsumer;
+38 -1: DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+11 -1: languageTag
+33 -1: java/lang/invoke/VolatileCallSite
+18 -1: setRequestProperty
+6 -1: 0x%02X
+20 -1: (Ljava/lang/Float;)I
+35 -1: (Ljava/nio/charset/CoderResult$1;)V
+24 -1: (Ljava/lang/Object;JJB)V
+21 -1: synchronizedSortedSet
+59 -1: (Ljava/util/function/ToLongFunction;)Ljava/util/Comparator;
+30 -1: av.length == arity: av.length=
+7 -1: $VALUES
+27 -1: RandomNumberGeneratorHolder
+3 -1: tlr
+43 -1: java/util/ArraysParallelSortHelpers$FJFloat
+28 -1: ()[Ljava/io/File$PathStatus;
+26 -1: invalid extra field length
+13 -1: getExtensions
+7 -1: PARAMS0
+7 -1: PARAMS1
+30 -1: [Ljava/lang/invoke/MemberName;
+7 -1: PARAMS2
+31 -1: java/lang/AbstractStringBuilder
+161 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/function/BiFunction;Ljava/util/function/Consumer;)V
+4 -1: repl
+19 -1: ()Ljava/lang/Class;
+24 -1: BufferedInputStream.java
+9 -1: sizeCache
+8 -1: READLINK
+9 -1: metaIndex
+18 -1: getLocalizedObject
+6 -1: filter
+58 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+140 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;
+24 -1: Ljava/util/HashMap$Node;
+35 -1: (Lsun/nio/cs/FastCharsetProvider;)V
+8 -1: dispatch
+19 -1: sun.stderr.encoding
+130 -1: (Ljava/util/List<Ljava/util/Locale$LanguageRange;>;Ljava/util/Collection<Ljava/lang/String;>;)Ljava/util/List<Ljava/lang/String;>;
+51 -1: Ljava/util/concurrent/ConcurrentHashMap$ValuesView;
+30 -1: sun.reflect.inflationThreshold
+20 -1: MutableCallSite.java
+26 -1: invokeWithArgumentsTracing
+7 -1: getters
+38 -1: ()[Ljava/lang/reflect/TypeVariable<*>;
+46 -1: ([DLjava/util/function/DoubleBinaryOperator;)V
+5 -1: klass
+13 -1: publicMethods
+37 -1: ()[Ljava/lang/reflect/Constructor<*>;
+126 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;
+6 -1: FJLong
+20 -1: canBeStaticallyBound
+17 -1: getTimezoneOffset
+9 -1: ALL_TYPES
+3 -1: toV
+8 -1: packages
+15 -1: codePointBefore
+10 -1: getCountry
+13 -1: getDSTSavings
+100 -1: (Ljava/io/InputStream;Ljava/lang/Object;Ljava/nio/charset/CharsetDecoder;)Lsun/nio/cs/StreamDecoder;
+50 -1: java/util/ArraysParallelSortHelpers$FJFloat$Sorter
+20 -1: hasNonVoidPrimitives
+7 -1: syncAll
+41 -1: domain        dump all domains in context
+59 -1: Ljava/util/Hashtable<Ljava/lang/Integer;Lsun/misc/Signal;>;
+16 -1: ForEachEntryTask
+18 -1: vminfoIsConsistent
+26 -1: (ZLjava/util/Comparator;)V
+9 -1: Lock.java
+31 -1: Lsun/reflect/ReflectionFactory;
+8 -1: (I[BII)I
+23 -1: doesExtendFXApplication
+87 -1: java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
+11 -1: windows-31j
+28 -1: sun/misc/URLClassPath$Loader
+17 -1: getEntryAfterMiss
+47 -1: ([Ljava/lang/reflect/Field;Ljava/lang/String;)J
+44 -1: Ljava/util/List<Ljava/security/Permission;>;
+10 -1: openStream
+31 -1: Ljava/net/UnknownHostException;
+19 -1: bad reference kind 
+29 -1: ()Ljava/nio/MappedByteBuffer;
+9 -1: H_UPALPHA
+37 -1: (Ljava/util/function/UnaryOperator;)V
+25 -1: FAKE_METHOD_HANDLE_INVOKE
+4 -1: peek
+25 -1: java/util/Hashtable$Entry
+18 -1: getMemberRefInfoAt
+37 -1: Ljava/util/WeakHashMap$Entry<TK;TV;>;
+14 -1: resolvedHandle
+27 -1: ()Ljava/util/Iterator<TV;>;
+61 -1: Ljava/util/Map<Ljava/lang/String;Ljava/lang/reflect/Method;>;
+6 -1: static
+50 -1: (Ljava/net/URLClassLoader;)Lsun/misc/URLClassPath;
+38 -1: (Ljava/lang/Class;)[Ljava/lang/Object;
+41 -1: (Ljava/util/SortedSet;Ljava/lang/Class;)V
+41 -1: java/lang/invoke/WrongMethodTypeException
+5 -1: group
+10 -1: readObject
+13 -1: getParentFile
+14 -1: daylightSaving
+15 -1: eagerValidation
+36 -1: (Ljava/io/File;)Lsun/misc/MetaIndex;
+18 -1: reduceEntriesToInt
+15 -1: INITIAL_ENTRIES
+18 -1: AtomicInteger.java
+7 -1: .length
+128 -1: Ljava/nio/Buffer;Ljava/lang/Comparable<Ljava/nio/CharBuffer;>;Ljava/lang/Appendable;Ljava/lang/CharSequence;Ljava/lang/Readable;
+6 -1: asList
+21 -1: unmodifiableSortedSet
+22 -1: ([B)Ljava/util/BitSet;
+5 -1: check
+64 -1: (Ljava/util/jar/JarFile;Lsun/misc/MetaIndex;)Lsun/misc/JarIndex;
+35 -1: ()Ljava/nio/charset/CharsetEncoder;
+4 -1: oome
+25 -1: ()Lsun/misc/URLClassPath;
+27 -1: (Ljava/io/FilePermission;)V
+29 -1: IllegalArgumentException.java
+17 -1: jvmSpecialVersion
+21 -1: Ljava/util/ArrayList;
+13 -1: packagePrefix
+27 -1: (Ljava/io/FilePermission;)Z
+11 -1: canonicalID
+82 -1: Ljava/lang/Object;Ljava/util/Comparator<Ljava/lang/String;>;Ljava/io/Serializable;
+24 -1: java.launcher.opt.footer
+13 -1: NativeLibrary
+37 -1: (Ljava/lang/String;J)Ljava/lang/Long;
+16 -1: longBitsToDouble
+6 -1: getKey
+22 -1: (JLjava/lang/String;)V
+14 -1: ensureCapacity
+69 -1: (Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;
+22 -1: java/lang/Thread$State
+50 -1: ()Ljava/util/Iterator<Ljava/nio/charset/Charset;>;
+4 -1: 7bit
+46 -1: (Ljava/lang/Class<+Ljava/lang/ClassLoader;>;)Z
+76 -1: (ILjava/util/List<Ljava/lang/Class<*>;>;)[Ljava/lang/invoke/LambdaForm$Name;
+3 -1: ttb
+12 -1: UTF_16LE_BOM
+9 -1: remainder
+40 -1: ()Lsun/reflect/generics/visitor/Reifier;
+22 -1: [Ljava/lang/Throwable;
+17 -1: EMPTY_ENUMERATION
+13 -1: erasedInvoker
+46 -1: Ljava/nio/charset/IllegalCharsetNameException;
+10 -1: UnicodeBig
+53 -1: ()Ljava/util/Map<Ljava/io/File;Lsun/misc/MetaIndex;>;
+12 -1: MAX_EXPONENT
+10 -1: Enumerator
+15 -1: charset decoder
+11 -1: AF_GETFIELD
+12 -1: | getInvoker
+74 -1: (Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
+14 -1: toUnsignedLong
+46 -1: java/lang/invoke/MethodHandleNatives$Constants
+29 -1: java version "1.8.0-internal"
+21 -1: ([Ljava/lang/Class;)I
+16 -1: UPPERCASE_LETTER
+22 -1: newConstantPerfCounter
+6 -1: signum
+9 -1: getField0
+38 -1: java/nio/charset/CoderMalfunctionError
+21 -1: [Ljava/lang/Runnable;
+11 -1: putIfAbsent
+30 -1: java/util/Collections$EmptySet
+22 -1: (I)[Ljava/lang/String;
+34 -1: Ljava/security/SecurityPermission;
+49 -1: ([Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+190 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$ReduceEntriesTask;Ljava/util/function/BiFunction;)V
+22 -1: Not an annotation type
+34 -1: java/io/ObjectInputStream$GetField
+50 -1: (Lsun/reflect/FieldInfo;)Ljava/lang/reflect/Field;
+32 -1: Ljava/lang/NoSuchFieldException;
+70 -1: (Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;
+9 -1: mergeSort
+77 -1: (ITK;TV;Ljava/util/HashMap$Node<TK;TV;>;)Ljava/util/HashMap$TreeNode<TK;TV;>;
+21 -1: sun/nio/cs/ISO_8859_1
+8 -1: DST_MASK
+21 -1: Ljava/lang/Throwable;
+108 -1: (Ljava/lang/ref/SoftReference<Ljava/lang/Class$ReflectionData<TT;>;>;I)Ljava/lang/Class$ReflectionData<TT;>;
+32 -1: java/util/Arrays$LegacyMergeSort
+59 -1: ()[Ljava/lang/reflect/TypeVariable<Ljava/lang/Class<TT;>;>;
+16 -1: parseUnsignedInt
+36 -1: ([D)Ljava/util/Spliterator$OfDouble;
+26 -1: SPECIFY_HANDLER_PERMISSION
+13 -1: primitiveType
+17 -1: threadStartFailed
+21 -1: (J)Ljava/lang/String;
+23 -1: setClassAssertionStatus
+28 -1: java/util/Hashtable$EntrySet
+28 -1: Non-positive maxBytesPerChar
+19 -1: getApplicationClass
+14 -1: SentinelHolder
+15 -1: staticFieldBase
+25 -1: setDefaultRequestProperty
+66 -1: java/util/concurrent/ConcurrentHashMap$ForEachTransformedValueTask
+8 -1: threadID
+9 -1: getFields
+15 -1: LineNumberTable
+38 -1: java/util/Collections$CheckedSortedSet
+14 -1: jdkBuildNumber
+6 -1: divide
+46 -1: (Ljava/io/BufferedWriter;Ljava/lang/String;Z)V
+20 -1: java/lang/Terminator
+92 -1: (Lsun/misc/URLClassPath$JarLoader;Ljava/lang/String;Ljava/net/URL;Ljava/util/jar/JarEntry;)V
+6 -1: force0
+10 -1: getThreads
+34 -1: java/util/IllformedLocaleException
+115 -1: (Ljava/lang/String;Lsun/reflect/generics/factory/GenericsFactory;)Lsun/reflect/generics/repository/FieldRepository;
+9 -1: testFlags
+11 -1: getLanguage
+36 -1: java/util/function/IntBinaryOperator
+12 -1: Suppressed: 
+10 -1: isMandated
+23 -1: MethodAccessorImpl.java
+28 -1: (Ljava/util/zip/ZipEntry;)[B
+27 -1: Ljava/util/Hashtable$Entry;
+5 -1: table
+10 -1: Short.java
+19 -1: ReferenceQueue.java
+8 -1: setTabAt
+26 -1: ()Lsun/invoke/empty/Empty;
+53 -1: (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+74 -1: (ILjava/lang/Object;)Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+19 -1: changeParameterType
+61 -1: Ljava/util/Map<Ljava/lang/String;Ljava/security/Permission;>;
+23 -1: (Ljava/lang/Object;IF)V
+32 -1: (I)Ljava/util/ListIterator<TE;>;
+6 -1: unread
+12 -1: isSubclassOf
+6 -1: (JJJ)V
+3 -1: Key
+105 -1: (Ljava/util/HashMap<TK;TV;>;[Ljava/util/HashMap$Node<TK;TV;>;ITK;TV;)Ljava/util/HashMap$TreeNode<TK;TV;>;
+14 -1: x-utf-16le-bom
+22 -1: ()Ljava/nio/IntBuffer;
+104 -1: (Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+21 -1: removeFirstOccurrence
+21 -1: sun/misc/DoubleConsts
+23 -1: ()Ljava/util/SortedSet;
+11 -1: getManEntry
+23 -1: URI is not hierarchical
+7 -1: replace
+16 -1: getDisplayScript
+11 -1: ISO_8859-15
+16 -1: permuteArguments
+5 -1: (JI)C
+41 -1: Error decoding percent encoded characters
+22 -1: ([I)Ljava/lang/String;
+31 -1: java/lang/management/ThreadInfo
+9 -1: useCaches
+22 -1: withInternalMemberName
+5 -1: (JI)I
+5 -1: (JI)J
+67 -1: <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;
+95 -1: (Ljava/util/jar/JarFile;[Ljava/security/CodeSource;)Ljava/util/Enumeration<Ljava/lang/String;>;
+7 -1: release
+56 -1: (Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;
+5 -1: (JI)V
+46 -1: (Ljava/util/Iterator;I)Ljava/util/Spliterator;
+18 -1: verifyMemberAccess
+9 -1: warning: 
+23 -1: java/lang/reflect/Field
+67 -1: (Ljava/lang/String;Lsun/reflect/generics/factory/GenericsFactory;)V
+10 -1: SizePrefix
+15 -1: setJavaIOAccess
+6 -1: (JI)[B
+10 -1: ST_FLUSHED
+10 -1: resolution
+9 -1: ST_CODING
+16 -1: sun/misc/Cleaner
+21 -1: (Ljava/lang/Class;)[B
+18 -1: WeakReference.java
+41 -1: (Ljava/util/List;Ljava/util/Comparator;)V
+18 -1: printPropertyValue
+3 -1: 813
+22 -1: setRunFinalizersOnExit
+4 -1: init
+44 -1: ()Ljava/util/Iterator<Ljava/nio/file/Path;>;
+3 -1: 819
+12 -1: listIterator
+8 -1: , arity=
+24 -1: (Ljava/util/ArrayList;)I
+49 -1: (IJLjava/io/FileDescriptor;Ljava/lang/Runnable;)V
+10 -1: principals
+17 -1: x-ISO-2022-CN-CNS
+22 -1: (Ljava/lang/Object;F)V
+14 -1: setReadTimeout
+19 -1: getProtectionDomain
+13 -1: pathSeparator
+12 -1: getAndSetInt
+58 -1: (Ljava/util/List;Ljava/util/Collection;)Ljava/util/Locale;
+11 -1: setWritable
+4 -1: perf
+50 -1: ()Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;
+6 -1: LOCTIM
+6 -1: status
+11 -1: replaceName
+52 -1: (Ljava/lang/CharSequence;II)Ljava/lang/StringBuffer;
+9 -1: nextToken
+13 -1: dropArguments
+20 -1: RECOGNIZED_MODIFIERS
+14 -1: getInputStream
+9 -1: readFully
+25 -1: (CLjava/nio/CharBuffer;)I
+24 -1: sun/misc/PathPermissions
+10 -1: malformedN
+9 -1: n is null
+19 -1: instanceof Double: 
+13 -1: markSupported
+26 -1: fromMethodDescriptorString
+43 -1: [Ljava/util/concurrent/locks/ReentrantLock;
+17 -1: parseUnsignedLong
+33 -1: Lsun/misc/URLClassPath$JarLoader;
+26 -1: (Ljava/io/OutputStream;I)V
+6 -1: L_DASH
+17 -1: EmptyNavigableMap
+19 -1: CharsetDecoder.java
+18 -1: makeDynamicInvoker
+12 -1: URLUtil.java
+27 -1: ()Ljava/util/Iterator<TT;>;
+9 -1: initTable
+11 -1: getFragment
+7 -1: isLower
+20 -1: getMethodOrFieldType
+29 -1: java/util/function/BiFunction
+10 -1: access$700
+3 -1: 850
+7 -1: UTC2037
+43 -1: java/util/ArraysParallelSortHelpers$FJShort
+9 -1: toSTZTime
+10 -1: access$702
+3 -1: 852
+8 -1: hashCode
+3 -1: 855
+44 -1: (Ljava/lang/ThreadLocal;Ljava/lang/Object;)V
+3 -1: 857
+3 -1: 858
+5 -1: erase
+55 -1: ()Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;
+47 -1: (Ljava/util/Iterator;JI)Ljava/util/Spliterator;
+38 -1: Ljava/nio/charset/spi/CharsetProvider;
+22 -1: can't deserialize enum
+13 -1: LF_EX_INVOKER
+18 -1: java/text/Collator
+18 -1: Zero length string
+49 -1: <T:Ljava/lang/Object;>()Ljava/util/Iterator<TT;>;
+5 -1: amd64
+12 -1: getNameCount
+7 -1: inCheck
+52 -1: (Ljava/util/concurrent/ConcurrentHashMap$TreeNode;)V
+53 -1: (ILjava/lang/CharSequence;II)Ljava/lang/StringBuffer;
+21 -1: java/util/WeakHashMap
+8 -1:  throws 
+52 -1: (Ljava/util/concurrent/ConcurrentHashMap$TreeNode;)Z
+55 -1: Ljava/lang/ref/SoftReference<Ljava/util/jar/Manifest;>;
+16 -1: emptyEnumeration
+3 -1: 862
+89 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Class;)Ljava/util/List;
+3 -1: 866
+55 -1: Lsun/reflect/generics/repository/ConstructorRepository;
+35 -1: (Ljava/lang/ref/ReferenceQueue$1;)V
+33 -1: java/util/Collections$CheckedList
+18 -1: prefetchReadStatic
+7 -1: (JI[I)I
+78 -1: (Ljava/lang/ThreadLocal$ThreadLocalMap;)Ljava/lang/ThreadLocal$ThreadLocalMap;
+7 -1: ordinal
+22 -1: FilterInputStream.java
+26 -1: java/util/zip/ZipConstants
+28 -1: JVM cannot find invoker for 
+43 -1: sun/reflect/generics/parser/SignatureParser
+51 -1: (Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)V
+73 -1: (Ljava/util/function/ToIntFunction;Ljava/lang/Object;Ljava/lang/Object;)I
+17 -1: StringBuffer.java
+62 -1: ([Ljava/lang/Object;Ljava/lang/StringBuilder;Ljava/util/Set;)V
+6 -1: equals
+9 -1: formatter
+3 -1: 874
+35 -1: newGetShortIllegalArgumentException
+74 -1: (Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
+3 -1: ucp
+60 -1: ([Ljava/lang/ClassValue$Entry;I)Ljava/lang/ClassValue$Entry;
+6 -1: create
+17 -1: makeReinvokerForm
+18 -1: csisolatincyrillic
+15 -1: incrementAndGet
+24 -1: maybeInstantiateVerifier
+33 -1: ()Ljava/nio/channels/FileChannel;
+6 -1: class 
+16 -1: getAnnotatedType
+43 -1: (Ljava/lang/reflect/Type;)Ljava/lang/Class;
+9 -1: HASH_BITS
+12 -1: placeInCache
+38 -1: java/util/Collections$SynchronizedList
+89 -1: (Ljava/net/URL;Ljava/util/jar/JarFile;Ljava/util/jar/JarEntry;)Ljava/security/CodeSource;
+22 -1: (Ljava/lang/String;I)B
+20 -1: Ljava/util/TimeZone;
+16 -1: sun.java.command
+28 -1: java/util/WeakHashMap$Values
+10 -1: X-UTF-16BE
+22 -1: (Ljava/lang/String;I)I
+26 -1: java/nio/DirectCharBufferS
+99 -1: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class<*>;
+22 -1: (Ljava/lang/String;I)J
+26 -1: java/nio/DirectCharBufferU
+54 -1: (Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal;
+21 -1: java/util/AbstractSet
+37 -1: (Ljava/lang/String;)Ljava/lang/Short;
+36 -1: Ljava/nio/charset/CoderResult$Cache;
+22 -1: (Ljava/lang/String;I)S
+15 -1: Ljava/util/Map;
+59 -1: (Ljava/lang/reflect/Type;)Ljava/lang/reflect/AnnotatedType;
+22 -1: (Ljava/lang/String;I)V
+10 -1: getAddress
+25 -1: java/nio/DirectIntBufferS
+11 -1: IMPL_LOOKUP
+3 -1: uee
+7 -1: addTime
+37 -1: sun/security/action/GetPropertyAction
+25 -1: java/nio/DirectIntBufferU
+21 -1: javaUtilZipFileAccess
+34 -1: java/util/Collections$CheckedQueue
+11 -1: readResolve
+22 -1: (Ljava/lang/String;I)Z
+11 -1: findVirtual
+63 -1: (Ljava/lang/String;Ljava/lang/String;)Lsun/security/util/Debug;
+22 -1: getDeclaredAnnotations
+16 -1: Collections.java
+18 -1: invalid entry size
+49 -1: java/util/concurrent/ConcurrentHashMap$TableStack
+32 -1: java/util/AbstractSequentialList
+4 -1: int0
+16 -1: MAXIMUM_CAPACITY
+53 -1: ()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
+4 -1: int1
+4 -1: int2
+4 -1: int3
+119 -1: (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/Class;[Ljava/lang/Class;I)Lsun/reflect/MethodAccessor;
+7 -1: variant
+39 -1: Lsun/reflect/annotation/AnnotationType;
+11 -1: arrayOffset
+24 -1: ()Ljava/util/LinkedList;
+31 -1: java/lang/ClassCircularityError
+17 -1: java/lang/Package
+10 -1: ccsid00858
+27 -1: java/io/ExpiringCache$Entry
+16 -1: newFieldAccessor
+67 -1: (Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;
+99 -1: Lsun/reflect/generics/repository/GenericDeclRepository<Lsun/reflect/generics/tree/ClassSignature;>;
+53 -1: (Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)V
+53 -1: Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+58 -1: <T:Ljava/lang/Object;>([TT;)Ljava/util/stream/Stream<TT;>;
+54 -1: (Ljava/lang/CharSequence;Ljava/text/Normalizer$Form;)Z
+8 -1: Kerberos
+29 -1: ()Ljava/nio/channels/Channel;
+12 -1: java_version
+45 -1: (Lsun/reflect/DelegatingMethodAccessorImpl;)V
+10 -1: canConvert
+136 -1: (Ljava/lang/StringBuffer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+26 -1: getDayOfWeekDateOnOrBefore
+7 -1: INVALID
+10 -1: TERMINATED
+41 -1: Ljava/security/cert/CertificateException;
+74 -1: (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/String;
+30 -1: [Ljava/lang/invoke/MethodType;
+13 -1: getMethodName
+7 -1: Factory
+34 -1: (Ljava/util/function/BiConsumer;)V
+11 -1: unlinkFirst
+37 -1: lambda$getDeclaredAnnotationsByType$0
+77 -1: (Ljava/nio/ByteBuffer;ILjava/nio/CharBuffer;II)Ljava/nio/charset/CoderResult;
+20 -1: java/util/ArrayDeque
+65 -1: (Ljava/lang/ThreadGroup;Ljava/lang/Runnable;Ljava/lang/String;J)V
+49 -1: (Ljava/util/ArrayDeque;Ljava/util/ArrayDeque$1;)V
+22 -1: (J)Ljava/time/Instant;
+17 -1: URLClassPath.java
+6 -1: 8859_1
+25 -1: stopRemoteManagementAgent
+6 -1: 8859_2
+17 -1: containsNullValue
+6 -1: 8859_4
+6 -1: 8859_5
+26 -1: (Ljava/nio/ByteBuffer;IC)V
+76 -1: (Ljava/lang/Runnable;Ljava/security/AccessControlContext;)Ljava/lang/Thread;
+6 -1: 8859_7
+6 -1: 8859_9
+8 -1: setHours
+9 -1: File.java
+21 -1: isIdentifierIgnorable
+5 -1: ([C)I
+4 -1: (B)I
+10 -1: codesource
+77 -1: ([Ljava/net/URL;Ljava/lang/ClassLoader;Ljava/security/AccessControlContext;)V
+4 -1: (B)J
+6 -1: isFair
+30 -1: java/lang/NullPointerException
+10 -1: IMPL_NAMES
+13 -1: Runnable.java
+26 -1: Ill-formed extension key: 
+17 -1: ()[Ljava/io/File;
+18 -1: javaSecurityAccess
+16 -1: equalsIgnoreCase
+4 -1: (B)V
+5 -1: ([C)V
+25 -1: Ljava/io/FileInputStream;
+14 -1: trackJavaUsage
+20 -1: Ljava/io/FileSystem;
+10 -1: iso_8859_1
+4 -1: (B)Z
+30 -1: java/lang/NoClassDefFoundError
+152 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/HashMap$TreeNode<TK;TV;>;Ljava/util/HashMap$TreeNode<TK;TV;>;)Ljava/util/HashMap$TreeNode<TK;TV;>;
+19 -1: java/lang/Cloneable
+55 -1: ([Ljava/lang/Object;Ljava/util/function/IntFunction;I)V
+27 -1: (Ljava/nio/ByteBuffer;IJZ)V
+21 -1: ()Lsun/misc/JarIndex;
+72 -1: ([Ljava/security/CodeSource;)Ljava/util/Enumeration<Ljava/lang/String;>;
+64 -1: (Ljava/util/Collection;Ljava/util/Comparator;)Ljava/lang/Object;
+20 -1: invalid entry crc-32
+9 -1: BASECOUNT
+29 -1: java/security/BasicPermission
+52 -1: (Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;
+7 -1: ([B[B)Z
+17 -1: EMPTY_ELEMENTDATA
+61 -1: (Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;
+49 -1: (ILjava/lang/Class;)Ljava/lang/invoke/MethodType;
+29 -1: sun/reflect/MagicAccessorImpl
+121 -1: (Ljava/lang/String;Lsun/reflect/generics/factory/GenericsFactory;)Lsun/reflect/generics/repository/ConstructorRepository;
+6 -1: ([II)I
+40 -1: (Ljava/lang/String;I)Ljava/lang/Integer;
+25 -1: java.content.handler.pkgs
+63 -1: ()Ljava/util/Set<Ljava/util/Map$Entry<Ljava/lang/String;TV;>;>;
+13 -1: parameterList
+6 -1: rebind
+16 -1: isSuperInterface
+6 -1: ([II)V
+14 -1: currentRuntime
+9 -1: BA_EXISTS
+15 -1: END_PUNCTUATION
+15 -1: no such method 
+19 -1: getAndVerifyPackage
+4 -1: wrap
+24 -1: checkAwtEventQueueAccess
+7 -1: ibm-437
+4 -1: open
+47 -1: (Ljava/nio/ByteBuffer;[BI)Ljava/nio/ByteBuffer;
+21 -1: ADDRESS_BITS_PER_WORD
+13 -1: isConstructor
+12 -1: getUseCaches
+27 -1: sun/util/locale/LocaleUtils
+4 -1: koi8
+23 -1: getParameterAnnotations
+9 -1: providers
+57 -1: ([Ljava/lang/Object;Ljava/util/function/BinaryOperator;)V
+24 -1: Lsun/misc/JavaNetAccess;
+22 -1: ([J)Ljava/lang/String;
+7 -1: p-1022$
+6 -1: isType
+63 -1: Ljava/util/Map<Ljava/lang/String;Lsun/util/calendar/ZoneInfo;>;
+21 -1: pageAlignDirectMemory
+18 -1: getManifestDigests
+37 -1: [Ljava/lang/reflect/AccessibleObject;
+7 -1: decrypt
+54 -1: (Lsun/misc/URLClassPath$JarLoader;)Ljava/util/HashMap;
+32 -1: lambda$comparingByKey$bbdbfea9$1
+21 -1: hasGenericInformation
+31 -1: java/nio/charset/CharsetEncoder
+15 -1: setTargetNormal
+3 -1: ulp
+18 -1: argumentTypesMatch
+12 -1: getDayOfYear
+8 -1: closeAll
+76 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/ref/SoftReference<TV;>;
+6 -1: concat
+9 -1: getLongAt
+16 -1: hasBeenFinalized
+32 -1: [Ljava/util/Hashtable$Entry<**>;
+23 -1: CheckedRandomAccessList
+106 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/net/URI;
+21 -1: defineClassInPackage.
+11 -1: ([III[III)V
+8 -1: toZoneId
+34 -1: SUBCLASS_IMPLEMENTATION_PERMISSION
+55 -1: java/util/concurrent/atomic/AtomicReferenceFieldUpdater
+8 -1: isDirect
+10 -1: ALL_ACCESS
+12 -1: isRegistered
+29 -1: ForEachTransformedMappingTask
+5 -1: LIJFD
+23 -1: (Ljava/util/TimeZone;)V
+23 -1: (Ljava/util/TimeZone;)Z
+20 -1: java/lang/Appendable
+29 -1: Lsun/util/calendar/Gregorian;
+9 -1: charValue
+8 -1: ONE_HOUR
+38 -1: (Ljava/util/Locale;)Ljava/lang/String;
+7 -1: script=
+10 -1: X-UTF-16LE
+7 -1: ENTRIES
+6 -1: detach
+38 -1: certpath      PKIX CertPathBuilder and
+14 -1: setLanguageTag
+13 -1: isAlphaString
+13 -1: interpretName
+9 -1: dayOfWeek
+88 -1: (Ljava/lang/Class;ZLjava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/List;
+91 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;)Ljava/lang/invoke/MethodHandle;
+13 -1: addTypeString
+17 -1: VectorSpliterator
+12 -1: MILLISECONDS
+6 -1: CENCOM
+10 -1: KeySetView
+18 -1: getTargetException
+7 -1: H_ALPHA
+32 -1: sun/util/locale/BaseLocale$Cache
+25 -1: [Ljava/lang/CharSequence;
+7 -1: Builder
+4 -1: left
+19 -1: BootClassPathHolder
+12 -1: publicFields
+11 -1: windows-437
+9 -1: EMPTY_SET
+26 -1: GET_STACK_TRACE_PERMISSION
+6 -1: copyOf
+14 -1: aliases_IBM737
+9 -1: writeLong
+35 -1: (JLjava/util/concurrent/TimeUnit;)Z
+70 -1: Ljava/lang/Object;Ljava/security/PrivilegedAction<Ljava/lang/String;>;
+22 -1: getAnnotatedReturnType
+41 -1: (Ljava/lang/String;[BII)Ljava/lang/Class;
+8 -1: ,maxpri=
+29 -1: handleParameterNumberMismatch
+26 -1: ts            timestamping
+11 -1: checkListen
+10 -1: SourceFile
+44 -1: (Ljava/lang/String;)Ljava/util/jar/JarEntry;
+17 -1: weakCompareAndSet
+9 -1: timestamp
+21 -1: (Z)Ljava/lang/String;
+12 -1: doneWithMeta
+20 -1: makeCollectArguments
+52 -1: (JLjava/util/function/BiFunction;)Ljava/lang/Object;
+10 -1: searchKeys
+48 -1: sun/reflect/SerializationConstructorAccessorImpl
+69 -1: (Ljava/lang/reflect/Constructor<*>;)Lsun/reflect/ConstructorAccessor;
+19 -1: ()Lsun/misc/Unsafe;
+11 -1: deepEquals0
+7 -1: GB18030
+13 -1: ValueIterator
+75 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
+28 -1: java/util/PropertyPermission
+6 -1: CENCRC
+3 -1: url
+3 -1: L_L
+19 -1: Certificate too big
+33 -1: sun/reflect/DelegatingClassLoader
+16 -1: lambda$stream$57
+11 -1: BitSet.java
+13 -1: sun/misc/Perf
+26 -1: Ljava/util/SimpleTimeZone;
+7 -1: (BBBB)I
+24 -1: sun/misc/FloatingDecimal
+21 -1: sun/util/PreHashedMap
+8 -1: utf-16be
+11 -1: isInherited
+83 -1: (Ljava/util/Properties;Ljava/io/OutputStream;Ljava/lang/String;Ljava/lang/String;)V
+52 -1: (Ljava/lang/Class;Ljava/security/ProtectionDomain;)V
+11 -1: getDoOutput
+18 -1: asVarargsCollector
+22 -1: NoSuchMethodError.java
+18 -1: getStackTraceDepth
+30 -1: (Ljava/io/File;)Ljava/net/URL;
+15 -1: CURRENCY_SYMBOL
+24 -1: Lsun/misc/JavaNioAccess;
+6 -1: NATIVE
+22 -1: Lsun/misc/PerfCounter;
+63 -1: java/util/concurrent/ConcurrentHashMap$MapReduceValuesToIntTask
+30 -1:  less than Character.MIN_RADIX
+17 -1: isCallerSensitive
+8 -1: shutdown
+11 -1: STATE_GREEN
+4 -1: next
+10 -1: tryPresize
+16 -1: CONSTRUCTOR_NAME
+3 -1: MAY
+21 -1: java.security.manager
+20 -1: Lsun/misc/Contended;
+16 -1: DISPLAY_LANGUAGE
+6 -1: KeySet
+9 -1: getScript
+3 -1: utc
+17 -1: TRACE_INTERPRETER
+39 -1: (Ljava/lang/Object;I)Ljava/lang/String;
+19 -1: getFieldAtIfLoaded0
+15 -1: methodFilterMap
+54 -1: Ljava/util/Map<Ljava/lang/String;Ljava/lang/Boolean;>;
+45 -1: java/security/cert/Certificate$CertificateRep
+43 -1: (Ljava/lang/String;)Lsun/util/calendar/Era;
+34 -1: java/security/cert/X509Certificate
+19 -1: versionsInitialized
+11 -1: isDirectory
+14 -1: aliases_IBM775
+38 -1: (Ljava/util/function/Consumer<-TE;>;)V
+38 -1: (Ljava/lang/String;)Ljava/util/Locale;
+40 -1: (Ljava/lang/String;Z)Lsun/misc/Resource;
+14 -1: setDefaultZone
+14 -1: highResCounter
+78 -1: (Ljava/lang/ClassValue$Version;Ljava/lang/Object;)Ljava/lang/ClassValue$Entry;
+16 -1: defaultUseCaches
+40 -1: (Ljava/util/zip/ZipFile;)Ljava/util/Map;
+24 -1: isSupplementaryCodePoint
+15 -1: ISO_8859_1.java
+13 -1: multiplyExact
+126 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lsun/util/locale/LocaleExtensions;)Ljava/util/Locale;
+8 -1: classMap
+8 -1: wildcard
+19 -1: getSimpleBinaryName
+17 -1: illegal signature
+14 -1:  == basicType(
+17 -1: ZipConstants.java
+32 -1: [Ljava/lang/VirtualMachineError;
+27 -1: ()Ljava/util/stream/Stream;
+24 -1: (Ljava/lang/Exception;)V
+21 -1: java/util/Enumeration
+13 -1: newSetFromMap
+8 -1: getenv.*
+20 -1: sun/management/Agent
+21 -1: sun/nio/cs/US_ASCII$1
+7 -1: comment
+15 -1: appendAuthority
+11 -1: hasWrappers
+10 -1: dstOffset 
+24 -1: sun/reflect/ConstantPool
+75 -1: (Ljava/util/jar/JarFile;[Ljava/security/CodeSource;)Ljava/util/Enumeration;
+52 -1: (Ljava/util/jar/JarFile;)Ljava/util/jar/JarVerifier;
+70 -1: Ljava/lang/Object;Ljava/security/PrivilegedAction<Ljava/lang/Object;>;
+14 -1: previousSetBit
+17 -1: AF_GETSTATIC_INIT
+15 -1: ArrayDeque.java
+7 -1: boolean
+25 -1: (I)Ljava/math/BigInteger;
+146 -1: (Ljava/lang/ref/ReferenceQueue<Ljava/lang/Class<*>;>;Ljava/util/concurrent/ConcurrentMap<+Ljava/lang/ref/WeakReference<Ljava/lang/Class<*>;>;*>;)V
+8 -1: getClass
+8 -1: user.dir
+6 -1: VALUES
+5 -1: raise
+39 -1: (JLjava/util/function/Consumer<-TV;>;)V
+107 -1: <T:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater<TT;TV;>;
+5 -1: print
+8 -1: readChar
+55 -1: (JLjava/util/TimeZone;)Lsun/util/calendar/CalendarDate;
+56 -1: java/util/concurrent/ConcurrentHashMap$MapReduceKeysTask
+60 -1: Ljava/lang/Number;Ljava/lang/Comparable<Ljava/lang/Double;>;
+102 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/SortedMap<TK;TV;>;)Ljava/util/SortedMap<TK;TV;>;
+23 -1: printModifiersIfNonzero
+14 -1: getterFunction
+15 -1: ISO-10646-UCS-2
+14 -1: canonizeString
+13 -1: getTotalSpace
+24 -1: synchronizedNavigableSet
+100 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedAction<TT;>;Ljava/security/AccessControlContext;)TT;
+4 -1: ioex
+24 -1: ()Ljava/nio/FloatBuffer;
+14 -1: toBinaryString
+7 -1: Segment
+34 -1: ()Lsun/misc/JavaUtilZipFileAccess;
+17 -1: setTargetVolatile
+22 -1: (Ljava/util/List<*>;)V
+51 -1: (ILjava/lang/CharSequence;)Ljava/lang/StringBuffer;
+22 -1: (Ljava/util/List<*>;)Z
+5 -1: (FI)F
+11 -1: parseMethod
+8 -1: Compiled
+19 -1: java/util/SortedMap
+7 -1: setByte
+12 -1: getFieldType
+8 -1: pageSize
+14 -1: getCallerClass
+9 -1: ensureObj
+18 -1: refKindHasReceiver
+10 -1: getZoneIds
+24 -1: (Ljava/nio/CharBuffer;)I
+47 -1: ()Lsun/reflect/generics/parser/SignatureParser;
+8 -1: getIndex
+24 -1: (Ljava/lang/Thread;TT;)V
+18 -1: (Ljava/util/Map;)V
+18 -1: (Ljava/util/Map;)Z
+6 -1: random
+10 -1: putAddress
+64 -1: (Ljava/util/function/Consumer<-Ljava/util/Map$Entry<TK;TV;>;>;)V
+24 -1: (Ljava/nio/CharBuffer;)V
+8 -1: canCache
+24 -1: (Ljava/nio/CharBuffer;)Z
+9 -1: getIntAt0
+4 -1: sqrt
+8 -1: makeLong
+54 -1: ([Ljava/lang/Object;Ljava/util/function/IntFunction;)V
+5 -1: (JJ)I
+26 -1: javaIOFileDescriptorAccess
+5 -1: (JJ)J
+15 -1:  != basicType: 
+36 -1: Ljava/lang/ref/ReferenceQueue<-TT;>;
+5 -1: words
+16 -1: sun.jnu.encoding
+32 -1: (Ljava/lang/invoke/LambdaForm;)V
+22 -1: ensureClassInitialized
+16 -1: Ljava/util/List;
+14 -1: varargsInvoker
+5 -1: (JJ)V
+20 -1: java/util/Properties
+12 -1: getImplClass
+21 -1: argumentTypesToString
+5 -1: (JJ)Z
+50 -1: java/util/Collections$SynchronizedRandomAccessList
+17 -1: makeWrappedMember
+21 -1: UnmodifiableSortedSet
+22 -1: (ILjava/lang/Class;Z)V
+3 -1: MIT
+13 -1: bootClassPath
+50 -1: (JLjava/util/function/Function;)Ljava/lang/Object;
+74 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/HashMap$Node<TK;TV;>;
+45 -1: (Ljava/util/Map$Entry;Ljava/util/Map$Entry;)I
+12 -1: advanceProbe
+10 -1: encoderFor
+14 -1: DataInput.java
+16 -1: java/lang/Double
+3 -1: 912
+3 -1: 914
+3 -1: abs
+3 -1: 915
+13 -1: currentThread
+17 -1: ClassDefiner.java
+32 -1: sun/misc/Launcher$ExtClassLoader
+16 -1: Current state = 
+12 -1: elementCount
+10 -1: unmaskNull
+8 -1: csibm857
+32 -1: java/net/UnknownServiceException
+10 -1: x-utf-16be
+3 -1: acc
+37 -1: Ljava/util/List<Ljava/io/Closeable;>;
+23 -1: ([Ljava/lang/Thread;Z)I
+17 -1: impliesIgnoreMask
+23 -1: getGenericComponentType
+51 -1: ()Lsun/reflect/generics/repository/ClassRepository;
+34 -1: " not found. Will use interpreter.
+38 -1: ()Ljava/security/AccessControlContext;
+6 -1: final 
+8 -1: utf-16le
+3 -1: 920
+3 -1: 923
+5 -1: (I)[C
+43 -1: (Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;
+8 -1: csibm862
+34 -1: (Ljava/lang/ref/Reference<+TT;>;)Z
+8 -1: csibm866
+20 -1: getParameterizedType
+7 -1: (II[C)V
+20 -1: [Ljava/lang/Package;
+84 -1: (Ljava/lang/String;Ljava/security/ProtectionDomain;)Ljava/security/ProtectionDomain;
+28 -1: SynchronizedRandomAccessList
+18 -1: sun/misc/VMSupport
+61 -1: java/lang/invoke/MethodType$ConcurrentWeakInternSet$WeakEntry
+3 -1: add
+16 -1: ZipEntryIterator
+11 -1: next_target
+87 -1: (Ljava/lang/String;Ljava/nio/ByteBuffer;Ljava/security/CodeSource;)Ljava/lang/Class<*>;
+4 -1: amod
+12 -1: markedSkipLF
+55 -1: java/util/concurrent/ConcurrentHashMap$EntrySpliterator
+5 -1:  lim=
+29 -1: java/security/PermissionsHash
+50 -1: (Ljava/lang/CharSequence;II)Ljava/lang/Appendable;
+19 -1: makePairwiseConvert
+58 -1: <T:Ljava/lang/Object;>(Ljava/lang/ClassValue$Entry<TT;>;)V
+8 -1: contents
+11 -1: user.region
+17 -1: RandomAccess.java
+13 -1: singletonList
+13 -1: policy,access
+64 -1: Ljava/util/Map<Ljava/lang/String;Ljava/io/ExpiringCache$Entry;>;
+25 -1: (Ljava/lang/Appendable;)V
+19 -1: (Ljava/util/List;)V
+43 -1: (Ljava/lang/ClassLoader;Ljava/lang/Class;)V
+19 -1: (Ljava/util/List;)Z
+15 -1: America/Chicago
+25 -1: (II)Ljava/nio/CharBuffer;
+12 -1: getDayOfWeek
+8 -1: ([BIIZ)V
+28 -1: (Ljava/lang/reflect/Field;)I
+28 -1: (Ljava/lang/reflect/Field;)J
+18 -1: getDeclaringClass0
+11 -1: counterTime
+30 -1: (Ljava/util/Collection<TE;>;)V
+28 -1: (Ljava/lang/reflect/Field;)V
+31 -1: (IIIILjava/io/FileDescriptor;)V
+25 -1: java/net/SocketPermission
+20 -1: bad parameter count 
+18 -1: getHeaderFieldLong
+26 -1: GetReflectionFactoryAction
+19 -1: MIN_TRANSFER_STRIDE
+17 -1: java/nio/Bits$1$1
+7 -1: getSize
+33 -1: java/util/function/ToLongFunction
+46 -1: (IILjava/lang/String;)Ljava/lang/StringBuffer;
+10 -1: access$800
+65 -1: sun/misc/JavaSecurityProtectionDomainAccess$ProtectionDomainCache
+26 -1: (Ljava/lang/ClassLoader;)V
+25 -1: java/util/IdentityHashMap
+26 -1: (Ljava/lang/ClassLoader;)Z
+91 -1: <T:Ljava/lang/Object;>(Ljava/util/function/ToIntFunction<-TT;>;)Ljava/util/Comparator<TT;>;
+26 -1: ([CIILjava/lang/String;I)I
+12 -1: canonicalize
+3 -1: val
+8 -1: putCharB
+12 -1: UTF_32LE_BOM
+60 -1: (Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;
+44 -1: (Lsun/misc/SignalHandler;Lsun/misc/Signal;)V
+26 -1: (Ljava/util/Enumeration;)V
+11 -1: INVALIDATED
+8 -1: putCharL
+22 -1: (II)Ljava/lang/String;
+7 -1: hasNext
+5 -1: WRITE
+20 -1: MIN_INITIAL_CAPACITY
+13 -1: propertyNames
+9 -1: Gregorian
+13 -1: getExpiration
+7 -1: minutes
+7 -1: ostream
+9 -1: java.lang
+17 -1: forceStandardTime
+9 -1: initWords
+41 -1: java/lang/Thread$UncaughtExceptionHandler
+9 -1: theUnsafe
+27 -1: ForEachTransformedEntryTask
+10 -1: forEncoder
+31 -1: needsClassLoaderPermissionCheck
+5 -1: ctime
+25 -1: ()Ljava/nio/DoubleBuffer;
+8 -1: getValue
+66 -1: (Lsun/util/locale/BaseLocale$Key;)Lsun/util/locale/BaseLocale$Key;
+42 -1: (Ljava/io/InputStream;Ljava/lang/String;)V
+6 -1: august
+14 -1: compileClasses
+13 -1: javaNetAccess
+22 -1: interpretWithArguments
+4 -1: url:
+14 -1: EMPTY_ITERATOR
+60 -1: Ljava/util/WeakHashMap<Ljava/io/Closeable;Ljava/lang/Void;>;
+24 -1: java/util/jar/Attributes
+12 -1: getOrDefault
+19 -1: Pacific/Guadalcanal
+33 -1: ()Ljava/lang/reflect/Constructor;
+38 -1: java/util/Collections$UnmodifiableList
+13 -1: basicTypeChar
+22 -1: (Ljava/lang/String;J)J
+14 -1: memberDefaults
+42 -1: (Ljava/lang/Class<*>;[Ljava/lang/String;)V
+38 -1: (Ljava/util/function/Consumer<-TK;>;)V
+16 -1: LF_NEWINVSPECIAL
+10 -1: classDepth
+28 -1: [Ljava/io/ObjectStreamField;
+46 -1: (Ljava/util/Collection;)Ljava/util/Collection;
+91 -1: ([Ljava/lang/reflect/Method;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
+11 -1: getLocation
+39 -1: (Ljava/lang/Class;[Ljava/lang/Class;Z)V
+9 -1: loadTable
+55 -1: Directory separator should not appear in library name: 
+7 -1: setTime
+14 -1: getConstructor
+4 -1: urls
+25 -1: dispatchUncaughtException
+77 -1: (ILjava/lang/Object;Ljava/lang/Class<*>;)Ljava/util/HashMap$TreeNode<TK;TV;>;
+8 -1: modCount
+8 -1: Opening 
+6 -1: ENDHDR
+4 -1: cnfe
+34 -1: DIRECTIONALITY_PARAGRAPH_SEPARATOR
+10 -1: Asia/Amman
+3 -1: MST
+28 -1: DIRECTIONALITY_ARABIC_NUMBER
+3 -1: all
+4 -1: enum
+8 -1: copyWith
+12 -1: ([JI[IIJII)I
+29 -1: Ljava/lang/annotation/Target;
+7 -1: Thread-
+14 -1: x-utf-32le-bom
+38 -1: (ILjava/lang/management/MemoryUsage;)V
+33 -1: Signal already used by VM or OS: 
+27 -1: (I)Ljava/lang/StringBuffer;
+25 -1: java/text/Normalizer$Form
+10 -1: x-utf-16le
+34 -1:  can not access a member of class 
+27 -1: (Ljava/nio/ByteBuffer;IFZ)V
+28 -1: (Ljava/lang/ClassValue<*>;)V
+16 -1: INITIAL_CAPACITY
+23 -1: DirectMethodHandle.java
+18 -1: reduceValuesToLong
+41 -1: (Ljava/lang/String;Ljava/lang/Class<*>;)V
+6 -1: unwrap
+12 -1: threadStatus
+5 -1: (DI)D
+11 -1: fieldOffset
+52 -1: java/util/concurrent/ConcurrentHashMap$EntryIterator
+14 -1: ACCESS_EXECUTE
+44 -1: (Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;
+29 -1: ([Ljava/lang/ThreadGroup;IZ)I
+18 -1: LocalVariableTable
+17 -1: ConstantPool.java
+26 -1: (Ljava/nio/ByteBuffer;ID)V
+4 -1: (C)B
+3 -1: and
+4 -1: head
+126 -1: (Ljava/lang/reflect/GenericDeclaration;Lsun/reflect/generics/scope/Scope;)Lsun/reflect/generics/factory/CoreReflectionFactory;
+4 -1: (C)C
+16 -1: Pacific/Auckland
+7 -1: Thread[
+5 -1: ([D)I
+4 -1: (C)I
+98 -1: <U:Ljava/lang/Object;>([Ljava/lang/reflect/Constructor<TU;>;)[Ljava/lang/reflect/Constructor<TU;>;
+11 -1: fileHandler
+30 -1: DIRECTIONALITY_NONSPACING_MARK
+10 -1: (this Map)
+14 -1: malformedCache
+5 -1: ([D)V
+4 -1: (C)V
+26 -1: getUnicodeLocaleAttributes
+4 -1: (C)Z
+81 -1: (JLjava/util/function/ToLongBiFunction;JLjava/util/function/LongBinaryOperator;)J
+46 -1: [Ljava/util/concurrent/ConcurrentHashMap$Node;
+20 -1:     Max. Heap Size: 
+24 -1: Ljava/lang/reflect/Type;
+13 -1: EmptyIterator
+8 -1: allocate
+7 -1: FLUSHED
+8 -1: exitVM.*
+59 -1: (Ljava/lang/String;)Lsun/util/locale/InternalLocaleBuilder;
+19 -1: reduceEntriesToLong
+15 -1: getISOLanguages
+13 -1: CONSTANT_ZERO
+23 -1: (I)Ljava/util/Iterator;
+96 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/util/Map<TK;TV;>;
+11 -1: isSynthetic
+7 -1: lineBuf
+30 -1: java/lang/annotation/Inherited
+65 -1: <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/lang/Iterable<TE;>;
+35 -1: (Ljava/lang/String;)[Ljava/io/File;
+27 -1: java/security/cert/CertPath
+26 -1: startRemoteManagementAgent
+9 -1: shiftLeft
+5 -1: stack
+42 -1: (Ljava/lang/Class<*>;[Ljava/lang/Object;)V
+11 -1: CheckedList
+10 -1: replaceAll
+86 -1: (Ljava/util/HashMap$TreeNode;Ljava/util/HashMap$TreeNode;)Ljava/util/HashMap$TreeNode;
+24 -1: (I)Ljava/nio/CharBuffer;
+13 -1: image/vnd.fpx
+15 -1: iso_8859-1:1987
+19 -1: (Ljava/lang/Long;)I
+22 -1: sun/misc/SignalHandler
+15 -1: ifModifiedSince
+42 -1: (Ljava/lang/Class;)Ljava/lang/ClassLoader;
+105 -1: (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Class;I[Ljava/lang/invoke/MemberName;)I
+22 -1: Negative timeout value
+38 -1: Ljava/io/UnsupportedEncodingException;
+11 -1: removeRange
+13 -1: Compiler.java
+6 -1: Sorter
+8 -1: aliasSet
+10 -1: UNASSIGNED
+34 -1: lambda$comparingByValue$1065357e$1
+34 -1: ()Ljava/lang/Class$AnnotationData;
+25 -1: sun/misc/Launcher$Factory
+15 -1: getLongVolatile
+8 -1: vmloader
+10 -1: unicodebig
+10 -1: closeables
+31 -1: JavaIOFileDescriptorAccess.java
+7 -1:  static
+3 -1: arg
+21 -1: library can't be null
+42 -1: java/util/ArraysParallelSortHelpers$FJByte
+22 -1: getDeclaringExecutable
+19 -1: runFinalizersOnExit
+20 -1: simpleTimeZoneParams
+13 -1: Modifier.java
+14 -1: pkcs11keystore
+6 -1: shared
+30 -1: java/net/MalformedURLException
+26 -1: ()[Lsun/util/calendar/Era;
+13 -1: x-MS950-HKSCS
+10 -1: relativize
+40 -1: (Ljava/lang/String;JJ)Ljava/lang/String;
+31 -1: java/util/HashMap$ValueIterator
+29 -1: MODIFY_THREADGROUP_PERMISSION
+38 -1: (Ljava/lang/String;)Ljava/lang/Object;
+7 -1: destroy
+37 -1: (Ljava/util/List;)[Ljava/lang/String;
+18 -1: (Ljava/io/File;Z)V
+32 -1: Ljava/util/HashMap$Node<TK;TV;>;
+18 -1: interfaceModifiers
+34 -1: java/util/LinkedList$LLSpliterator
+7 -1: REF_???
+23 -1: java/net/ContentHandler
+20 -1: <compiledLambdaForm>
+17 -1: [Ljava/lang/Byte;
+6 -1: exitVM
+3 -1: att
+27 -1: sun/nio/cs/UTF_16BE$Encoder
+6 -1: exists
+28 -1: Ljava/util/Collection<+TE;>;
+48 -1: (Ljava/lang/CharSequence;)Ljava/lang/Appendable;
+6 -1: getMap
+52 -1: ([Ljava/lang/Class;I)Ljava/lang/reflect/Constructor;
+11 -1: stackTrace[
+21 -1: slowCheckMemberAccess
+33 -1: ReflectiveOperationException.java
+9 -1: versionId
+56 -1: Wrong number of parameters in MethodParameters attribute
+14 -1: isLowSurrogate
+8 -1: csPCp852
+16 -1: copyConstructors
+25 -1: ()Ljava/util/Spliterator;
+9 -1: closeLock
+17 -1: readUnsignedShort
+7 -1: 8859_13
+7 -1: 8859_15
+13 -1: TARGET_OFFSET
+26 -1: (Ljava/util/Hashtable;IZ)V
+44 -1: (Ljava/nio/CharBuffer;)Ljava/nio/CharBuffer;
+46 -1: (Ljava/lang/reflect/Type;)Ljava/lang/Class<*>;
+25 -1: DEFAULT_CONCURRENCY_LEVEL
+36 -1: Ljava/util/List<Ljava/lang/String;>;
+29 -1: sun.nio.PageAlignDirectMemory
+37 -1: (Ljava/lang/Class;I)Ljava/lang/Class;
+12 -1: encryptBlock
+8 -1: parentOf
+5 -1: H_HEX
+11 -1: getFloatAt0
+24 -1: VirtualMachineError.java
+18 -1: getDeclaredClasses
+59 -1: (Ljava/lang/AbstractStringBuilder;)Ljava/lang/StringBuffer;
+42 -1: (Ljava/util/List<Ljava/lang/Class<*>;>;)[C
+37 -1: (Ljava/lang/String;)Ljava/lang/Float;
+13 -1: Iterator.java
+25 -1: (Ljava/io/PrintStream;I)V
+9 -1: getObject
+19 -1: [Ljava/lang/String;
+7 -1: SIZECTL
+11 -1: isUnderflow
+27 -1: sun.nio.MaxDirectMemorySize
+21 -1: isNonPublicProxyClass
+13 -1: toCalendarDOW
+9 -1: Type.java
+14 -1: aliases_IBM850
+17 -1: emptyNavigableMap
+14 -1: aliases_IBM852
+14 -1: aliases_IBM855
+14 -1: aliases_IBM857
+14 -1: aliases_IBM858
+15 -1: iso_8859-4:1988
+13 -1: UnicodeScript
+8 -1: getCharB
+17 -1: constructorMethod
+27 -1: java/util/function/Function
+20 -1: getProtectionDomain0
+8 -1: getCharL
+32 -1: ([Ljava/io/File;)[Ljava/net/URL;
+51 -1: (Ljava/lang/Class;Z)Ljava/lang/invoke/MethodHandle;
+7 -1: getenv.
+5 -1: stale
+14 -1: aliases_IBM862
+32 -1: java/util/spi/LocaleNameProvider
+14 -1: aliases_IBM866
+51 -1: ([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
+6 -1: CENDSK
+36 -1: java/util/Comparators$NullComparator
+34 -1: UnsafeStaticFieldAccessorImpl.java
+17 -1: staticFieldOffset
+12 -1: prefetchRead
+4 -1: help
+34 -1: (Ljava/util/concurrent/TimeUnit;)J
+8 -1: getChars
+19 -1: java/lang/Throwable
+34 -1: Annotation Type:\n   Member types: 
+55 -1: (Ljava/lang/Class<*>;Ljava/security/ProtectionDomain;)V
+14 -1: aliases_IBM874
+17 -1: getDisplayVariant
+24 -1: Ljava/net/NetPermission;
+15 -1: jvmMinorVersion
+11 -1: subSequence
+3 -1: x86
+6 -1: double
+14 -1: checkSlotCount
+20 -1: java/net/InetAddress
+14 -1: Principal.java
+8 -1: $,;:@&=+
+17 -1: ByteBuffered.java
+21 -1: sun.misc.Perf.getPerf
+11 -1: finishEntry
+27 -1: sun.timezone.ids.oldmapping
+26 -1: (ZLjava/io/OutputStream;)V
+41 -1: (Ljava/lang/String;Z)Ljava/lang/Class<*>;
+32 -1: generateSerializationConstructor
+6 -1: Value 
+40 -1: (Ljava/lang/String;Ljava/lang/String;Z)V
+16 -1: previousClearBit
+7 -1: theProp
+51 -1: (Ljava/io/OutputStream;Ljava/nio/charset/Charset;)V
+39 -1: com.sun.javafx.application.LauncherImpl
+21 -1: URLStreamHandler.java
+4 -1:  in 
+14 -1: BIT_INDEX_MASK
+125 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Comparator<-TK;>;)Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
+49 -1: (Ljava/util/Set;Ljava/lang/Class;)Ljava/util/Set;
+10 -1: scaleValue
+27 -1: (Ljava/nio/ByteBuffer;IDZ)V
+78 -1: (Ljava/util/Collection<Ljava/lang/reflect/Field;>;[Ljava/lang/reflect/Field;)V
+53 -1: <T:Ljava/lang/Object;>(I)Ljava/util/Enumeration<TT;>;
+38 -1: java/lang/IncompatibleClassChangeError
+60 -1: java/util/concurrent/ConcurrentHashMap$MapReduceMappingsTask
+23 -1: not a method or field: 
+35 -1: Ljava/nio/BufferUnderflowException;
+4 -1: i386
+13 -1: US_ASCII.java
+80 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/lang/reflect/AnnotatedType;
+21 -1: initializeSystemClass
+6 -1: ([CI)I
+18 -1: getBooleanProperty
+35 -1: java/util/function/ToDoubleFunction
+37 -1: (Ljava/lang/String;)Ljava/lang/Class;
+28 -1: MapReduceEntriesToDoubleTask
+38 -1: java/util/LinkedHashMap$LinkedEntrySet
+8 -1: copySign
+6 -1: ([CI)V
+55 -1: sun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule
+12 -1: parseBoolean
+3 -1: NET
+3 -1: NEW
+6 -1: Values
+17 -1: getJavaLangAccess
+9 -1: LocaleKey
+3 -1: :-1
+30 -1: (Ljava/io/ObjectInputStream;)V
+3 -1: NFC
+3 -1: NFD
+18 -1: SIMPLIFIED_CHINESE
+28 -1: ()Ljava/lang/reflect/Method;
+9 -1: localInit
+37 -1: sun/util/locale/LocaleSyntaxException
+15 -1: LambdaForm.java
+5 -1: rtype
+8 -1:  field "
+50 -1: (Ljava/lang/Class;Ljava/lang/ref/ReferenceQueue;)V
+80 -1: (Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;IILjava/lang/String;[B[B)V
+36 -1: java/lang/invoke/MethodHandleNatives
+22 -1: (Ljava/util/Map<**>;)Z
+22 -1: Ljava/lang/Class<TV;>;
+7 -1: SubList
+14 -1: connect,accept
+19 -1: declaredAnnotations
+38 -1: Ljava/lang/ThreadLocal$ThreadLocalMap;
+11 -1: isSpaceChar
+10 -1: offerFirst
+20 -1: sun/nio/ByteBuffered
+17 -1: packageDefinition
+7 -1: trigger
+35 -1: [Ljava/lang/invoke/LambdaForm$Name;
+19 -1: sun.stdout.encoding
+5 -1: start
+26 -1: (Ljava/util/HashMap;IIII)V
+65 -1: (JLjava/util/function/Consumer<-Ljava/util/Map$Entry<TK;TV;>;>;)V
+6 -1: LOCVER
+3 -1: ://
+42 -1: (CLjava/lang/Class<*>;Ljava/lang/Object;)Z
+6 -1: friday
+45 -1: sun/reflect/DelegatingConstructorAccessorImpl
+15 -1: iso_8859-7:1987
+15 -1: newCalendarDate
+24 -1: getAnnotatedReceiverType
+32 -1: java/util/NoSuchElementException
+50 -1: (Ljava/util/NavigableSet;)Ljava/util/NavigableSet;
+26 -1: java/text/SimpleDateFormat
+16 -1: threadInitNumber
+55 -1: <T:Ljava/lang/Object;>(TT;)Ljava/util/Spliterator<TT;>;
+23 -1: (Ljava/lang/Object;)TT;
+3 1: bar
+37 -1: getFunctionalInterfaceMethodSignature
+5 -1: state
+39 -1: [Ljava/lang/reflect/GenericDeclaration;
+22 -1: sun/net/ProgressSource
+13 -1: LLSpliterator
+93 -1: <T:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Enumeration<TT;>;Ljava/util/Iterator<TT;>;
+5 -1: JAPAN
+11 -1: SPACE_TOTAL
+20 -1: CharsetProvider.java
+12 -1: CR_UNDERFLOW
+7 -1: ITALIAN
+11 -1: getCallerPD
+13 -1: isMemberClass
+38 -1: (Ljava/util/function/Consumer<-TT;>;)V
+18 -1: malformedForLength
+14 -1: ReflectionData
+34 -1: (BZI)Ljava/lang/invoke/LambdaForm;
+16 -1: forPrimitiveType
+31 -1:  field found in java.lang.Class
+60 -1: (Ljava/lang/Void;Ljava/lang/ThreadGroup;Ljava/lang/String;)V
+18 -1: DescendingIterator
+25 -1: (IZLjava/lang/Runnable;)V
+35 -1: ()[Ljava/lang/reflect/TypeVariable;
+3 -1: bcp
+23 -1: (Ljava/lang/Object;)TV;
+25 -1: setDefaultAssertionStatus
+10 -1: ([BIIIII)V
+150 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;)Ljava/util/concurrent/ConcurrentHashMap$Node<TK;TV;>;
+14 -1:    Inherited: 
+17 -1: fileTimeToWinTime
+7 -1: ([BI)[B
+26 -1: java/io/OutputStreamWriter
+58 -1: <T:Ljava/lang/Object;>(Ljava/util/ListIterator<+TT;>;I)TT;
+39 -1: sun/reflect/annotation/AnnotationParser
+71 -1: (Ljava/nio/file/Path;Ljava/lang/String;)Ljava/nio/file/DirectoryStream;
+47 -1: Ljava/util/concurrent/locks/ReentrantLock$Sync;
+44 -1: (Ljava/util/Collection;[Ljava/lang/Object;)Z
+43 -1: ([ILjava/util/function/IntBinaryOperator;)V
+29 -1: reverseAllValidSurrogatePairs
+20 -1: Ljava/nio/file/Path;
+20 -1: getGenericSignature0
+42 -1: (Ljava/lang/String;Ljava/lang/Class<*>;Z)V
+8 -1: manEntry
+64 -1: (Ljava/lang/String;)Ljava/util/Enumeration<Lsun/misc/Resource;>;
+36 -1: newGetDoubleIllegalArgumentException
+63 -1: (Ljava/util/Collection;Ljava/lang/Class;)Ljava/util/Collection;
+30 -1:     Ergonomics Machine Class: 
+40 -1: ()Ljava/util/Map<Ljava/lang/String;TT;>;
+50 -1: (Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;
+30 -1: CHECK_MEMBER_ACCESS_PERMISSION
+22 -1: (Ljava/lang/Boolean;)I
+10 -1: V_Variable
+68 -1: java/util/concurrent/ConcurrentHashMap$ForEachTransformedMappingTask
+61 -1: (Ljava/lang/String;IILjava/lang/String;)Ljava/nio/ByteBuffer;
+21 -1: accessClassInPackage.
+44 -1: java/util/WeakHashMap$WeakHashMapSpliterator
+11 -1: nextElement
+9 -1: separator
+48 -1: java/util/zip/ZipFile$ZipFileInflaterInputStream
+44 -1: java/security/UnresolvedPermissionCollection
+10 -1: access$900
+44 -1: java/util/ArraysParallelSortHelpers$FJDouble
+84 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodHandle;
+52 -1: (Ljava/lang/ref/Finalizer;)Ljava/lang/ref/Finalizer;
+19 -1: getDeclaredMethods0
+29 -1: (IJ)Ljava/lang/StringBuilder;
+11 -1: Member.java
+61 -1: (Ljava/lang/String;ZJJ)Ljava/lang/management/MemoryPoolMBean;
+35 -1: java/lang/AssertionStatusDirectives
+23 -1: Declaring class is null
+56 -1: (Ljava/lang/Class;Ljava/lang/Object;Ljava/lang/Object;)I
+12 -1: java/io/File
+41 -1: java/util/ConcurrentModificationException
+47 -1: (Ljava/lang/CharSequence;)Ljava/nio/CharBuffer;
+19 -1: parameterClassCache
+8 -1: US_ASCII
+15 -1: tryMonitorEnter
+22 -1: Ljava/util/Collection;
+67 -1: (Lsun/misc/Signal;Lsun/misc/SignalHandler;)Lsun/misc/SignalHandler;
+27 -1: (Lsun/misc/JavaNioAccess;)V
+9 -1: DigitOnes
+5 -1: write
+31 -1: NF_internalMemberNameEnsureInit
+18 -1: comparableClassFor
+20 -1: defineAnonymousClass
+49 -1: (Ljava/io/InputStream;Lsun/net/ProgressSource;J)V
+31 -1: java/lang/NumberFormatException
+17 -1: remainderUnsigned
+62 -1: <T::Ljava/lang/Comparable<-TT;>;>()Ljava/util/Comparator<TT;>;
+4 -1: Kind
+20 -1: (Ljava/lang/Short;)I
+8 -1: OfDouble
+51 -1: ([Ljava/lang/Object;Ljava/lang/invoke/MethodType;)Z
+22 -1: [Ljava/util/Map$Entry;
+13 -1: instanceClass
+29 -1: ()Ljava/lang/SecurityManager;
+12 -1: isUnmappable
+17 -1: getAllStackTraces
+19 -1: LinkedValueIterator
+7 -1: isDigit
+10 -1: rangeCheck
+89 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;)Ljava/util/List<Ljava/lang/invoke/MemberName;>;
+13 -1: getMethodType
+21 -1: FileOutputStream.java
+22 -1: ()Ljava/text/Collator;
+64 -1: <T:Ljava/lang/Object;>(Ljava/security/PrivilegedAction<TT;>;)TT;
+15 -1: defaultTimeZone
+14 -1: emptySortedMap
+35 -1: (Ljava/util/function/IntConsumer;)V
+45 -1: java/util/Collections$CheckedRandomAccessList
+11 -1: getPriority
+7 -1: signals
+6 -1: Subset
+15 -1: invokeInterface
+16 -1: nameRefsAreLegal
+38 -1: (Ljava/lang/Object;)Ljava/lang/Object;
+37 -1: Ljava/util/Collections$EmptyIterator;
+9 -1: Perf.java
+20 -1: java/math/BigInteger
+38 -1: java/util/WeakHashMap$ValueSpliterator
+71 -1: (Ljava/nio/charset/CodingErrorAction;)Ljava/nio/charset/CharsetEncoder;
+50 -1: (Ljava/lang/invoke/MemberName;Ljava/lang/Object;)V
+21 -1: [Ljava/lang/Class<*>;
+13 -1: getProperties
+63 -1: (Ljava/lang/Class<*>;[B[Ljava/lang/Object;)Ljava/lang/Class<*>;
+65 -1: (Ljava/util/Set<Ljava/lang/Class<*>;>;)[Ljava/lang/reflect/Field;
+21 -1: sun/util/calendar/Era
+21 -1: Ljava/nio/CharBuffer;
+23 -1: (Ljava/lang/Object;JS)V
+24 -1: oracle/jrockit/jfr/VMJFR
+15 -1: access allowed 
+34 -1: ()Lsun/util/calendar/CalendarDate;
+97 -1: (Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;
+44 -1: ([Ljava/lang/Object;[Ljava/lang/Object;III)V
+48 -1: (Ljava/util/Collection;I)Ljava/util/Spliterator;
+11 -1: SimpleEntry
+63 -1: (Ljava/net/URL;Ljava/net/URLStreamHandler;Ljava/util/HashMap;)V
+8 -1: putFloat
+20 -1: linkToCallSiteMethod
+8 -1: invokers
+35 -1: (J)Lsun/util/calendar/BaseCalendar;
+6 -1: FRENCH
+26 -1: getRawParameterAnnotations
+9 -1: wordIndex
+29 -1: JNI_COPY_FROM_ARRAY_THRESHOLD
+20 -1: sun/nio/cs/Surrogate
+48 -1: (Lsun/misc/JavaSecurityProtectionDomainAccess;)V
+45 -1: (Ljava/lang/ThreadLocal;Ljava/lang/Object;I)V
+3 -1: NST
+14 -1: getHeaderField
+27 -1: (Ljava/util/jar/JarFile;Z)V
+10 -1: findNative
+38 -1: The following can be used with access:
+29 -1: convertCertArrayToSignerArray
+4 -1: .DSA
+12 -1: dependencies
+12 -1: SYNCHRONIZED
+14 -1: x-euc-jp-linux
+28 -1: URLStreamHandlerFactory.java
+11 -1: checkPtypes
+68 -1: (Ljava/io/InputStream;Ljava/lang/Object;Ljava/nio/charset/Charset;)V
+13 -1: addDayOfMonth
+10 -1: isAncestor
+16 -1: entryDislocation
+12 -1: tableSizeFor
+29 -1: (ID)Ljava/lang/StringBuilder;
+19 -1: getLastRuleInstance
+24 -1: getGenericParameterTypes
+8 -1: ,offset=
+37 -1: (Ljava/net/URL;Ljava/lang/String;II)V
+13 -1: UTF_16LE.java
+12 -1: setTimestamp
+31 -1: AtomicReferenceFieldUpdaterImpl
+6 -1: L_URIC
+4 -1: (D)D
+14 -1: DeqSpliterator
+13 -1: LF_INVVIRTUAL
+171 -1: <U:Ljava/lang/Object;W:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;Ljava/lang/Class<TW;>;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater<TU;TW;>;
+4 -1: (D)I
+22 -1: Ljava/lang/Class<TT;>;
+4 -1: (D)J
+196 -1: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+13 -1: ,transitions=
+30 -1: (Lsun/net/www/MessageHeader;)I
+4 -1: (D)V
+12 -1: segmentShift
+4 -1: (D)Z
+14 -1: Reference.java
+26 -1: [Ljava/lang/reflect/Field;
+26 -1: java/nio/DirectByteBufferR
+31 -1: lambda$thenComparing$36697e65$1
+30 -1: (Lsun/net/www/MessageHeader;)V
+55 -1: No java.nio.charset.StandardCharsets instances for you!
+59 -1: (Ljava/lang/Class<*>;Ljava/lang/Object;Ljava/lang/Object;)I
+19 -1: thenComparingDouble
+31 -1: ()Ljava/lang/invoke/LambdaForm;
+9 -1: getMillis
+21 -1: StandardCharsets.java
+15 -1: postDefineClass
+8 -1: getExtra
+3 -1: box
+10 -1: nextSetBit
+27 -1: java/util/ArrayList$SubList
+43 -1: (Ljava/util/concurrent/ConcurrentHashMap;)V
+52 -1: (Lsun/misc/URLClassPath;)Ljava/net/URLStreamHandler;
+7 -1: putLong
+40 -1: <T::Ljava/lang/Comparable<-TT;>;>([TT;)V
+8 -1: ([DII)[D
+8 -1: ([SIIS)I
+8 -1: argument
+12 -1: linkCallSite
+56 -1: <T:Ljava/lang/Object;>Ljava/lang/ref/WeakReference<TT;>;
+15 -1: returnSlotCount
+68 -1: (Ljava/lang/String;[Ljava/lang/Class<*>;Z)Ljava/lang/reflect/Method;
+20 -1: defaultDisplayLocale
+21 -1: (Ljava/util/Vector;)V
+49 -1: (Lsun/reflect/generics/visitor/TypeTreeVisitor;)V
+12 -1: isAlphabetic
+5 -1: perms
+13 -1: dosToJavaTime
+8 -1: ([SIIS)V
+7 -1: valueOf
+27 -1: Ljava/util/LinkedList$Node;
+41 -1: (Ljava/lang/String;I)Ljava/lang/Class<*>;
+38 -1: ()Ljava/nio/charset/CodingErrorAction;
+4 -1: MASK
+5 -1: Field
+101 -1: (Ljava/lang/Class;Ljava/nio/ByteBuffer;Lsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/lang/Object;
+56 -1: (Ljava/lang/String;Lsun/misc/Resource;)Ljava/lang/Class;
+9 -1: SURROGATE
+72 -1: (Ljava/lang/invoke/DirectMethodHandle$StaticAccessor;)Ljava/lang/Object;
+19 -1: PARAMETER_MODIFIERS
+48 -1: ([Ljava/lang/Object;II)Ljava/util/stream/Stream;
+56 -1: (TK;TV;Ljava/util/function/BiFunction<-TV;-TV;+TV;>;)TV;
+118 -1: <U:Ljava/lang/Object;>(JLjava/util/function/BiFunction<-TK;-TV;+TU;>;Ljava/util/function/BiFunction<-TU;-TU;+TU;>;)TU;
+29 -1: (Lsun/nio/ch/Interruptible;)V
+45 -1: Ljava/lang/ref/Reference<Ljava/lang/Object;>;
+17 -1: isHeldExclusively
+3 -1: NYI
+15 -1: getByteVolatile
+20 -1: compareAndSwapObject
+29 -1: (Z)[Ljava/lang/reflect/Field;
+7 -1: ([SII)V
+13 -1: toLanguageTag
+18 -1: StreamEncoder.java
+25 -1: (IF)Ljava/nio/ByteBuffer;
+18 -1: afterNodeInsertion
+11 -1: accessOrder
+60 -1: Lsun/reflect/annotation/TypeAnnotation$TypeAnnotationTarget;
+20 -1: META-INF/MANIFEST.MF
+18 -1: getSuperInterfaces
+26 -1: (Ljava/nio/ByteBuffer;IZ)C
+26 -1: (Ljava/nio/ByteBuffer;IZ)D
+9 -1: PROTECTED
+18 -1:  not visible from 
+26 -1: java/lang/RuntimeException
+26 -1: (Ljava/nio/ByteBuffer;IZ)F
+20 -1: java/net/FileNameMap
+15 -1: insertArguments
+8 -1: diagprop
+26 -1: (Ljava/nio/ByteBuffer;IZ)I
+26 -1: (Ljava/nio/ByteBuffer;IZ)J
+20 -1: createContentHandler
+11 -1: getProtocol
+26 -1: (Ljava/nio/ByteBuffer;IZ)S
+33 -1: Ljava/lang/NoSuchMethodException;
+19 -1: entry name too long
+40 -1: java/util/jar/JarVerifier$VerifierStream
+6 -1: server
+7 -1: OCTOBER
+26 -1: sun/invoke/util/VerifyType
+6 -1: domain
+9 -1: getUnsafe
+5 -1: ([Z)I
+4 -1: cons
+42 -1: ()Ljava/lang/ReflectiveOperationException;
+4 -1: byte
+29 -1: java/util/function/BiConsumer
+24 -1: getJavaUtilZipFileAccess
+37 -1: ([Ljava/lang/Object;)Ljava/util/List;
+27 -1: timeout can not be negative
+62 -1: Ljava/util/Map<Ljava/io/InputStream;Ljava/util/zip/Inflater;>;
+16 -1: getOurStackTrace
+34 -1: (J)Ljava/lang/ref/Reference<+TT;>;
+50 -1: Lsun/reflect/generics/repository/MethodRepository;
+20 -1: MIN_BYTE_BUFFER_SIZE
+3 -1: buf
+13 -1: getAttributes
+6 -1: GERMAN
+38 -1: java/security/NoSuchAlgorithmException
+20 -1: Direct buffer memory
+6 -1: (IIZ)V
+27 -1: JVMTI_THREAD_STATE_RUNNABLE
+26 -1: [Ljava/io/File$PathStatus;
+36 -1: (Ljava/util/List;Ljava/lang/Class;)V
+13 -1: JarIndex.java
+34 -1: java/lang/Character$CharacterCache
+8 -1: csIBM857
+10 -1: LineReader
+28 -1: Ljava/lang/RuntimeException;
+30 -1: ()Ljava/util/Enumeration<TV;>;
+12 -1: getSeparator
+124 -1: (Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;)Ljava/lang/Object;
+97 -1: Ljava/util/Map<Ljava/lang/Integer;Ljava/lang/ref/WeakReference<Ljava/nio/charset/CoderResult;>;>;
+21 -1: ConstantCallSite.java
+40 -1: sun/util/locale/provider/LocaleResources
+101 -1: <U::Ljava/lang/Comparable<-TU;>;>(Ljava/util/function/Function<-TT;+TU;>;)Ljava/util/Comparator<TT;>;
+4 -1: copy
+23 -1: sun/security/util/Debug
+10 -1: isAbsolute
+34 -1: (Ljava/lang/invoke/MethodHandle;)V
+34 -1: (Ljava/lang/invoke/MethodHandle;)Z
+48 -1: ()[Ljava/util/concurrent/ConcurrentHashMap$Node;
+34 -1: (Lsun/reflect/LangReflectAccess;)V
+8 -1: csIBM862
+8 -1: csIBM866
+64 -1: java/util/concurrent/ConcurrentHashMap$MapReduceKeysToDoubleTask
+39 -1: No java.util.Objects instances for you!
+68 -1: (Ljava/util/PrimitiveIterator$OfInt;JI)Ljava/util/Spliterator$OfInt;
+19 -1: Illegal class name 
+24 -1: uncaughtExceptionHandler
+12 -1: runFinalizer
+23 -1: java/io/FileInputStream
+41 -1: (Ljava/lang/Class<*>;Ljava/lang/String;)V
+98 -1: (Ljava/util/HashMap$Node<TK;TV;>;Ljava/util/HashMap$Node<TK;TV;>;)Ljava/util/HashMap$Node<TK;TV;>;
+30 -1: java/nio/charset/CoderResult$1
+20 -1: SourceDebugExtension
+30 -1: java/nio/charset/CoderResult$2
+69 -1: ([Ljava/security/ProtectionDomain;[Ljava/security/ProtectionDomain;)Z
+14 -1: 1.8.0-internal
+16 -1: ReduceValuesTask
+13 -1: toLowerString
+14 -1: newPrintStream
+13 -1: unicodelittle
+19 -1: getClassLoadingLock
+9 -1: DigitTens
+80 -1: (Ljava/lang/Class<*>;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodType;
+12 -1: sun_eu_greek
+21 -1: getBootstrapClassPath
+9 -1: volatile 
+15 -1: UnmodifiableMap
+21 -1: enumConstantDirectory
+10 -1: getContent
+4 -1: cosh
+74 -1: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
+11 -1: ([JII[JII)V
+28 -1: java/lang/reflect/Executable
+17 -1: MapReduceKeysTask
+6 -1: isOpen
+17 -1: AnnotationDefault
+17 -1: Already connected
+27 -1: (Lsun/misc/JavaNetAccess;)V
+34 -1: ([BILjava/nio/charset/Charset;Z)[B
+55 -1: Ljava/lang/invoke/DirectMethodHandle$EnsureInitialized;
+8 -1: Set.java
+10 -1: DEAD_ENTRY
+7 -1: nextInt
+3 -1: wtb
+23 -1: java/util/Collections$1
+86 -1: (Lsun/reflect/generics/factory/GenericsFactory;)Lsun/reflect/generics/visitor/Reifier;
+23 -1: java/util/Collections$2
+23 -1: java/util/Collections$3
+18 -1: DoubleCumulateTask
+22 -1: skip value is negative
+85 -1: (Ljava/io/InputStream;Ljava/lang/Object;Ljava/lang/String;)Lsun/nio/cs/StreamDecoder;
+5 -1: \\[\\]$
+34 -1: Ljava/util/NoSuchElementException;
+3 -1: NaN
+30 -1: sun/util/calendar/CalendarDate
+10 -1: V_Constant
+20 -1: java/lang/Comparable
+9 -1: text/html
+20 -1: -9223372036854775808
+20 -1: DataInputStream.java
+20 -1:    Member defaults: 
+35 -1: Ljava/lang/ref/ReferenceQueue$Lock;
+8 -1: getBytes
+17 -1: CodePointIterator
+11 -1: Signal.java
+19 -1: javaHomePrefixCache
+12 -1: replaceFirst
+37 -1: Ljava/lang/IndexOutOfBoundsException;
+39 -1: (Ljava/lang/String;ZI)Ljava/lang/Class;
+21 -1: initSystemClassLoader
+28 -1: America/Indiana/Indianapolis
+47 -1: (Ljava/security/Permission;Ljava/lang/Object;)V
+27 -1: java/net/URISyntaxException
+21 -1: createSecurityManager
+7 -1: suspend
+12 -1: L_UNRESERVED
+17 -1: checkMemberAccess
+12 -1: CoreCounters
+19 -1: java/net/HttpCookie
+8 -1: isGetter
+17 -1: setDaylightSaving
+27 -1: java.launcher.javafx.error1
+53 -1: java/util/concurrent/ConcurrentHashMap$CollectionView
+16 -1: readUnsignedByte
+47 -1: (Ljava/lang/String;)Ljava/net/URLStreamHandler;
+40 -1: (Z)[Ljava/lang/reflect/Constructor<TT;>;
+14 -1: javaLangAccess
+5 -1: apply
+8 -1: getFloat
+15 -1: getD3DAvailable
+25 -1: startLocalManagementAgent
+7 -1: RUNTIME
+22 -1: LocalVariableTypeTable
+8 -1: doOutput
+16 -1: CheckedSortedSet
+10 -1: zoneOffset
+64 -1: (Ljava/security/Permission;)Ljava/security/PermissionCollection;
+13 -1: hasUnresolved
+13 -1: user.language
+11 -1: getDoubleAt
+14 -1: getQueueLength
+37 -1: java/nio/DirectByteBuffer$Deallocator
+6 -1: ASHIFT
+9 -1: checkPath
+80 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)V
+6 -1: CENEXT
+16 -1: doubleToLongBits
+11 -1: copyToArray
+9 -1: copyField
+36 -1: ()Lsun/util/calendar/Gregorian$Date;
+53 -1: (ILjava/lang/Object;)Ljava/util/HashMap$Node<TK;TV;>;
+44 -1: (TK;TV;Ljava/lang/ref/ReferenceQueue<TV;>;)V
+35 -1: java/util/Collections$EmptyIterator
+38 -1: sealing violation: can't seal package 
+37 -1: (Ljava/util/Queue;Ljava/lang/Class;)V
+129 -1: (Ljava/lang/Class<*>;Ljava/lang/String;[Ljava/lang/Class<*>;Ljava/lang/Class<*>;[Ljava/lang/Class<*>;IILjava/lang/String;[B[B[B)V
+18 -1: HashMapSpliterator
+8 -1: putShort
+23 -1: (Ljava/lang/Object;II)V
+7 -1: GERMANY
+13 -1: toTitleString
+102 -1: (Ljava/util/ArrayPrefixHelpers$CumulateTask;Ljava/util/function/BinaryOperator;[Ljava/lang/Object;II)V
+44 -1: ([Ljava/lang/Object;)Ljava/util/Spliterator;
+6 -1: unused
+25 -1: java/net/URLClassLoader$1
+25 -1: java/net/URLClassLoader$2
+25 -1: java/net/URLClassLoader$3
+25 -1: java/net/URLClassLoader$4
+12 -1: getFixedDate
+25 -1: java/net/URLClassLoader$5
+4 -1: time
+25 -1: java/net/URLClassLoader$6
+25 -1: java/net/URLClassLoader$7
+14 -1: historicalName
+12 -1: normalizeKey
+13 -1: MIN_SURROGATE
+41 -1: java/nio/charset/CharacterCodingException
+18 -1: java/lang/Iterable
+8 -1: ([JII)[J
+103 -1: Ljava/util/Map<Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;Ljava/lang/annotation/Annotation;>;
+18 -1: putBooleanVolatile
+5 -1: Entry
+11 -1: CounterCell
+12 -1: monitorEnter
+10 -1: skipBuffer
+15 -1: hasMoreElements
+24 -1: newIllegalStateException
+24 -1: Ljava/lang/LinkageError;
+12 -1: getEntryFlag
+44 -1: (Ljava/lang/Throwable$PrintStreamOrWriter;)V
+18 -1: java/nio/IntBuffer
+17 -1: jdk_minor_version
+28 -1: DIRECTIONALITY_RIGHT_TO_LEFT
+15 -1: getAndSetObject
+7 -1: sizeCtl
+15 -1: Ljava/util/Set;
+32 -1: (I)Ljava/lang/invoke/LambdaForm;
+16 -1: runFinalization0
+30 -1: Ljava/lang/reflect/Executable;
+15 -1: compareUnsigned
+5 -1: nkeys
+31 -1: Ljava/nio/channels/FileChannel;
+40 -1: sun/reflect/generics/tree/ClassSignature
+22 -1: (Ljava/lang/Object;I)B
+22 -1: (Ljava/lang/Object;I)C
+22 -1: (Ljava/lang/Object;I)D
+7 -1: JANUARY
+30 -1: newGetIllegalArgumentException
+22 -1: (Ljava/lang/Object;I)F
+22 -1: (Ljava/lang/Object;I)I
+22 -1: (Ljava/lang/Object;I)J
+28 -1: generateNamedFunctionInvoker
+38 -1: (Ljava/lang/String;)Ljava/time/ZoneId;
+19 -1: lambda$codePoints$2
+4 -1: Null
+7 -1: setEras
+15 -1: lambda$chars$15
+14 -1: CollectionView
+24 -1: (C)Ljava/io/PrintStream;
+22 -1: (Ljava/lang/Object;I)S
+96 -1: (Ljava/security/AccessControlContext;Lsun/security/util/Debug;Ljava/security/ProtectionDomain;)V
+17 -1: getJulianCalendar
+22 -1: (Ljava/lang/Object;I)V
+17 -1: getMethodAccessor
+9 -1: not owner
+35 -1: java/lang/reflect/ParameterizedType
+15 -1: ValueCollection
+22 -1: (Ljava/lang/Object;I)Z
+4 -1: utf8
+5 -1: CHINA
+9 -1: sprintf0d
+18 -1: java/nio/file/Path
+35 -1: DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+30 -1: URI has an authority component
+43 -1: (Ljava/lang/Object;)Ljava/util/Spliterator;
+15 -1: <no principals>
+62 -1: (Lsun/util/locale/BaseLocale$Key;)Lsun/util/locale/BaseLocale;
+6 -1: ([ZZ)V
+10 -1: getContext
+12 -1: content-type
+99 -1: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;ILjava/util/WeakHashMap$Entry;)V
+51 -1: (Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;)V
+27 -1: Invalid constant pool index
+20 -1: getUnicodeLocaleType
+43 -1: Ljava/nio/charset/CharacterCodingException;
+113 -1: (Ljava/net/URL;Ljava/net/URLStreamHandler;Ljava/util/HashMap<Ljava/lang/String;Lsun/misc/URLClassPath$Loader;>;)V
+56 -1: (Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
+24 -1: Lsun/misc/SignalHandler;
+8 -1: readlink
+125 -1: (Ljava/nio/file/WatchService;[Ljava/nio/file/WatchEvent$Kind<*>;[Ljava/nio/file/WatchEvent$Modifier;)Ljava/nio/file/WatchKey;
+11 -1: initStatics
+15 -1: unmappableCache
+13 -1: fixMethodType
+25 -1: sun/net/www/MessageHeader
+3 -1: cdt
+27 -1: Ljava/util/Locale$Category;
+59 -1: (ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/lang/Object;
+8 -1: Accessor
+14 -1: mapLibraryName
+54 -1: (Lsun/misc/URLClassPath$JarLoader;)Lsun/misc/JarIndex;
+24 -1: ZoneOffsetTransitionRule
+7 -1: getChar
+3 -1: cee
+25 -1: MapReduceValuesToLongTask
+20 -1: declaredPublicFields
+44 -1: (Ljava/lang/ClassLoader;Ljava/lang/String;)J
+13 -1: removeElement
+20 -1: Ljava/nio/ByteOrder;
+8 -1: parallel
+67 -1: (Ljava/lang/reflect/Constructor;Lsun/reflect/ConstructorAccessor;)V
+22 -1: java/util/zip/ZipCoder
+8 -1: ([ZIIZ)V
+45 -1: (Ljava/lang/String;Ljava/lang/CharSequence;)Z
+8 -1: february
+40 -1: java/util/zip/ZipFile$ZipFileInputStream
+47 -1: java/nio/charset/Charset$ExtendedProviderHolder
+13 -1: IEEEremainder
+15 -1: sun/misc/Perf$1
+9 -1: abstract 
+20 -1: ()Ljava/time/ZoneId;
+7 -1: ONE_DAY
+92 -1: (Ljava/util/concurrent/ConcurrentHashMap$Node;)Ljava/util/concurrent/ConcurrentHashMap$Node;
+45 -1: (Ljava/util/ListIterator;I)Ljava/lang/Object;
+16 -1: Buffer size <= 0
+9 -1: checkName
+11 -1: getJarEntry
+20 -1: Replacement too long
+53 -1: (Ljava/lang/String;)Ljava/nio/charset/CharsetDecoder;
+12 -1: isWhitespace
+15 -1: csISOLatinGreek
+70 -1: (Ljava/lang/reflect/Constructor<*>;Lsun/reflect/ConstructorAccessor;)V
+20 -1: TypeAnnotationTarget
+3 -1: No 
+27 -1: Lsun/reflect/FieldAccessor;
+12 -1: doPrivileged
+83 -1: (JLjava/util/function/ToIntFunction<-TV;>;ILjava/util/function/IntBinaryOperator;)I
+60 -1: (Ljava/nio/file/attribute/FileTime;)Ljava/util/zip/ZipEntry;
+11 -1: changeEntry
+18 -1: MessageHeader.java
+51 -1: ([Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;
+9 -1: castEntry
+16 -1: ACCESS_MODIFIERS
+11 -1: newInstance
+24 -1: lastIndexOfSupplementary
+13 -1: JZENTRY_EXTRA
+5 -1: LONGS
+7 -1: domain 
+16 -1: protocolPathProp
+21 -1: java/util/Hashtable$1
+10 -1: isSameDate
+23 -1: (I)Ljava/nio/file/Path;
+33 -1: java/util/PrimitiveIterator$OfInt
+7 -1: ([II)[I
+8 -1: variant=
+29 -1: (Ljava/util/Collection<*>;Z)Z
+38 -1:  already loaded in another classloader
+10 -1: setSeconds
+9 -1: makeShort
+59 -1: ClassLoader.findLibrary failed to return an absolute path: 
+26 -1: java/util/jar/JarException
+9 -1: setCharAt
+13 -1: initCauseFrom
+13 -1: val$fieldName
+18 -1: MIN_HIGH_SURROGATE
+60 -1: (Lsun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule;)B
+25 -1: getDayOfWeekFromFixedDate
+10 -1: maybeReBox
+9 -1: getHandle
+60 -1: (Lsun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule;)I
+59 -1: ([Ljava/lang/Class<*>;)Ljava/lang/reflect/Constructor<TT;>;
+3 -1: cis
+11 -1: getIssuerDN
+9 -1: codebase=
+80 -1: (ILjava/lang/invoke/BoundMethodHandle$SpeciesData;)Ljava/lang/invoke/LambdaForm;
+29 -1: addThreadDumpForSynchronizers
+6 -1: FRANCE
+77 -1: <T:Ljava/lang/Object;U:Ljava/lang/Object;>([TU;ILjava/lang/Class<+[TT;>;)[TT;
+45 -1: <T:Ljava/lang/Object;>()Ljava/util/List<TT;>;
+16 -1: putFloatVolatile
+34 -1: (Ljava/lang/Class;)Ljava/util/Map;
+28 -1: ()Ljava/security/Permission;
+28 -1: (Ljava/lang/CharSequence;I)I
+51 -1: ()Ljava/util/Enumeration<Ljava/util/jar/JarEntry;>;
+25 -1: (II)Ljava/nio/ByteBuffer;
+20 -1: BasicPermission.java
+5 -1: isNaN
+48 -1: (Ljava/lang/Throwable;)Ljava/lang/InternalError;
+10 -1: ONE_MINUTE
+55 -1: (Ljava/lang/invoke/DirectMethodHandle$StaticAccessor;)J
+13 -1: DAYS_IN_MONTH
+7 -1: domains
+10 -1: isUnshared
+58 -1: Ljava/lang/Number;Ljava/lang/Comparable<Ljava/lang/Long;>;
+47 -1: (Ljava/util/List;)Ljava/security/cert/CertPath;
+28 -1: ()Ljava/util/Enumeration<*>;
+34 -1: sun/misc/Launcher$ExtClassLoader$1
+22 -1: (CLjava/lang/Object;)Z
+64 -1: Ljava/lang/ref/WeakReference<Ljava/nio/charset/CharsetDecoder;>;
+7 -1: ENGLISH
+27 -1: (Ljava/util/zip/Inflater;)V
+24 -1: makeArrayElementAccessor
+72 -1: (Ljava/lang/Class<*>;[Ljava/lang/Class<*>;)Ljava/lang/invoke/MethodType;
+48 -1: (Ljava/util/jar/JarFile;)Ljava/util/Enumeration;
+48 -1: (Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+15 -1: getNthDayOfWeek
+16 -1: printHelpMessage
+15 -1: getAbsoluteFile
+9 -1: OPEN_READ
+19 -1: willGMTOffsetChange
+28 -1: (Ljava/util/LinkedHashMap;)V
+37 -1: java/security/AllPermissionCollection
+5 -1: [id="
+34 -1: java/lang/invoke/BoundMethodHandle
+31 -1: ()Ljava/security/cert/CertPath;
+50 -1: java/util/ArraysParallelSortHelpers$FJShort$Sorter
+14 -1: StaticAccessor
+22 -1: synchronizedCollection
+53 -1: ([Ljava/io/File;)Ljava/security/AccessControlContext;
+37 -1: (Ljava/lang/Class;Ljava/lang/Class;)Z
+14 -1: codePointCount
+13 -1:  is param at 
+37 -1: Ljava/lang/invoke/MemberName$Factory;
+20 -1: annotationDataOffset
+31 -1: protocol doesn't support output
+11 -1: hostAddress
+12 -1: ,dstSavings=
+35 -1: java.lang.Integer.IntegerCache.high
+15 -1: ParallelLoaders
+48 -1: (Ljava/util/Locale;)Lsun/util/locale/BaseLocale;
+8 -1: getSize0
+22 -1: checkCreateClassLoader
+8 -1: transfer
+32 -1: (Lsun/misc/JavaSecurityAccess;)V
+26 -1: ()Ljava/net/URLConnection;
+3 -1: cmp
+9 -1: setMillis
+34 -1: sun/util/calendar/AbstractCalendar
+19 -1: getDirectBufferPool
+7 -1: ([FII)V
+28 -1: ([C)Ljava/lang/StringBuffer;
+54 -1: (Ljava/lang/Class<*>;)Ljava/security/ProtectionDomain;
+26 -1: (Ljava/nio/ByteBuffer;IF)V
+11 -1: discardMark
+71 -1: (Ljava/lang/Class;)Lsun/util/locale/provider/LocaleServiceProviderPool;
+30 -1: java/io/UTFDataFormatException
+53 -1: (Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
+48 -1: java/util/concurrent/ConcurrentHashMap$Traverser
+5 -1: ([F)I
+37 -1: (IC)Ljava/lang/AbstractStringBuilder;
+27 -1: Ljava/util/jar/JarVerifier;
+22 -1: java/util/Spliterators
+32 -1: java/lang/invoke/MutableCallSite
+20 -1: java/io/Serializable
+5 -1: ([F)V
+35 -1: (Ljava/security/ProtectionDomain;)V
+33 -1: ()Ljava/lang/ref/Reference<+TT;>;
+10 -1: unlinkLast
+6 -1: (JSZ)V
+8 -1: isStatic
+14 -1: subclassAudits
+23 -1: (Ljava/lang/String;)TT;
+17 -1: java.awt.headless
+9 -1: <Unknown>
+39 -1: Lsun/util/locale/LocaleSyntaxException;
+8 -1: location
+3 -1: cos
+27 -1: createGarbageCollectorMBean
+20 -1: MAX_MH_INVOKER_ARITY
+75 -1: (Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;Z)Ljava/nio/charset/CoderResult;
+14 -1: Cloneable.java
+50 -1: (Lsun/reflect/DelegatingConstructorAccessorImpl;)V
+26 -1: sun/nio/ch/FileChannelImpl
+51 -1: (Ljava/lang/Class;Ljava/lang/reflect/Constructor;)V
+18 -1: Unknown byte order
+28 -1: ()[Lsun/invoke/util/Wrapper;
+21 -1: getReadClassBytesTime
+64 -1: (Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodTypeForm;
+11 -1: setDelegate
+20 -1: (Ljava/util/List;)[C
+7 -1: usemmap
+22 -1: (CC)Ljava/lang/String;
+34 -1: sun/invoke/util/BytecodeDescriptor
+21 -1: getJavaSecurityAccess
+53 -1: (Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
+7 -1: ibm-737
+19 -1: (Ljava/lang/Enum;)I
+4 -1: rint
+11 -1: Constructor
+9 -1: arraycopy
+35 -1: ([D)Ljava/util/stream/DoubleStream;
+13 -1: comparingLong
+40 -1: <T:Ljava/lang/Object;>Ljava/lang/Object;
+23 -1: OutputStreamWriter.java
+8 -1: getShort
+17 -1: CLASSPATH_LASTOCC
+13 -1: createNewFile
+14 -1: internalValues
+34 -1: Ljava/lang/IllegalAccessException;
+23 -1: (JILjava/lang/Object;)V
+27 -1: sun.misc.URLClassPath.debug
+45 -1: [Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+35 -1: ()Lsun/reflect/ConstructorAccessor;
+12 -1: classEnabled
+23 -1: cachedFixedDateNextJan1
+48 -1: (Ljava/util/Locale$LocaleKey;)Ljava/util/Locale;
+26 -1: (Ljava/lang/ThreadGroup;)V
+7 -1: setErr0
+6 -1: CENFLG
+26 -1: (Ljava/lang/ThreadGroup;)Z
+18 -1: sun/misc/MetaIndex
+3 -1: crc
+34 -1: (Z)Ljava/lang/invoke/MethodHandle;
+12 -1: replaceNames
+15 -1: java/util/Stack
+57 -1: Ljava/util/Vector<Ljava/lang/ClassLoader$NativeLibrary;>;
+89 -1: (JLjava/util/function/ToDoubleFunction<-TV;>;DLjava/util/function/DoubleBinaryOperator;)D
+24 -1: permission can't be null
+22 -1: Unable to connect to: 
+44 -1: (Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;
+14 -1: floatToIntBits
+11 -1: getLastRule
+6 -1: EXTCRC
+26 -1: java/net/InetSocketAddress
+36 -1: (Lsun/misc/URLClassPath$JarLoader;)V
+27 3: sun/launcher/LauncherHelper
+8 -1: ecma-118
+49 -1: (Ljava/net/URL;Ljava/lang/String;)[Ljava/net/URL;
+13 -1: hashCodeValue
+5 -1: CESU8
+21 -1: appendVmSelectMessage
+13 -1: bindImmediate
+12 -1: closeLoaders
+16 -1: emptySpliterator
+28 -1: (J)Ljava/time/LocalDateTime;
+22 -1: [Ljava/lang/Character;
+5 -1: certs
+6 -1: (null)
+25 -1: java/io/ObjectInputStream
+27 -1: ([Ljava/lang/ThreadGroup;)I
+3 -1: cst
+3 -1: csu
+20 -1: java/nio/ShortBuffer
+53 -1: (Ljava/lang/ClassValue;Ljava/lang/ClassValue$Entry;)V
+4 -1: (Z)I
+24 -1: Ljava/io/FileDescriptor;
+6 -1: cclass
+10 -1: , profile 
+39 -1: (Ljava/lang/String;)Ljava/lang/Process;
+4 -1: (Z)V
+5 -1: toURI
+24 -1: ConstructorAccessor.java
+5 -1: toURL
+18 -1: addAllIfNotPresent
+4 -1: (Z)Z
+5 -1: parse
+11 -1: isPrimitive
+42 -1: (Ljava/io/File;)Ljava/lang/ProcessBuilder;
+36 -1: (Ljava/util/Date;)Ljava/lang/String;
+23 -1: getFormalTypeParameters
+13 -1: Resource.java
+7 -1: ibm-775
+6 -1: isEnum
+24 -1: setJavaUtilZipFileAccess
+21 -1: \t[CIRCULAR REFERENCE:
+51 -1: (Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;
+24 -1: (I)Ljava/nio/ByteBuffer;
+53 -1: sun/reflect/generics/repository/GenericDeclRepository
+3 -1: xor
+17 -1: invokeBasicMethod
+27 -1: java/lang/invoke/LambdaForm
+99 -1: (Ljava/util/jar/Manifest;Ljava/util/jar/JarEntry;Ljava/io/InputStream;Ljava/util/jar/JarVerifier;)V
+46 -1: Lsun/reflect/generics/factory/GenericsFactory;
+37 -1: sun/misc/Launcher$BootClassPathHolder
+10 -1: BindCaller
+24 -1: java/lang/reflect/Member
+32 -1: java/lang/management/ThreadState
+5 -1: (IB)V
+21 -1: RuntimeException.java
+5 -1: ended
+17 -1: java/util/TreeSet
+7 -1: : no !/
+16 -1: java/util/Vector
+9 -1: nextAfter
+22 -1: Ljava/lang/Deprecated;
+20 -1: requestedCharsetName
+37 -1: ([JIII)Ljava/util/Spliterator$OfLong;
+14 -1: internArgument
+11 -1: getTimeZone
+10 -1: isValidKey
+11 -1: LAST_RESULT
+43 -1: sun/reflect/annotation/TypeAnnotationParser
+13 -1: encodedInPath
+52 -1: (Ljava/security/PrivilegedAction;)Ljava/lang/Object;
+4 -1: LL_L
+34 -1: java/nio/charset/CodingErrorAction
+10 -1: copyFields
+11 -1: getConstant
+9 -1: threshold
+13 -1: aliases_UTF_8
+27 -1: (Ljava/util/ArrayDeque;II)V
+29 -1: Ljava/lang/ref/SoftReference;
+19 -1: indexedBinarySearch
+11 -1: containsKey
+81 -1: ([Ljava/lang/ClassValue$Entry;Ljava/lang/ClassValue;)Ljava/lang/ClassValue$Entry;
+86 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/Class<*>;II)Ljava/lang/invoke/MethodHandle;
+15 -1: cannot convert 
+25 -1: getSystemResourceAsStream
+46 -1: (Ljava/util/Properties;)Ljava/util/Properties;
+12 -1: reverseOrder
+16 -1: getSystemPackage
+8 -1: ([SII)[S
+19 -1: makeAccessException
+100 -1: <U:Ljava/lang/Object;>(JLjava/util/function/Function<-TK;+TU;>;Ljava/util/function/Consumer<-TU;>;)V
+39 -1: ([Ljava/lang/Class;I)[Ljava/lang/Class;
+19 -1: Ljava/lang/Boolean;
+6 -1: Hidden
+47 -1: java/lang/invoke/MethodHandleImpl$ArrayAccessor
+5 -1: APRIL
+8 -1: emptySet
+11 -1: getCombiner
+58 -1: (Ljava/lang/String;I[Ljava/lang/invoke/LambdaForm$Name;I)V
+24 -1: java.system.class.loader
+14 -1: Can't handle: 
+16 -1: isNullConversion
+38 -1: ()Ljava/util/HashMap$TreeNode<TK;TV;>;
+29 -1: referenceKindIsConsistentWith
+11 -1: flushBuffer
+8 -1: putField
+27 -1: ()Ljava/security/PublicKey;
+53 -1: ()Ljava/util/stream/Stream<Ljava/util/jar/JarEntry;>;
+10 -1: pathToURLs
+26 -1: throwIllegalStateException
+10 -1: markedChar
+14 -1: isNativeMethod
+36 -1: (I)Ljava/lang/AbstractStringBuilder;
+54 -1: java/util/concurrent/ConcurrentHashMap$ReservationNode
+45 -1: Lsun/misc/JavaSecurityProtectionDomainAccess;
+62 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;Ljava/lang/Object;I)V
+7 -1: subList
+8 -1: UTF_32BE
+6 -1: U_None
+50 -1: sun/reflect/generics/repository/AbstractRepository
+62 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;Ljava/lang/Object;I)Z
+43 -1: sun/net/www/protocol/file/FileURLConnection
+13 -1: setZoneOffset
+43 -1: Underlying input stream returned zero bytes
+54 -1: [a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*
+13 -1: containsValue
+44 -1: (Ljava/nio/CharBuffer;)Ljava/nio/ByteBuffer;
+25 -1: isNullReferenceConversion
+38 -1: Ljava/util/Vector<Ljava/lang/String;>;
+6 -1: toFile
+7 -1: getSlot
+17 -1: (Ljava/net/URI;)V
+32 -1: java.security.cert.Certificate: 
+24 -1: ()Lsun/misc/PerfCounter;
+11 -1: Asia/Hebron
+16 -1: createMemoryPool
+10 -1: addToCache
+29 -1: Ljava/lang/invoke/DontInline;
+39 -1: java/lang/ref/Finalizer$FinalizerThread
+58 -1: (Ljava/lang/Class;)Lsun/reflect/generics/scope/ClassScope;
+20 -1: getBooleanAttributes
+15 -1: parallelLockMap
+34 -1: java/util/Vector$VectorSpliterator
+21 -1: createMemoryPoolMBean
+15 -1: no content-type
+41 -1: Couldn't find 3-letter language code for 
+5 -1: slash
+34 -1: Ljava/lang/annotation/ElementType;
+8 -1: isSetter
+26 -1: (ZLjava/lang/String;JJJZ)V
+6 -1: GMT_ID
+73 -1: ()[Ljava/lang/reflect/TypeVariable<Ljava/lang/reflect/Constructor<TT;>;>;
+56 -1: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+32 -1: (Ljava/util/Set;)Ljava/util/Set;
+4 -1: stop
+62 -1: (Ljava/lang/String;IILjava/lang/String;I)Ljava/nio/ByteBuffer;
+11 -1: genericInfo
+11 -1: listToArray
+26 -1: ()Ljava/util/jar/Manifest;
+13 -1: putOrderedInt
+5 -1: flush
+13 -1: ArrayAccessor
+4 -1: Name
+95 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;[Ljava/util/concurrent/ConcurrentHashMap$Node;)V
+68 -1: (Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+23 -1: java/lang/ref/Reference
+37 -1: (Ljava/nio/file/attribute/FileTime;)J
+14 -1: MIN_CODE_POINT
+9 -1: ISO8859-1
+9 -1: ISO8859-2
+9 -1: ISO8859-5
+34 -1: ([CILjava/nio/charset/Charset;Z)[C
+9 -1: ISO8859-9
+9 -1: getUTF8At
+12 -1: java/net/URI
+67 -1: (Ljava/io/DataInput;Ljava/lang/String;)Lsun/util/calendar/ZoneInfo;
+22 -1: ListCompositionPattern
+67 -1: (Ljava/lang/String;[BIILjava/security/CodeSource;)Ljava/lang/Class;
+3 1: xxx
+12 -1: java/net/URL
+27 -1: Can't overwrite cause with 
+30 -1: sun/util/locale/BaseLocale$Key
+22 -1: forkSecondaryFinalizer
+23 -1: java/security/Principal
+8 -1: makeSite
+17 -1: NEGATIVE_INFINITY
+12 -1: addUnstarted
+12 -1: internalForm
+9 -1: cellsBusy
+23 -1: (Ljava/lang/Object;IJ)V
+13 -1: getParameters
+6 -1: H_PATH
+10 -1: L_REG_NAME
+139 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/util/Map<TK;TV;>;Ljava/lang/Cloneable;Ljava/io/Serializable;
+6 -1: latin0
+10 -1: addSeconds
+6 -1: latin1
+6 -1: latin2
+6 -1: latin4
+6 -1: latin5
+17 -1: getWaitingThreads
+6 -1: latin9
+21 -1: java/util/Comparators
+10 -1: trimToSize
+96 -1: <T:Ljava/lang/Object;>(Ljava/util/Collection<TT;>;Ljava/lang/Object;)Ljava/util/Collection<TT;>;
+43 -1: ([JLjava/util/function/IntToLongFunction;)V
+23 -1: GET_COMBINER_PERMISSION
+20 -1: lambda$replaceAll$14
+5 -1: KOREA
+20 -1: getJvmSpecialVersion
+9 -1: dumpStack
+16 -1: CACHE_LOAD_LIMIT
+43 -1:               GSS LoginConfigImpl debugging
+26 -1: (DLjava/lang/Appendable;)V
+8 -1: forName0
+35 -1: java/lang/ClassLoader$NativeLibrary
+46 -1: java/util/concurrent/ConcurrentHashMap$Segment
+24 -1: getDeclaredAnnotationMap
+89 -1: java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl$1
+20 -1: java_runtime_version
+26 -1: java/util/stream/IntStream
+16 -1: Ljava/io/Writer;
+69 -1: ()Ljava/util/SortedMap<Ljava/lang/String;Ljava/nio/charset/Charset;>;
+15 -1: getClassLoader0
+6 -1: x86_64
+11 -1: isInterface
+15 -1: MODIFIER_SYMBOL
+44 -1: Note: Separate multiple options with a comma
+9 -1: recursive
+19 -1: java/nio/CharBuffer
+8 -1: capacity
+17 -1: validateMainClass
+50 -1: (Ljava/util/Set;Ljava/lang/Object;)Ljava/util/Set;
+22 -1: (Ljava/lang/Object;J)B
+22 -1: (Ljava/lang/Object;J)C
+22 -1: (Ljava/lang/Object;J)D
+17 -1: not a method type
+22 -1: (Ljava/lang/Object;J)F
+5 -1: count
+32 -1: AtomicReferenceFieldUpdater.java
+22 -1: (Ljava/lang/Object;J)I
+14 -1: methodAccessor
+22 -1: (Ljava/lang/Object;J)J
+7 -1: isError
+51 -1: (Ljava/nio/Buffer;II)Ljava/nio/charset/CoderResult;
+53 -1: (BZLjava/lang/Class<*>;)Ljava/lang/invoke/LambdaForm;
+25 -1:  <no signer certificates>
+5 -1: [pos=
+14 -1: lambda$chars$1
+9 -1: CELLVALUE
+16 -1: haveLeftoverChar
+22 -1: ([Ljava/lang/String;)V
+32 -1: java/lang/InstantiationException
+7 -1: SIG_IGN
+13 -1: ZipUtils.java
+50 -1: Ljava/lang/ref/ReferenceQueue<Ljava/lang/Object;>;
+22 -1: (Ljava/lang/Object;J)S
+69 -1: Ljava/util/HashMap<Ljava/lang/String;Lsun/misc/URLClassPath$Loader;>;
+16 -1: newInternalError
+22 -1: (Ljava/lang/Object;J)V
+9 -1: ABBR_MASK
+5 -1: array
+22 -1: (Ljava/lang/Object;J)Z
+13 -1: FilteringMode
+30 -1: java/util/stream/StreamSupport
+19 -1: retrieveDisplayName
+56 -1: (Ljava/util/TimeZone;)Lsun/util/calendar/Gregorian$Date;
+10 -1: val$values
+9 -1: normalize
+28 -1: (II)Ljava/lang/CharSequence;
+16 -1: serialVersionUID
+7 -1: getPath
+25 -1: (ILjava/lang/Class<*>;Z)V
+13 -1: thenComparing
+51 -1: (Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;
+36 -1: ()[Ljava/lang/annotation/Annotation;
+14 -1: MetaIndex.java
+8 -1: identity
+15 -1: findSystemClass
+24 -1: privateGetDeclaredFields
+27 -1: java/lang/ref/SoftReference
+19 -1: useCanonPrefixCache
+3 -1: dec
+3 -1: PLT
+8 -1: UTF_32LE
+17 -1: java/util/HashMap
+12 -1: toEpochMilli
+9 -1: intStream
+11 -1: Caused by: 
+31 -1: java/nio/charset/CharsetDecoder
+30 -1:               is being checked
+11 -1: parseHeader
+25 -1: ACCUMULATED_DAYS_IN_MONTH
+34 -1: newGetByteIllegalArgumentException
+21 -1: checkPropertiesAccess
+13 -1: StackMapTable
+8 -1: addCount
+51 -1: (Ljava/lang/invoke/MethodHandle;)Ljava/lang/String;
+9 -1: authority
+15 -1: iso-10646-ucs-2
+6 -1: SUNDAY
+22 -1: LocalGregorianCalendar
+9 -1: listRoots
+32 -1: Lsun/reflect/generics/tree/Tree;
+38 -1: [Ljava/util/WeakHashMap$Entry<TK;TV;>;
+11 -1: nativeOrder
+5 -1: long0
+5 -1: long1
+5 -1: long2
+5 -1: long3
+17 -1: capacityIncrement
+5 -1: long4
+97 -1: (Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;
+31 -1: Ljava/lang/CharacterDataLatin1;
+5 -1: long5
+5 -1: long6
+5 -1: long7
+17 -1: reduceValuesToInt
+13 -1: package2certs
+13 -1: isTypeVisible
+30 -1: java/lang/ref/PhantomReference
+47 -1: ()Ljava/util/stream/Stream<Ljava/lang/String;>;
+9 -1: longValue
+3 -1: PNT
+10 -1: storeToXML
+10 -1: getMethod0
+12 -1: constantZero
+7 -1: promise
+116 -1: (Ljava/lang/String;Lsun/reflect/generics/factory/GenericsFactory;)Lsun/reflect/generics/repository/MethodRepository;
+32 -1: DIRECTIONALITY_SEGMENT_SEPARATOR
+9 -1: byteOrder
+9 -1: isPromise
+4 -1: isOn
+6 -1: LOCCRC
+10 -1: setDefault
+9 -1: setHandle
+15 -1: java/nio/Buffer
+37 -1: (Ljava/lang/String;I)Ljava/lang/Long;
+10 -1: Float.java
+12 -1: showSettings
+27 -1: (Ljava/io/FileDescriptor;)I
+27 -1: (Ljava/io/FileDescriptor;)J
+21 -1: java/util/Spliterator
+22 -1: CodingErrorAction.java
+11 -1: isMalformed
+27 -1: java/util/PrimitiveIterator
+15 -1: THROW_EXCEPTION
+15 -1: copyToCharArray
+26 -1: ()Ljava/util/jar/JarEntry;
+27 -1: (Ljava/io/FileDescriptor;)V
+11 -1: getEncoding
+48 -1: (Ljava/lang/ThreadLocal<*>;Ljava/lang/Object;I)V
+17 -1: java.runtime.name
+28 -1: (Lsun/invoke/util/Wrapper;)Z
+20 -1: annotationTypeOffset
+27 -1: (J)Ljava/lang/StringBuffer;
+15 -1: METHOD_RECEIVER
+10 -1: startEntry
+29 -1: (I)Ljava/lang/reflect/Member;
+7 -1: setOut0
+10 -1: getMethods
+26 -1: ()Lsun/misc/JavaNioAccess;
+18 -1: linkToTargetMethod
+8 -1: INSTANCE
+3 -1: dir
+41 -1: ([Ljava/net/URL;Ljava/lang/ClassLoader;)V
+9 -1: unboxCast
+58 -1: <T:Ljava/lang/Throwable;>(TT;)Lsun/invoke/empty/Empty;^TT;
+12 -1: java.version
+50 -1: (Ljava/io/InputStream;Ljava/nio/charset/Charset;)V
+32 2: sun/net/www/protocol/jar/Handler
+20 -1: java/lang/Compiler$1
+9 -1: LongCache
+14 -1: FILL_THRESHOLD
+22 -1: getRawClassAnnotations
+9 -1: (JI[CII)I
+13 -1: hasMoreTokens
+13 -1: getSuperclass
+3 -1: PRC
+12 -1: MAX_PRIORITY
+14 -1: checkCacheLoad
+7 -1: lowMask
+8 -1: LM_CLASS
+7 -1: initIDs
+27 -1: Ljava/util/Collection<TV;>;
+3 -1: yes
+3 -1: PRT
+91 -1: (Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/LambdaForm;
+27 -1: ()Lsun/security/util/Debug;
+8 -1: VM start
+9 -1: setMemory
+7 -1: getName
+10 -1: findSignal
+19 -1: startsWithLocHeader
+37 -1: java/util/Collections$SynchronizedMap
+51 -1: (ICLjava/lang/Object;)Ljava/lang/invoke/LambdaForm;
+62 -1: (Ljava/util/Locale;)Lsun/util/locale/provider/LocaleResources;
+17 -1: lastParameterType
+9 -1: NO_PTYPES
+116 -1: <T:Ljava/lang/Object;>([Ljava/lang/ClassValue$Entry<*>;Ljava/lang/ClassValue<TT;>;)Ljava/lang/ClassValue$Entry<TT;>;
+18 -1: DisplayNamePattern
+8 -1: getField
+5 -1: flags
+3 -1: PST
+17 -1: annotationDefault
+18 -1: java/nio/ByteOrder
+8 -1: highMask
+6 -1: ascii7
+29 -1: getGregorianYearFromFixedDate
+125 -1: (Ljava/lang/String;[Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/invoke/LambdaForm$Name;Ljava/lang/invoke/LambdaForm$Name;)V
+8 -1: =Lambda(
+29 -1: Ljava/util/WeakHashMap$Entry;
+18 -1: multiValueIterator
+74 -1: Ljava/util/LinkedHashMap<Ljava/lang/String;Ljava/io/ExpiringCache$Entry;>;
+13 -1: CONV_OP_LIMIT
+6 -1: sclSet
+81 -1: (Lsun/misc/URLClassPath$JarLoader;Ljava/util/jar/JarFile;)Ljava/util/jar/JarFile;
+14 -1: appendFragment
+46 -1: java/util/Collections$SynchronizedNavigableMap
+36 -1: application/x-java-serialized-object
+13 -1: setNativeName
+53 -1: java/util/concurrent/ConcurrentHashMap$ForwardingNode
+16 -1: setJavaAWTAccess
+30 -1: methodHandleInvokeLinkerMethod
+15 -1: reduceKeysToInt
+20 -1: ensureCapacityHelper
+23 -1: createFileURLConnection
+12 -1: d3dAvailable
+69 -1: (Ljava/lang/Object;Ljava/lang/invoke/MethodHandle;)Ljava/lang/String;
+49 -1: java/util/ArraysParallelSortHelpers$FJLong$Sorter
+21 -1: explicitCastArguments
+24 -1: JAVAFX_LAUNCH_MODE_CLASS
+9 -1: invoke_MT
+18 -1: ensureMemberAccess
+74 -1: (Ljava/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject;)I
+36 -1: java/nio/charset/spi/CharsetProvider
+23 -1: (Ljava/lang/String;II)V
+14 -1: initProperties
+4 -1: (F)F
+35 -1: [[Ljava/lang/annotation/Annotation;
+4 -1: (F)I
+106 -1: Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/lang/CharSequence;
+46 -1: java/lang/invoke/BoundMethodHandle$SpeciesData
+74 -1: (Ljava/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject;)Z
+24 -1: java.launcher.opt.header
+37 -1: ([Ljava/security/ProtectionDomain;Z)V
+10 -1: lineBuffer
+7 -1: ibm-813
+9 -1: isBuiltin
+4 -1: (F)V
+7 -1: ibm-819
+9 -1: H_ESCAPED
+4 -1: (F)Z
+20 -1: suppressedExceptions
+12 -1: UTF-32LE-BOM
+19 -1: CalendarSystem.java
+8 -1: readOnly
+81 -1: (JLjava/util/function/Function;Ljava/util/function/BiFunction;)Ljava/lang/Object;
+32 -1: sun/misc/Launcher$AppClassLoader
+78 -1: Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/io/File;>;
+17 -1: [Ljava/lang/Enum;
+41 -1: java/util/Collections$CheckedNavigableSet
+8 -1: asSetter
+3 -1: dom
+41 -1: (I)[Ljava/util/WeakHashMap$Entry<TK;TV;>;
+16 -1: localeExtensions
+21 -1: sun/net/www/ParseUtil
+21 -1: Ljava/nio/ByteBuffer;
+29 -1: java/util/concurrent/TimeUnit
+25 -1: java/lang/CharacterData00
+15 -1: sun/misc/Unsafe
+28 -1: java/io/ByteArrayInputStream
+3 -1: dow
+25 -1: java/lang/CharacterData01
+25 -1: java/lang/CharacterData02
+6 -1: STORED
+11 -1: isTransient
+8 -1: function
+16 -1: getCanonicalFile
+13 -1: ,useDaylight=
+24 -1: domain (context is null)
+12 -1: Cleaner.java
+17 -1: CalendarDate.java
+49 -1: Lsun/reflect/generics/repository/FieldRepository;
+14 -1: forInputString
+25 -1: java/lang/CharacterData0E
+67 -1: (Ljava/lang/Object;Ljava/util/function/Supplier;)Ljava/lang/Object;
+19 -1: codePointBeforeImpl
+6 -1: script
+21 -1: systemNativeLibraries
+38 -1: ([Ljava/lang/Class;)Ljava/lang/String;
+14 -1: CONTENT_LENGTH
+19 -1: HeapCharBuffer.java
+22 -1: ExtendedProviderHolder
+41 -1: java/lang/invoke/InvokerBytecodeGenerator
+12 -1: basicInvoker
+26 -1: ([Ljava/lang/Comparable;)V
+10 -1: val$tclass
+47 -1: (Ljava/lang/Throwable;)Lsun/invoke/empty/Empty;
+18 -1: isLegalReplacement
+22 -1: spliteratorUnknownSize
+15 -1: SynchronizedSet
+16 -1: MethodParameters
+22 -1: desiredAssertionStatus
+29 -1: ()Ljava/util/ArrayDeque<TE;>;
+36 -1: ()Ljava/lang/reflect/Constructor<*>;
+66 -1: ()Ljava/util/Map<Ljava/lang/String;Ljava/lang/invoke/LambdaForm;>;
+58 -1: (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V
+50 -1: (Ljava/util/concurrent/CountedCompleter;[J[JIIII)V
+14 -1: requireNonNull
+21 -1: java/lang/ThreadGroup
+95 -1: ([Ljava/util/concurrent/ConcurrentHashMap$Node;ILjava/util/concurrent/ConcurrentHashMap$Node;)V
+76 -1: (Ljava/nio/channels/WritableByteChannel;Ljava/nio/charset/CharsetEncoder;I)V
+14 -1: reflectionData
+33 -1: Ljava/lang/invoke/MethodTypeForm;
+7 -1: tuesday
+31 -1: ()Lsun/misc/JavaSecurityAccess;
+14 -1: fieldFilterMap
+28 -1: ([Ljava/lang/ThreadGroup;Z)I
+7 -1: ibm-850
+83 -1: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/management/GarbageCollectorMXBean;
+7 -1: ibm-852
+5 -1: cesu8
+14 -1: ForwardingNode
+29 -1: (Ljava/nio/ByteBuffer;IIIII)V
+7 -1: ibm-855
+12 -1: SingletonSet
+16 -1: isOtherUppercase
+15 -1: FIELD_UNDEFINED
+9 -1: makeEntry
+7 -1: ibm-857
+10 -1: extensions
+10 -1: longStream
+19 -1: getGenericSignature
+7 -1: newNode
+8 -1: jarNames
+25 -1: java/util/jar/JarVerifier
+49 -1: ()[Lsun/reflect/generics/tree/ClassTypeSignature;
+4 -1: wait
+115 -1: (Ljava/lang/String;Lsun/reflect/generics/factory/GenericsFactory;)Lsun/reflect/generics/repository/ClassRepository;
+56 -1: (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
+65 -1: (Lsun/util/locale/BaseLocale;Lsun/util/locale/LocaleExtensions;)V
+7 -1: ibm-862
+9 -1: ISO646-US
+7 -1: ibm-866
+16 -1: extendedProvider
+7 -1: ([C[C)Z
+93 -1: (Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
+8 -1: getHours
+21 -1: ()[Ljava/lang/String;
+187 -1: (Ljava/util/concurrent/ConcurrentHashMap$BulkTask;III[Ljava/util/concurrent/ConcurrentHashMap$Node;Ljava/util/concurrent/ConcurrentHashMap$ReduceKeysTask;Ljava/util/function/BiFunction;)V
+106 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/concurrent/locks/ReentrantLock;Ljava/io/Serializable;
+24 -1: java/nio/file/FileSystem
+14 -1: ForEachKeyTask
+13 -1: defaultLocale
+20 -1: constructorModifiers
+13 -1: asWrapperType
+42 -1: (Ljava/lang/String;ZI)Ljava/lang/Class<*>;
+17 -1: BaseCalendar.java
+76 -1: (Ljava/util/jar/JarFile;Ljava/util/jar/JarEntry;)[Ljava/security/CodeSigner;
+14 -1: isSynchronized
+27 -1: java/nio/DirectByteBuffer$1
+3 -1: ()B
+7 -1: ibm-874
+12 -1: exactInvoker
+3 -1: ()C
+39 -1: (Ljava/lang/Thread;Ljava/lang/Object;)V
+3 -1: ()D
+3 -1: ()F
+27 -1: [Ljava/lang/reflect/Method;
+10 -1: floatValue
+3 -1: ()I
+3 -1: ()J
+18 -1: getLocaleResources
+59 -1: java/util/concurrent/ConcurrentHashMap$MapReduceEntriesTask
+67 -1: (ILjava/lang/Object;Ljava/lang/Object;Ljava/util/Hashtable$Entry;)V
+11 -1: maxPriority
+11 -1: getStringAt
+60 -1: (Ljava/lang/ClassValue$Version;)Ljava/lang/ClassValue$Entry;
+3 -1: ()S
+49 -1: (Ljava/lang/String;)Ljava/io/ExpiringCache$Entry;
+42 -1: (III)Lsun/util/calendar/BaseCalendar$Date;
+82 -1: <T:Ljava/lang/Object;>(Ljava/util/Set<TT;>;Ljava/lang/Object;)Ljava/util/Set<TT;>;
+62 -1: ([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/util/Map;
+3 -1: ()V
+24 -1: ()Ljava/nio/ShortBuffer;
+29 -1: file descriptor can't be null
+3 -1: ()Z
+7 -1: matcher
+66 -1: (Ljava/lang/reflect/Constructor;)Lsun/reflect/ConstructorAccessor;
+7 -1: matches
+12 -1: getAuthority
+16 -1: java/lang/Object
+5 -1: (IC)V
+17 -1: EmptyListIterator
+8 -1: charsets
+8 -1: sameFile
+47 -1: (TT;Ljava/util/function/UnaryOperator<TV;>;)TV;
+16 -1: overwrittenEntry
+15 -1: reinvokerTarget
+11 -1: isUpperCase
+5 -1: toUri
+9 -1: GMT+00:00
+33 -1: java/util/concurrent/ForkJoinPool
+10 -1: parseFloat
+53 -1: java/util/concurrent/ConcurrentHashMap$SearchKeysTask
+48 -1: (Ljava/lang/Object;Ljava/util/LinkedList$Node;)V
+82 -1: (Ljava/lang/Class<*>;Ljava/lang/Class<*>;Ljava/lang/Object;ILjava/lang/Class<*>;)V
+15 -1: reduceCacheLoad
+76 -1: (Ljava/lang/Class<*>;[Ljava/lang/reflect/Method;)[Ljava/lang/reflect/Method;
+20 -1: singletonSpliterator
+24 -1: getTransitionEpochSecond
+24 -1: MapReduceValuesToIntTask
+13 -1: ALLOWED_FLAGS
+55 -1: (Ljava/lang/reflect/Field;Z)Lsun/reflect/FieldAccessor;
+34 -1: [Ljava/lang/annotation/Annotation;
+10 -1: readBuffer
+21 -1: Illegal month value: 
+31 -1: java/security/SecureClassLoader
+12 -1: reinitialize
+5 -1: limit
+4 -1: grow
+15 -1: getCreationTime
+7 -1: , from 
+25 -1: (Ljava/lang/ClassValue;)V
+13 -1: java.compiler
+37 -1: ()Ljava/util/Set<Ljava/lang/String;>;
+6 -1: FJChar
+16 -1: getFieldAccessor
+4 -1: eras
+11 -1: isSupported
+24 -1: ()Ljava/text/DateFormat;
+32 -1: java/util/Collections$CopiesList
+32 -1: java/io/NotSerializableException
+15 -1: typeAnnotations
+27 -1: defaultAllowUserInteraction
+57 -1: (Ljava/lang/String;I[Ljava/lang/invoke/LambdaForm$Name;)V
+18 -1: checkArgumentTypes
+71 -1: (Lsun/util/calendar/BaseCalendar$Date;)Lsun/util/calendar/BaseCalendar;
+10 -1: isMirrored
+27 -1: (I)Ljava/lang/Thread$State;
+26 -1: (Ljava/util/Collection;Z)Z
+6 -1: ibm367
+16 -1: isAssignableFrom
+7 -1: readUTF
+35 -1: Ljava/lang/ref/ReferenceQueue<TV;>;
+56 -1: ([Ljava/util/HashMap$Node;Ljava/util/HashMap$TreeNode;)V
+8 -1: MANDATED
+18 -1: canonicalizeRegion
+11 -1: checkAccept
+44 -1: (Ljava/net/Proxy;)Lsun/net/ApplicationProxy;
+8 -1: ECMA-118
+22 -1: ReflectPermission.java
+4 -1: _put
+41 -1: java.lang.invoke.MethodHandle.DEBUG_NAMES
+47 -1: java/util/concurrent/ConcurrentHashMap$TreeNode
+44 -1: (Ljava/net/URL;[Ljava/security/CodeSigner;)V
+5 -1: april
+44 -1: ([Ljava/lang/Class<*>;Ljava/lang/Class<*>;)V
+150 -1: <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/concurrent/ConcurrentHashMap$CollectionView<TK;TV;TK;>;Ljava/util/Set<TK;>;Ljava/io/Serializable;
+91 -1: (ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)Ljava/util/HashMap$TreeNode;
+26 -1: sun/net/util/IPAddressUtil
+8 -1: Modifier
+9 -1: isVarargs
+24 -1: -- listing properties --
+16 -1: hasAllPermission
+27 -1: MapReduceMappingsToLongTask
+29 -1: sharedGetParameterAnnotations
+9 -1: argCounts
+11 -1: toLocalTime
+89 -1: (Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MemberName;
+4 -1: ROOT
+20 -1: sun.reflect.noCaches
+18 -1: UnicodeBigUnmarked
+4 -1: Lazy
+35 -1: java/lang/invoke/SimpleMethodHandle
+20 -1: (I)Ljava/nio/Buffer;
+48 -1: ()Lsun/reflect/generics/tree/ClassTypeSignature;
+31 -1: (I[CII)Ljava/lang/StringBuffer;
+17 -1: America/Anchorage
+7 -1: markpos
+9 -1: enumerate
+11 -1: parseLocale
+24 -1: java.launcher.cls.error1
+46 -1: (ILjava/lang/Object;)Ljava/lang/StringBuilder;
+24 -1: java.launcher.cls.error2
+24 -1: java.launcher.cls.error3
+24 -1: java.launcher.cls.error4
+21 -1: java/util/ArrayList$1
+17 -1: getExceptionTypes
+24 -1: java.launcher.cls.error5
+30 -1: java/util/Spliterator$OfDouble
+10 -1: forDecoder
+8 -1: getEntry
+10 -1: checkGuard
+12 -1: checkInitted
+34 -1: Lsun/util/locale/LocaleExtensions;
+41 -1: java/util/ArraysParallelSortHelpers$FJInt
+10 -1: findStatic
+22 -1: setConstructorAccessor
+34 -1: Lsun/misc/URLClassPath$FileLoader;
+20 -1: not a reinvoker MH: 
+16 -1: LongCumulateTask
+11 -1: checkAccess
+14 -1: SearchKeysTask
+36 -1: ()[Ljava/lang/reflect/AnnotatedType;
+11 -1: initDefault
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/FieldAnnotationsTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test for field annotations.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/FieldAnnotationsApp.java test-classes/MyAnnotation.java
+ * @run main FieldAnnotationsTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+// This is a test for the handling of multi-dimensional Arrays in MetaspaceClosure.
+//
+// We choose FieldAnnotations because they happen to be implemented as a multi-dimension
+// Array (Annotations::_fields_annotations, which is of type Array<Array<unsigned char>*>*,
+// and is handled by the template class PointerArrayRef<T> in metaspaceClosure.hpp).
+//
+// Specifically, we are testing the following C code, where _fields_annotations is non-NULL:
+//
+// void Annotations::metaspace_pointers_do(MetaspaceClosure* it) {
+//   ...
+//   it->push(&_fields_annotations);
+//
+// which will be matched with the function
+//
+// template <typename T> void MetaspaceClosure::push(Array<T*>** mpp, Writability w = _default)
+//
+public class FieldAnnotationsTest {
+    public static void main(String[] args) throws Exception {
+        String[] ARCHIVE_CLASSES = {"FieldAnnotationsApp", "MyAnnotation"};
+        String appJar = JarBuilder.build("FieldAnnotationsTest", ARCHIVE_CLASSES);
+
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+                appJar, ARCHIVE_CLASSES);
+        TestCommon.checkDump(dumpOutput);
+
+        OutputAnalyzer execOutput = TestCommon.exec(appJar, "FieldAnnotationsApp");
+        TestCommon.checkExec(execOutput, "Field annotations are OK.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/FreeUnusedMetadata.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Unused metadata created during dump time should be freed from the CDS archive.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile test-classes/MethodNoReturn.jasm test-classes/Hello.java
+ * @run main FreeUnusedMetadata
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class FreeUnusedMetadata {
+    static byte iconst_1 =  4;
+    static byte pop      = 87;
+    static byte[] pattern = { // This has the same sequence as in test-classes/MethodNoReturn.jasm
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        pop,
+        iconst_1,
+        iconst_1,
+        iconst_1,
+        iconst_1,
+        iconst_1,
+        iconst_1,
+        iconst_1,
+        iconst_1,
+        pop,
+        pop,
+        pop,
+        pop,
+        pop,
+        pop,
+        pop,
+        pop
+    };
+
+    public static void main(String[] args) throws Exception {
+        String[] ARCHIVE_CLASSES = {"Hello", "MethodNoReturn"};
+        String appJar = JarBuilder.build("FreeUnusedMetadata", ARCHIVE_CLASSES);
+
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+                appJar, ARCHIVE_CLASSES);
+        TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+        OutputAnalyzer execOutput = TestCommon.exec(appJar, "Hello");
+        TestCommon.checkExec(execOutput, "Hello World");
+
+
+        String archive = TestCommon.getCurrentArchiveName();
+        System.out.println("Checking for pattern inside " + archive + "...");
+
+        byte[] data = Files.readAllBytes(Paths.get(archive));
+        int max = data.length - pattern.length;
+        for (int i=0; i<max; i++) {
+            if (data[i+0] == iconst_1 && data[i+1] == pop &&
+                data[i+2] == iconst_1 && data[i+3] == pop) {
+                boolean match = true;
+                for (int x=4; x<pattern.length; x++) {
+                    if (data[i+x] != pattern[x]) {
+                        match = false;
+                        break;
+                    }
+                }
+
+                if (match) {
+                    throw new RuntimeException("method of unverifiable class should have been " +
+                        "removed from the archive " + archive +
+                        " , but was found at offset " + i);
+                }
+            }
+        }
+        System.out.println("Not found: method from unverifiable class has been removed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/HelloExtTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary a simple test for loading a class using the ext class loader in AppCDS
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @compile test-classes/HelloExt.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main HelloExtTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class HelloExtTest {
+
+  public static void main(String[] args) throws Exception {
+    JarBuilder.build("helloExt", "HelloExt");
+
+    String appJar = TestCommon.getTestJar("helloExt.jar");
+    JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+    String whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
+    String bootClassPath = "-Xbootclasspath/a:" + whiteBoxJar;
+
+    TestCommon.dump(appJar,
+        TestCommon.list("org/omg/CORBA/ORB", "[Ljava/lang/Comparable;"),
+        bootClassPath, "-verbose:class", "--add-modules", "java.corba");
+
+    OutputAnalyzer output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+        "-cp", appJar, bootClassPath, "-verbose:class", "--add-modules", "java.corba", "HelloExt");
+
+    String prefix = ".class.load. ";
+    String class_pattern = ".*LambdaForm[$]MH[/][0123456789].*";
+    String suffix = ".*source: shared objects file.*";
+    String pattern = prefix + class_pattern + suffix;
+    output.shouldNotMatch(pattern);
+
+    output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+        "-cp", appJar, bootClassPath, "-verbose:class",
+        "-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary",
+        "--add-modules", "java.corba", "HelloExt");
+    output.shouldNotMatch(class_pattern);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/HelloTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Hello World test for AppCDS
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main HelloTest
+ */
+
+public class HelloTest {
+
+  public static void main(String[] args) throws Exception {
+      TestCommon.test(JarBuilder.getOrCreateHelloJar(),
+          TestCommon.list("Hello"), "Hello");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/IgnoreEmptyClassPaths.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test the -XX:+IgnoreEmptyClassPaths flag
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run main IgnoreEmptyClassPaths
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class IgnoreEmptyClassPaths {
+
+  public static void main(String[] args) throws Exception {
+    String jar1 = JarBuilder.getOrCreateHelloJar();
+    String jar2 = JarBuilder.build("IgnoreEmptyClassPaths_more", "HelloMore");
+
+    String sep = File.pathSeparator;
+    String cp_dump = jar1 + sep + jar2 + sep;
+    String cp_exec = sep + jar1 + sep + sep + jar2 + sep;
+
+    TestCommon.testDump(cp_dump, TestCommon.list("Hello", "HelloMore"),
+                        "-XX:+TraceClassPaths", "-XX:+IgnoreEmptyClassPaths");
+
+    OutputAnalyzer output = TestCommon.execCommon(
+        "-verbose:class",
+        "-cp", cp_exec,
+        "-XX:+IgnoreEmptyClassPaths", // should affect classpath even if placed after the "-cp" argument
+        "-XX:+TraceClassPaths",
+        "HelloMore");
+    TestCommon.checkExec(output);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/JarBuilder.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @summary Simple jar builder
+ *   Input: jarName className1 className2 ...
+ *     do not specify extensions, just the names
+ *     E.g. prot_domain ProtDomainA ProtDomainB
+ *   Output: A jar containing compiled classes, placed in a test classes folder
+ * @library /open/test/lib
+ */
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import java.io.File;
+import java.util.ArrayList;
+import sun.tools.jar.Main;
+
+public class JarBuilder {
+    // to turn DEBUG on via command line: -DJarBuilder.DEBUG=[true, TRUE]
+    private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("JarBuilder.DEBUG", "false"));
+    private static final String classDir = System.getProperty("test.classes");
+
+    public static String getJarFilePath(String jarName) {
+        return classDir + File.separator + jarName + ".jar";
+    }
+
+    // jar all files under dir, with manifest file man, with an optional versionArgs
+    // for generating a multi-release jar.
+    // The jar command is as follows:
+    // jar cmf \
+    //  <path to output jar> <path to the manifest file>\
+    //   -C <path to the base classes> .\
+    //    --release 9 -C <path to the versioned classes> .
+    // the last line begins with "--release" corresponds to the optional versionArgs.
+    public static void build(String jarName, File dir, String man, String ...versionArgs)
+        throws Exception {
+        ArrayList<String> args = new ArrayList<String>();
+        if (man != null) {
+            args.add("cfm");
+        } else {
+            args.add("cf");
+        }
+        args.add(classDir + File.separator + jarName + ".jar");
+        if (man != null) {
+            args.add(man);
+        }
+        args.add("-C");
+        args.add(dir.getAbsolutePath());
+        args.add(".");
+        for (String verArg : versionArgs) {
+            args.add(verArg);
+        }
+        createJar(args);
+    }
+
+    public static String build(String jarName, String ...classNames)
+        throws Exception {
+
+        return createSimpleJar(classDir, getJarFilePath(jarName), classNames);
+    }
+
+    public static String build(boolean classesInWorkDir, String jarName, String ...classNames)
+        throws Exception {
+        if (classesInWorkDir) {
+            return createSimpleJar(".", getJarFilePath(jarName), classNames);
+        } else {
+            return build(jarName, classNames);
+        }
+    }
+
+
+    public static String buildWithManifest(String jarName, String manifest,
+        String jarClassesDir, String ...classNames) throws Exception {
+        String jarPath = getJarFilePath(jarName);
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("cvfm");
+        args.add(jarPath);
+        args.add(System.getProperty("test.src") + File.separator + "test-classes"
+            + File.separator + manifest);
+        addClassArgs(args, jarClassesDir, classNames);
+        createJar(args);
+
+        return jarPath;
+    }
+
+
+    // Execute: jar uvf $jarFile -C $dir .
+    static void update(String jarFile, String dir) throws Exception {
+        String jarExe = JDKToolFinder.getJDKTool("jar");
+
+        ArrayList<String> args = new ArrayList<>();
+        args.add(jarExe);
+        args.add("uvf");
+        args.add(jarFile);
+        args.add("-C");
+        args.add(dir);
+        args.add(".");
+
+        executeProcess(args.toArray(new String[1]));
+    }
+
+
+    private static String createSimpleJar(String jarclassDir, String jarName,
+        String[] classNames) throws Exception {
+
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("cf");
+        args.add(jarName);
+        addClassArgs(args, jarclassDir, classNames);
+        createJar(args);
+
+        return jarName;
+    }
+
+    private static void addClassArgs(ArrayList<String> args, String jarclassDir,
+        String[] classNames) {
+
+        for (String name : classNames) {
+            args.add("-C");
+            args.add(jarclassDir);
+            args.add(name + ".class");
+        }
+    }
+
+    private static void createJar(ArrayList<String> args) {
+        if (DEBUG) printIterable("createJar args: ", args);
+
+        Main jarTool = new Main(System.out, System.err, "jar");
+        if (!jarTool.run(args.toArray(new String[1]))) {
+            throw new RuntimeException("jar operation failed");
+        }
+    }
+
+    // Many AppCDS tests use the same simple "Hello.jar" which contains
+    // simple Hello.class and does not specify additional attributes.
+    // For this common use case, use this method to get the jar path.
+    // The method will check if the jar already exists
+    // (created by another test or test run), and will create the jar
+    // if it does not exist
+    public static String getOrCreateHelloJar() throws Exception {
+        String jarPath = getJarFilePath("hello");
+
+        File jarFile = new File(jarPath);
+        if (jarFile.exists()) {
+            return jarPath;
+        } else {
+            return build("hello", "Hello");
+        }
+    }
+
+    public static void compile(String dstPath, String source, String... extraArgs) throws Exception {
+        ArrayList<String> args = new ArrayList<String>();
+        args.add(JDKToolFinder.getCompileJDKTool("javac"));
+        args.add("-d");
+        args.add(dstPath);
+        if (extraArgs != null) {
+            for (String s : extraArgs) {
+                args.add(s);
+            }
+        }
+        args.add(source);
+
+        if (DEBUG) printIterable("compile args: ", args);
+
+        ProcessBuilder pb = new ProcessBuilder(args);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void signJar() throws Exception {
+        String keyTool = JDKToolFinder.getJDKTool("keytool");
+        String jarSigner = JDKToolFinder.getJDKTool("jarsigner");
+        String classDir = System.getProperty("test.classes");
+        String FS = File.separator;
+
+        executeProcess(keyTool,
+            "-genkey", "-keystore", "./keystore", "-alias", "mykey",
+            "-storepass", "abc123", "-keypass", "abc123",
+            "-dname", "CN=jvmtest")
+            .shouldHaveExitValue(0);
+
+        executeProcess(jarSigner,
+           "-keystore", "./keystore", "-storepass", "abc123", "-keypass",
+           "abc123", "-signedjar", classDir + FS + "signed_hello.jar",
+           classDir + FS + "hello.jar", "mykey")
+           .shouldHaveExitValue(0);
+    }
+
+    private static OutputAnalyzer executeProcess(String... cmds)
+        throws Exception {
+
+        JarBuilder.printArray("executeProcess: ", cmds);
+        return ProcessTools.executeProcess(new ProcessBuilder(cmds));
+    }
+
+    // diagnostic
+    public static void printIterable(String msg, Iterable<String> l) {
+        StringBuilder sum = new StringBuilder();
+        for (String s : l) {
+            sum.append(s).append(' ');
+        }
+        System.out.println(msg + sum.toString());
+    }
+
+    public static void printArray(String msg, String[] l) {
+        StringBuilder sum = new StringBuilder();
+        for (String s : l) {
+            sum.append(s).append(' ');
+        }
+        System.out.println(msg + sum.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary JvmtiEnv::AddToBootstrapClassLoaderSearch and JvmtiEnv::AddToSystemClassLoaderSearch should disable AppCDS
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @bug 8060592
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @compile test-classes/Hello.java
+ * @compile test-classes/JvmtiApp.java
+ * @run main JvmtiAddPath
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+public class JvmtiAddPath {
+    static String use_whitebox_jar;
+    static String[] no_extra_matches = {};
+    static String[] check_appcds_enabled = {
+        "[class,load] ExtraClass source: shared object"
+    };
+    static String[] check_appcds_disabled = {
+        "[class,load] ExtraClass source: file:"
+    };
+
+    static void run(String cp, String... args) throws Exception {
+        run(no_extra_matches, cp, args);
+    }
+
+    static void run(String[] extra_matches, String cp, String... args) throws Exception {
+        String[] opts = {"-cp", cp, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", use_whitebox_jar};
+        opts = TestCommon.concat(opts, args);
+        OutputAnalyzer output = TestCommon.execCommon(opts);
+        TestCommon.checkExec(output, extra_matches);
+    }
+
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("jvmti_addboot", "Hello");
+        JarBuilder.build("jvmti_addapp", "Hello");
+        JarBuilder.build("jvmti_app", "JvmtiApp", "ExtraClass");
+        JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+
+        // In all the test cases below, appJar does not contain Hello.class. Instead, we
+        // append JAR file(s) that contain Hello.class to the boot classpath, the app
+        // classpath, or both, and verify that Hello.class is loaded by the expected ClassLoader.
+        String appJar = TestCommon.getTestJar("jvmti_app.jar");         // contains JvmtiApp.class
+        String addappJar = TestCommon.getTestJar("jvmti_addapp.jar");   // contains Hello.class
+        String addbootJar = TestCommon.getTestJar("jvmti_addboot.jar"); // contains Hello.class
+        String twoAppJars = appJar + File.pathSeparator + addappJar;
+        String wbJar = TestCommon.getTestJar("WhiteBox.jar");
+        use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        TestCommon.testDump(appJar, TestCommon.list("JvmtiApp", "ExtraClass"), use_whitebox_jar);
+
+        System.out.println("Test case 1: not adding any paths - Hello.class should not be found");
+        run(check_appcds_enabled, appJar, "-Xlog:class+load", "JvmtiApp", "noadd"); // appcds should be enabled
+
+        System.out.println("Test case 2: add to boot classpath only - should find Hello.class in boot loader");
+        run(check_appcds_disabled, appJar, "-Xlog:class+load", "JvmtiApp", "bootonly", addbootJar); // appcds should be disabled
+
+        System.out.println("Test case 3: add to app classpath only - should find Hello.class in app loader");
+        run(appJar, "JvmtiApp", "apponly", addappJar);
+
+        System.out.println("Test case 4: add to boot and app paths - should find Hello.class in boot loader");
+        run(appJar, "JvmtiApp", "appandboot", addbootJar, addappJar);
+
+        System.out.println("Test case 5: add to app using -cp, but add to boot using JVMTI - should find Hello.class in boot loader");
+        run(twoAppJars, "JvmtiApp", "bootonly", addappJar);
+
+        System.out.println("Test case 6: add to app using AppCDS, but add to boot using JVMTI - should find Hello.class in boot loader");
+        TestCommon.testDump(twoAppJars, TestCommon.list("JvmtiApp", "ExtraClass", "Hello"), use_whitebox_jar);
+        run(twoAppJars, "JvmtiApp", "bootonly", addappJar);
+
+        System.out.println("Test case 7: add to app using AppCDS, no JVMTI calls - should find Hello.class in app loader");
+        run(twoAppJars, "JvmtiApp", "noadd-appcds");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/MismatchedUseAppCDS.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Try different combination of mismatched UseAppCDS between dump time and run time.
+ * (Note: AppCDS does not support uncompressed oops.)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/CheckIfShared.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main MismatchedUseAppCDS
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class MismatchedUseAppCDS {
+  public static void main(String[] args) throws Exception {
+    String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+    String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+    String appJar = JarBuilder.build("MismatchedUseAppCDS", "CheckIfShared");
+
+    OutputAnalyzer output;
+
+    // (1): dump with -XX:+UseAppCDS, but run with -XX:-UseAppCDS
+    TestCommon.testDump(appJar, TestCommon.list("CheckIfShared"),
+                        // command-line arguments ...
+                        "-XX:+UseAppCDS",
+                        use_whitebox_jar);
+
+    output = TestCommon.exec(appJar,
+                             // command-line arguments ...
+                             use_whitebox_jar,
+                             "-XX:-UseAppCDS",
+                             "-XX:+UnlockDiagnosticVMOptions",
+                             "-XX:+WhiteBoxAPI",
+                             "CheckIfShared", "false");
+    TestCommon.checkExec(output);
+
+    // (2): dump with -XX:-UseAppCDS, but run with -XX:+UseAppCDS
+    TestCommon.testDump(appJar, TestCommon.list("CheckIfShared"),
+                        // command-line arguments ...
+                        "-XX:-UseAppCDS",
+                        use_whitebox_jar);
+
+    output = TestCommon.exec(appJar,
+                             // command-line arguments ...
+                             use_whitebox_jar,
+                             "-XX:+UseAppCDS",
+                             "-XX:+UnlockDiagnosticVMOptions",
+                             "-XX:+WhiteBoxAPI",
+                             "CheckIfShared", "false");
+    TestCommon.checkExec(output);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/MissingSuperTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary When super class is missing during dumping, no crash should happen.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/MissingSuper.java
+ * @run main MissingSuperTest
+ */
+
+public class MissingSuperTest {
+
+  public static void main(String[] args) throws Exception {
+    // The classes "MissingSuperSup" and "MissingSuperIntf" are intentionally not
+    // included into the jar to provoke the test condition
+    JarBuilder.build("missing_super", "MissingSuper",
+        "MissingSuperSub", "MissingSuperImpl");
+
+    String appJar = TestCommon.getTestJar("missing_super.jar");
+    TestCommon.test(appJar, TestCommon.list("MissingSuper",
+        "MissingSuperSub",
+        "MissingSuperImpl"),
+        "MissingSuper");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/MultiProcessSharing.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Run multiple processes with the same archive, ensure they share
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @compile test-classes/MultiProcClass.java
+ * @run main MultiProcessSharing
+ */
+
+import java.io.File;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+
+public class MultiProcessSharing {
+    static String useWbJar;
+    static String sharedClass1Jar;
+    static boolean checkPmap = false;
+
+    public static void main(String[] args) throws Exception {
+        String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        useWbJar = "-Xbootclasspath/a:" + wbJar;
+        sharedClass1Jar = JarBuilder.build("shared_class1", "MultiProcClass");
+
+        // create an archive
+        OutputAnalyzer out = TestCommon.dump(sharedClass1Jar,
+            TestCommon.list("MultiProcClass"), useWbJar);
+        TestCommon.checkDump(out);
+
+        // determine whether OK to use pmap for extra test verification
+        long myPid = ProcessHandle.current().pid();
+        checkPmap = (Platform.isLinux() && (MultiProcClass.runPmap(myPid, false) == 0));
+        System.out.println("MultiProcessSharing: checkPmap is " + checkPmap);
+
+        // use an archive in several processes concurrently
+        int numProcesses = 3;
+        Thread[] threads = new Thread[numProcesses];
+        ProcessHandler[] processHandlers = new ProcessHandler[numProcesses];
+        for (int i = 0; i < numProcesses; i++) {
+            processHandlers[i] = new ProcessHandler(i);
+            threads[i] = new Thread(processHandlers[i]);
+        }
+
+        for (Thread t : threads) {
+            t.start();
+        }
+
+        for (Thread t : threads) {
+            try {
+                t.join();
+            } catch (InterruptedException ie) {
+                throw ie;
+            }
+        }
+
+        // check results
+        for (ProcessHandler ph : processHandlers) {
+            TestCommon.checkExec(ph.out);
+            if (checkPmap && !TestCommon.isUnableToMap(ph.out)) {
+                checkPmapOutput(ph.out.getOutput());
+            }
+        }
+    }
+
+
+    static class ProcessHandler implements Runnable {
+        int processNumber;
+        OutputAnalyzer out;
+
+        ProcessHandler(int processNumber) {
+            this.processNumber = processNumber;
+        }
+
+        @Override
+        public void run() {
+            try {
+                out = TestCommon.exec(sharedClass1Jar,
+                   "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", useWbJar,
+                   "MultiProcClass", "" + processNumber, "" + checkPmap);
+            } catch (Exception e) {
+                throw new RuntimeException("Error occurred when using archive, exec()" + e);
+            }
+        }
+    }
+
+
+    private static void checkPmapOutput(String stdio) {
+        System.out.println("Checking pmap output ...");
+        String[] lines = stdio.split("\n");
+
+        boolean foundJsa = false;
+        boolean foundReadOnlyJsaSection = false;
+
+        for (String line : lines) {
+            if (line.contains(TestCommon.getCurrentArchiveName()))
+                System.out.println(line);
+                foundJsa = true;
+                if (line.contains("r--")) {
+                    foundReadOnlyJsaSection = true;
+                }
+
+                // On certain ARM platforms system maps r/o memory mapped files
+                // as r/x; see JDK-8145694 for details
+                if ( (Platform.isARM() || Platform.isAArch64()) && line.contains("r-x") ) {
+                    foundReadOnlyJsaSection = true;
+                }
+        }
+
+        Asserts.assertTrue(foundJsa && foundReadOnlyJsaSection);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/MultiReleaseJars.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test MultiReleaseJars
+ * @bug 8170105
+ * @summary Test multi-release jar with AppCDS.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @run main/othervm MultiReleaseJars
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class MultiReleaseJars {
+
+    static final int MAJOR_VERSION = Runtime.version().major();
+    static final String MAJOR_VERSION_STRING = String.valueOf(Runtime.version().major());
+
+    static String[] getMain() {
+        String[] sts = {
+            "package version;",
+            "public class Main {",
+            "    public static void main(String[] args) {",
+            "        Version version = new Version();",
+            "        System.out.println(\"I am running on version \" + version.getVersion());",
+            "    }",
+            "}"
+        };
+        return sts;
+    }
+
+    static String[] getVersion(int version) {
+        String[] sts = {
+            "package version;",
+            "public class Version {",
+            "    public int getVersion(){ return " + version + "; }",
+            "}"
+        };
+        return sts;
+    }
+
+    static void writeFile(File file, String... contents) throws Exception {
+        if (contents == null) {
+            throw new java.lang.RuntimeException("No input for writing to file" + file);
+        }
+        FileOutputStream fos = new FileOutputStream(file);
+        PrintStream ps = new PrintStream(fos);
+        for (String str : contents) {
+            ps.println(str);
+        }
+        ps.close();
+        fos.close();
+    }
+
+    /* version.jar entries and files:
+     * META-INF/
+     * META-INF/MANIFEST.MF
+     * version/
+     * version/Main.class
+     * version/Version.class
+     * META-INF/versions/
+     * META-INF/versions/<major-version>/
+     * META-INF/versions/<major-version>/version/
+     * META-INF/versions/<major-version>/version/Version.class
+     */
+    static void createClassFilesAndJar() throws Exception {
+        String tempDir = System.getProperty("test.classes");
+        File baseDir = new File(tempDir + File.separator + "base");
+        File vDir    = new File(tempDir + File.separator + MAJOR_VERSION_STRING);
+
+        baseDir.mkdirs();
+        vDir.mkdirs();
+
+        File fileMain = TestCommon.getOutputSourceFile("Main.java");
+        writeFile(fileMain, getMain());
+
+        File fileVersion = TestCommon.getOutputSourceFile("Version.java");
+        writeFile(fileVersion, getVersion(7));
+        JarBuilder.compile(baseDir.getAbsolutePath(), fileVersion.getAbsolutePath(), "--release", "7");
+        JarBuilder.compile(baseDir.getAbsolutePath(), fileMain.getAbsolutePath(),
+            "-cp", baseDir.getAbsolutePath(), "--release", MAJOR_VERSION_STRING);
+
+        String[] meta = {
+            "Multi-Release: true",
+            "Main-Class: version.Main"
+        };
+        File metainf = new File(tempDir, "mf.txt");
+        writeFile(metainf, meta);
+
+        fileVersion = TestCommon.getOutputSourceFile("Version.java");
+        writeFile(fileVersion, getVersion(MAJOR_VERSION));
+        JarBuilder.compile(vDir.getAbsolutePath(), fileVersion.getAbsolutePath(), "--release", MAJOR_VERSION_STRING);
+
+        JarBuilder.build("version", baseDir, metainf.getAbsolutePath(),
+            "--release", MAJOR_VERSION_STRING, "-C", vDir.getAbsolutePath(), ".");
+
+        // the following jar file is for testing case-insensitive "Multi-Release"
+        // attibute name
+        String[] meta2 = {
+            "multi-Release: true",
+            "Main-Class: version.Main"
+        };
+        metainf = new File(tempDir, "mf2.txt");
+        writeFile(metainf, meta2);
+        JarBuilder.build("version2", baseDir, metainf.getAbsolutePath(),
+            "--release", MAJOR_VERSION_STRING, "-C", vDir.getAbsolutePath(), ".");
+    }
+
+    static void checkExecOutput(OutputAnalyzer output, String expectedOutput) throws Exception {
+        try {
+            TestCommon.checkExec(output, expectedOutput);
+        } catch (java.lang.RuntimeException re) {
+            String cause = re.getMessage();
+            if (!expectedOutput.equals(cause)) {
+                throw re;
+            }
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        // create version.jar which contains Main.class and Version.class.
+        // Version.class has two versions: 8 and the current version.
+        createClassFilesAndJar();
+
+        String mainClass          = "version.Main";
+        String loadInfo           = "[class,load] version.Version source: shared objects file";
+        String appClasses[]       = {"version/Main", "version/Version"};
+        String appJar             = TestCommon.getTestJar("version.jar");
+        String appJar2            = TestCommon.getTestJar("version2.jar");
+        String verboseMode        = "-verbose:class";
+        String enableMultiRelease = "-Djdk.util.jar.enableMultiRelease=true";
+        String jarVersion         = null;
+        String expectedOutput     = null;
+
+        // 1. default to highest version
+        //    if META-INF/versions exists, no other commandline options like -Djdk.util.jar.version and
+        //    -Djdk.util.jar.enableMultiRelease passed to vm
+        OutputAnalyzer output = TestCommon.dump(appJar, appClasses);
+        output.shouldContain("Loading classes to share: done.");
+        output.shouldHaveExitValue(0);
+
+        output = TestCommon.exec(appJar, verboseMode, mainClass);
+        checkExecOutput(output, "I am running on version " + MAJOR_VERSION_STRING);
+
+        // 2. Test versions 7 and the current major version.
+        //    -Djdk.util.jar.enableMultiRelease=true (or force), default is true.
+        //    a) -Djdk.util.jar.version=7 does not exist in jar.
+        //        It will fallback to the root version which is also 7 in this test.
+        //    b) -Djdk.util.jar.version=MAJOR_VERSION exists in the jar.
+        for (int i : new int[] {7, MAJOR_VERSION}) {
+            jarVersion = "-Djdk.util.jar.version=" + i;
+            expectedOutput = "I am running on version " + i;
+            output = TestCommon.dump(appJar, appClasses, enableMultiRelease, jarVersion);
+            output.shouldContain("Loading classes to share: done.");
+            output.shouldHaveExitValue(0);
+
+            output = TestCommon.exec(appJar, verboseMode, mainClass);
+            checkExecOutput(output, expectedOutput);
+        }
+
+        // 3. For unsupported version, 5 and current major version + 1, the multiversion
+        // will be turned off, so it will use the default (root) version.
+        for (int i : new int[] {5, MAJOR_VERSION + 1}) {
+            jarVersion = "-Djdk.util.jar.version=" + i;
+            output = TestCommon.dump(appJar, appClasses, enableMultiRelease, jarVersion);
+            output.shouldHaveExitValue(0);
+            // With the fix for 8172218, multi-release jar is being handled in
+            // jdk corelib which doesn't emit the following warning message.
+            //output.shouldContain("JDK" + i + " is not supported in multiple version jars");
+
+            output = TestCommon.exec(appJar, verboseMode, mainClass);
+            if (i == 5)
+                checkExecOutput(output, "I am running on version 7");
+            else
+                checkExecOutput(output, "I am running on version " + MAJOR_VERSION_STRING);
+        }
+
+        // 4. If explicitly disabled from command line for multiversion jar, it will use default
+        //    version at root regardless multiversion versions exists.
+        //    -Djdk.util.jar.enableMultiRelease=false (not 'true' or 'force')
+        for (int i = 6; i < MAJOR_VERSION + 1; i++) {
+            jarVersion = "-Djdk.util.jar.version=" + i;
+            output = TestCommon.dump(appJar, appClasses, "-Djdk.util.jar.enableMultiRelease=false", jarVersion);
+            output.shouldHaveExitValue(0);
+
+            output = TestCommon.exec(appJar, verboseMode, mainClass);
+            expectedOutput = "I am running on version 7";
+            checkExecOutput(output, expectedOutput);
+        }
+
+        // 5. Sanity test with -Xbootclasspath/a
+        //    AppCDS behaves the same as the non-AppCDS case. A multi-release
+        //    jar file in the -Xbootclasspath/a will be ignored.
+        output = TestCommon.dump(appJar, appClasses, "-Xbootclasspath/a:" + appJar, enableMultiRelease, jarVersion);
+        output.shouldContain("Loading classes to share: done.");
+        output.shouldHaveExitValue(0);
+
+        output = TestCommon.exec(appJar, "-Xbootclasspath/a:" + appJar, verboseMode, mainClass);
+        checkExecOutput(output, "I am running on version 7");
+
+        // 6. Sanity test case-insensitive "Multi-Release" attribute name
+        output = TestCommon.dump(appJar2, appClasses);
+        output.shouldContain("Loading classes to share: done.");
+        output.shouldHaveExitValue(0);
+
+        output = TestCommon.exec(appJar2, verboseMode, mainClass);
+        checkExecOutput(output, "I am running on version " + MAJOR_VERSION_STRING);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/OldClassTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary classes with major version < JDK_1.5 (48) should not be included in CDS
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run build TestCommon JarBuilder
+ * @run main OldClassTest
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.nio.file.Files;
+
+import java.util.*;
+import jdk.internal.org.objectweb.asm.*;
+
+public class OldClassTest implements Opcodes {
+
+  public static void main(String[] args) throws Exception {
+    File jarSrcFile = new File(JarBuilder.getOrCreateHelloJar());
+
+    File dir = new File(System.getProperty("test.classes", "."));
+    File jarFile = new File(dir, "OldClassTest_old.jar");
+    String jar = jarFile.getPath();
+
+    if (!jarFile.exists() || jarFile.lastModified() < jarSrcFile.lastModified()) {
+      createTestJarFile(jarSrcFile, jarFile);
+    } else {
+      System.out.println("Already up-to-date: " + jarFile);
+    }
+
+    String appClasses[] = TestCommon.list("Hello");
+
+    // CASE 1: pre-JDK 1.5 compiled classes should be excluded from the dump
+    OutputAnalyzer output = TestCommon.dump(jar, appClasses);
+    TestCommon.checkExecReturn(output, 0, true, "Pre JDK 1.5 class not supported by CDS");
+
+    output = TestCommon.execCommon(
+        "-cp", jar,
+        "-verbose:class",
+        "Hello");
+    TestCommon.checkExecReturn(output, 0, true, "Hello Unicode world (Old)");
+
+    // CASE 2: if we exlcude old version of this class, we should not pick up
+    //         the newer version of this class in a subsequent classpath element.
+    String classpath = jar + File.pathSeparator + jarSrcFile.getPath();
+    output = TestCommon.dump(classpath, appClasses);
+    TestCommon.checkExecReturn(output, 0, true, "Pre JDK 1.5 class not supported by CDS");
+
+    output = TestCommon.execCommon(
+        "-cp", classpath,
+        "-verbose:class",
+        "Hello");
+    TestCommon.checkExecReturn(output, 0, true, "Hello Unicode world (Old)");
+  }
+
+  static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {
+    jarFile.delete();
+    Files.copy(jarSrcFile.toPath(), jarFile.toPath());
+
+    File dir = new File(System.getProperty("test.classes", "."));
+    File outdir = new File(dir, "old_class_test_classes");
+    outdir.delete();
+    outdir.mkdir();
+
+    writeClassFile(new File(outdir, "Hello.class"), makeOldHello());
+
+    JarBuilder.update(jarFile.getPath(), outdir.getPath());
+  }
+
+  static void writeClassFile(File file, byte bytecodes[]) throws Exception {
+    try (FileOutputStream fos = new FileOutputStream(file)) {
+        fos.write(bytecodes);
+      }
+  }
+
+/* makeOldHello() was obtained using JDK8. We use a method name > 128 that would
+   trigger a call to java.lang.Character.isJavaIdentifierStart() during class
+   file parsing.
+
+cat > Hello.java <<EOF
+public class Hello {
+    public static void main(String args[]) {
+        System.out.println(\u1234());
+    }
+    static String \u1234() {
+        return "Hello Unicode world (Old)";
+    }
+}
+EOF
+javac Hello.java
+java jdk.internal.org.objectweb.asm.util.ASMifier Hello.class
+
+ */
+
+  static byte[] makeOldHello() throws Exception {
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+    AnnotationVisitor av0;
+
+//WAS cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Hello", null, "java/lang/Object", null);
+      cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, "Hello", null, "java/lang/Object", null);
+
+    {
+      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+      mv.visitCode();
+      mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      mv.visitMethodInsn(INVOKESTATIC, "Hello", "\u1234", "()Ljava/lang/String;", false);
+      mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 1);
+      mv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(ACC_STATIC, "\u1234", "()Ljava/lang/String;", null, null);
+      mv.visitCode();
+      mv.visitLdcInsn("Hello Unicode world (Old)");
+      mv.visitInsn(ARETURN);
+      mv.visitMaxs(1, 0);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/PackageSealing.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of package.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @compile test-classes/C1.java
+ * @compile test-classes/C2.java
+ * @compile test-classes/PackageSealingTest.java
+ * @run main PackageSealing
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class PackageSealing {
+    public static void main(String args[]) throws Exception {
+        String[] classList = {"sealed/pkg/C1", "pkg/C2", "PackageSealingTest"};
+        String appJar = ClassFileInstaller.writeJar("pkg_seal.jar",
+            ClassFileInstaller.Manifest.fromSourceFile("test-classes/package_seal.mf"),
+            "PackageSealingTest", "sealed/pkg/C1", "pkg/C2");
+
+        // test shared package from -cp path
+        TestCommon.testDump(appJar, TestCommon.list(classList));
+        OutputAnalyzer output;
+        output = TestCommon.exec(appJar, "PackageSealingTest");
+        TestCommon.checkExec(output, "OK");
+
+        // test shared package from -Xbootclasspath/a
+        TestCommon.dump(appJar, TestCommon.list(classList),
+                        "-Xbootclasspath/a:" + appJar);
+        output = TestCommon.exec(appJar, "-Xbootclasspath/a:" + appJar, "PackageSealingTest");
+        TestCommon.checkExec(output, "OK");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ParallelLoad2.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load app classes from CDS archive in parallel threads. Similar to ParallelLoad.java, but each class in its own JAR
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/ParallelLoad.java
+ * @compile test-classes/ParallelClasses.java
+ * @run main ParallelLoad2
+ */
+
+import java.io.File;
+
+public class ParallelLoad2 {
+  public static int MAX_CLASSES = 40;
+  public static void main(String[] args) throws Exception {
+    JarBuilder.build("parallel_load2", "ParallelLoad", "ParallelLoadThread", "ParallelLoadWatchdog");
+    for (int i=0; i<MAX_CLASSES; i++) {
+      JarBuilder.build("parallel_load2_" + i, "ParallelClass" + i);
+    }
+
+    String cp = TestCommon.getTestJar("parallel_load2.jar");
+    for (int i=0; i<MAX_CLASSES; i++) {
+      cp += File.pathSeparator + TestCommon.getTestJar("parallel_load2_" + i + ".jar");
+    }
+
+    String[] class_list = new String[MAX_CLASSES + 2];
+    for (int i=0; i<MAX_CLASSES; i++) {
+      class_list[i] = "ParallelClass" + i;
+    }
+    class_list[class_list.length - 1] = "ParallelLoad";
+    class_list[class_list.length - 2] = "ParallelLoadThread";
+
+    TestCommon.test(cp, class_list,
+                          "ParallelLoad");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ParallelLoadTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load app classes from CDS archive in parallel threads
+ * AppCDS does not support uncompressed oops
+ * @library /test/lib
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/ParallelLoad.java
+ * @compile test-classes/ParallelClasses.java
+ * @run main ParallelLoadTest
+ */
+
+public class ParallelLoadTest {
+    public static final int MAX_CLASSES = 40;
+
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("parallel_load", getClassList(true));
+        String appJar = TestCommon.getTestJar("parallel_load.jar");
+        TestCommon.test(appJar, getClassList(false), "ParallelLoad");
+    }
+
+    private static String[] getClassList(boolean includeWatchdog) {
+        int extra = includeWatchdog ? 3 : 2;
+        String[] classList = new String[MAX_CLASSES + extra];
+
+        int i;
+        for (i=0; i<MAX_CLASSES; i++) {
+            classList[i] = "ParallelClass" + i;
+        }
+
+        classList[i++] = "ParallelLoad";
+        classList[i++] = "ParallelLoadThread";
+        if (includeWatchdog)
+            classList[i++] = "ParallelLoadWatchdog";
+
+        return classList;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary test the -XX:+PrintSharedArchiveAndExit flag
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run main/othervm/timeout=3600 PrintSharedArchiveAndExit
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class PrintSharedArchiveAndExit {
+  private static void check(OutputAnalyzer output, int ret, boolean checkContain, String... matches) throws Exception {
+    // Tests specific to this test
+    TestCommon.checkExecReturn(output, ret, checkContain, matches);
+
+    // In all test case, we should never print out the following due to
+    // PrintSharedArchiveAndExit. JVM should have been terminated
+    // before reaching these outputs.
+    TestCommon.checkExecReturn(output, ret, false,
+                               "Usage:",            // JVM help message
+                               "java version",      // JVM version
+                               "Hello World");      // output from the Hello.class in hello.jar
+  }
+
+  private static void log(String msg) {
+    System.out.println(">---------------------------------------------------------------------");
+    System.out.println(msg);
+    System.out.println("<---------------------------------------------------------------------");
+  }
+
+  public static void main(String[] args) throws Exception {
+    String appJar = JarBuilder.getOrCreateHelloJar();
+    String appJar2 = JarBuilder.build("PrintSharedArchiveAndExit-more", "HelloMore");
+
+    String cp = appJar + File.pathSeparator + appJar2;
+    String lastCheckMsg = "checking shared classpath entry: " + appJar2; // the last JAR to check
+
+    TestCommon.testDump(cp, TestCommon.list("Hello"));
+
+    OutputAnalyzer output;
+
+    log("Normal execution -- all the JAR paths should be checked");
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-XX:+PrintSharedArchiveAndExit");
+    check(output, 0, true, lastCheckMsg);
+
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-XX:+PrintSharedArchiveAndExit",
+        "-XX:+PrintSharedDictionary");  // Test PrintSharedDictionary as well.
+    check(output, 0, true, lastCheckMsg, "java.lang.Object");
+
+    log("Normal execution -- Make sure -version, help message and app main()\n" +
+        "class are not invoked. These are checked inside check().");
+    output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-version");
+    check(output, 0, true, lastCheckMsg);
+
+    output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-help");
+    check(output, 0, true, lastCheckMsg);
+
+    output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello");
+    check(output, 0, true, lastCheckMsg);
+
+    log("Execution with simple errors -- with 'simple' errors like missing or modified\n" +
+        "JAR files, the VM should try to continue to print the remaining information.\n" +
+        "Use an invalid Boot CP -- all the JAR paths should be checked");
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-Xbootclasspath/a:foo.jar",
+        "-XX:+PrintSharedArchiveAndExit");
+    check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, ");
+
+    log("Use an App CP shorter than the one at dump time -- all the JAR paths should be checked");
+    output = TestCommon.execCommon(
+        "-cp", ".",
+        "-XX:+PrintSharedArchiveAndExit");
+    check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: .");
+
+    log("Use an invalid App CP -- all the JAR paths should be checked");
+    String invalidCP = "non-existing-dir" + File.pathSeparator + cp;
+    output = TestCommon.execCommon(
+        "-cp", invalidCP,
+        "-XX:+PrintSharedArchiveAndExit");
+    check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP);
+
+    log("Changed modification time of hello.jar -- all the JAR paths should be checked");
+    (new File(appJar)).setLastModified(System.currentTimeMillis() + 2000);
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-XX:+PrintSharedArchiveAndExit");
+    check(output, 1, true, lastCheckMsg, "[Timestamp mismatch]");
+
+    log("Even if hello.jar is out of date, we should still be able to print the dictionary.");
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-XX:+PrintSharedArchiveAndExit",
+        "-XX:+PrintSharedDictionary");  // Test PrintSharedDictionary as well.
+    check(output, 1, true, lastCheckMsg, "java.lang.Object");
+
+
+    log("Remove hello.jar -- all the JAR paths should be checked");
+    (new File(appJar)).delete();
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-XX:+PrintSharedArchiveAndExit");
+    check(output, 1, true, lastCheckMsg, "[Required classpath entry does not exist: " + appJar + "]");
+
+    log("Execution with major errors -- with 'major' errors like the JSA file\n" +
+        "is missing, we should stop immediately to avoid crashing the JVM.");
+    output = TestCommon.execCommon(
+        "-cp", cp,
+        "-XX:+PrintSharedArchiveAndExit",
+        "-XX:SharedArchiveFile=./no-such-fileappcds.jsa");
+    check(output, 1, false, lastCheckMsg);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of prohibited package.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/ProhibitedHelper.java test-classes/Prohibited.jasm
+ * @run main ProhibitedPackage
+ */
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ProhibitedPackage {
+
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("prohibited_pkg", "java/lang/Prohibited", "ProhibitedHelper");
+
+        String appJar = TestCommon.getTestJar("prohibited_pkg.jar");
+
+        // Test support for customer loaders
+        if (Platform.areCustomLoadersSupportedForCDS()) {
+            String classlist[] = new String[] {
+                "java/lang/Object id: 1",
+                "java/lang/Prohibited id: 2 super: 1 source: " + appJar
+            };
+
+            // Make sure a class in a prohibited package for a custom loader
+            // will be ignored during dumping.
+            TestCommon.dump(appJar,  classlist, "-Xlog:cds")
+                .shouldContain("Dumping")
+                .shouldContain("[cds] Prohibited package for non-bootstrap classes: java/lang/Prohibited.class")
+                .shouldHaveExitValue(0);
+        }
+
+
+        // Make sure a class in a prohibited package for a non-custom loader
+        // will be ignored during dumping.
+        TestCommon.dump(appJar,
+                        TestCommon.list("java/lang/Prohibited", "ProhibitedHelper"),
+                        "-Xlog:class+load")
+            .shouldContain("Dumping")
+            .shouldNotContain("[info][class,load] java.lang.Prohibited source: ")
+            .shouldHaveExitValue(0);
+
+        // Try loading the class in a prohibited package with various -Xshare
+        // modes. The class shouldn't be loaded and appropriate exceptions
+        // are expected.
+
+        OutputAnalyzer output;
+
+        // -Xshare:on
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+            "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper");
+        TestCommon.checkExec(output, "Prohibited package name: java.lang");
+
+        // -Xshare:auto
+        output = TestCommon.execAuto(
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+            "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper");
+        TestCommon.checkExec(output, "Prohibited package name: java.lang");
+
+        // -Xshare:off
+        output = TestCommon.execOff(
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+            "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper");
+        output.shouldContain("Prohibited package name: java.lang");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/ProtectionDomain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of protection domain.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/ProtDomain.java
+ * @compile test-classes/ProtDomainB.java
+ * @compile test-classes/JimageClassProtDomain.java
+ * @run main ProtectionDomain
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ProtectionDomain {
+  public static void main(String[] args) throws Exception {
+    JarBuilder.build("prot_domain", "ProtDomain", "ProtDomainB", "ProtDomainOther",
+                     "ProtDomainBOther", "JimageClassProtDomain");
+
+    String appJar = TestCommon.getTestJar("prot_domain.jar");
+    TestCommon.testDump(appJar,
+         TestCommon.list("ProtDomain",
+                         "ProtDomainBOther",
+                         "java/util/Dictionary",
+                         "sun/tools/javac/Main",
+                         "jdk/nio/zipfs/ZipInfo",
+                         "java/net/URL",
+                         "sun/rmi/rmic/Main",
+                         "com/sun/jndi/dns/DnsName"));
+
+    OutputAnalyzer output;
+
+    // First class is loaded from CDS, second class is loaded from JAR
+    output = TestCommon.exec(appJar, "-verbose:class", "ProtDomain");
+    TestCommon.checkExec(output, "Protection Domains match");
+
+    // First class is loaded from JAR, second class is loaded from CDS
+    output = TestCommon.exec(appJar, "-verbose:class", "ProtDomainB");
+    TestCommon.checkExec(output, "Protection Domains match");
+
+    // Test ProtectionDomain for application and extension module classes from the
+    // "modules" jimage
+    output = TestCommon.exec(appJar, "-verbose:class", "JimageClassProtDomain");
+    output.shouldNotContain("Failed: Protection Domains do not match");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/RewriteBytecodesTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Use ClassLoader.defineClass() to load a class with rewritten bytecode. Make sure
+ *          the archived class with the same name is not loaded.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/RewriteBytecodes.java test-classes/Util.java test-classes/Super.java test-classes/Child.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main RewriteBytecodesTest
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RewriteBytecodesTest {
+  public static void main(String[] args) throws Exception {
+    String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+    String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+    String appJar = JarBuilder.build("dynamic_define", "RewriteBytecodes", "Util", "Super", "Child");
+    String superClsFile = (new File(System.getProperty("test.classes", "."), "Super.class")).getPath();
+
+    TestCommon.dump(appJar, TestCommon.list("RewriteBytecodes", "Super", "Child"),
+                    // command-line arguments ...
+                    use_whitebox_jar);
+
+    OutputAnalyzer output = TestCommon.exec(appJar,
+                    // command-line arguments ...
+                    "--add-opens=java.base/java.lang=ALL-UNNAMED",
+                    use_whitebox_jar,
+                    "-XX:+UnlockDiagnosticVMOptions",
+                    "-XX:+WhiteBoxAPI",
+                    "RewriteBytecodes", superClsFile);
+    TestCommon.checkExec(output);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ *  @test
+ *  @summary SharedArchiveConsistency
+ *   AppCDS does not support uncompressed oops
+ *  @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ *  @library /test/lib
+ *  @modules java.base/jdk.internal.misc
+ *           java.compiler
+ *           java.management
+ *           jdk.jartool/sun.tools.jar
+ *           jdk.internal.jvmstat/sun.jvmstat.monitor
+ *  @build sun.hotspot.WhiteBox
+ *  @compile test-classes/Hello.java
+ *  @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *  @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SharedArchiveConsistency
+ */
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Utils;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import java.nio.file.StandardOpenOption;
+import static java.nio.file.StandardOpenOption.READ;
+import static java.nio.file.StandardOpenOption.WRITE;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import sun.hotspot.WhiteBox;
+
+public class SharedArchiveConsistency {
+    public static WhiteBox wb;
+    public static int offset_magic;    // FileMapHeader::_magic
+    public static int sp_offset_crc;   // FileMapHeader::space_info::_crc
+    public static int file_header_size = -1;// total size of header, variant, need calculation
+    public static int space_info_size; // size of space_info
+    public static int sp_offset;       // offset of FileMapHeader::space_info
+    public static int sp_used_offset;  // offset of space_info::_used
+    public static int size_t_size;     // size of size_t
+
+    public static File jsa;        // will be updated during test
+    public static File orgJsaFile; // kept the original file not touched.
+    public static String[] shared_region_name = {"MiscCode", "ReadWrite", "ReadOnly", "MiscData"};
+    public static int num_regions = shared_region_name.length;
+    public static String[] matchMessages = {
+        "Unable to use shared archive",
+        "An error has occurred while processing the shared archive file.",
+        "Checksum verification failed.",
+        "The shared archive file has been truncated."
+    };
+
+    public static void getFileOffsetInfo() throws Exception {
+        wb = WhiteBox.getWhiteBox();
+        offset_magic = wb.getOffsetForName("FileMapHeader::_magic");
+        sp_offset_crc = wb.getOffsetForName("space_info::_crc");
+        try {
+            int nonExistOffset = wb.getOffsetForName("FileMapHeader::_non_exist_offset");
+            System.exit(-1); // should fail
+        } catch (Exception e) {
+            // success
+        }
+
+        sp_offset = wb.getOffsetForName("FileMapHeader::_space[0]") - offset_magic;
+        sp_used_offset = wb.getOffsetForName("space_info::_used") - sp_offset_crc;
+        size_t_size = wb.getOffsetForName("size_t_size");
+        space_info_size  = wb.getOffsetForName("space_info_size");
+    }
+
+    public static int getFileHeaderSize(FileChannel fc) throws Exception {
+        if (file_header_size != -1) {
+            return file_header_size;
+        }
+        // this is not real header size, it is struct size
+        file_header_size = wb.getOffsetForName("file_header_size");
+        int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
+            offset_magic;
+        int path_misc_info_size   = (int)readInt(fc, offset_path_misc_info, size_t_size);
+        file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size);
+        System.out.println("offset_path_misc_info = " + offset_path_misc_info);
+        System.out.println("path_misc_info_size   = " + path_misc_info_size);
+        System.out.println("file_header_size      = " + file_header_size);
+        file_header_size = (int)align_up_page(file_header_size);
+        System.out.println("file_header_size (aligned to page) = " + file_header_size);
+        return file_header_size;
+    }
+
+    public static long align_up_page(long l) throws Exception {
+        // wb is obtained in getFileOffsetInfo() which is called first in main() else we should call
+        // WhiteBox.getWhiteBox() here first.
+        int pageSize = wb.getVMPageSize();
+        return (l + pageSize -1) & (~ (pageSize - 1));
+    }
+
+    private static long getRandomBetween(long start, long end) throws Exception {
+        if (start > end) {
+            throw new IllegalArgumentException("start must be less than end");
+        }
+        Random aRandom = Utils.getRandomInstance();
+        int d = aRandom.nextInt((int)(end - start));
+        if (d < 1) {
+            d = 1;
+        }
+        return start + d;
+    }
+
+    public static long readInt(FileChannel fc, long offset, int nbytes) throws Exception {
+        ByteBuffer bb = ByteBuffer.allocate(nbytes);
+        bb.order(ByteOrder.nativeOrder());
+        fc.position(offset);
+        fc.read(bb);
+        return  (nbytes > 4 ? bb.getLong(0) : bb.getInt(0));
+    }
+
+    public static void writeData(FileChannel fc, long offset, ByteBuffer bb) throws Exception {
+        fc.position(offset);
+        fc.write(bb);
+        fc.force(true);
+    }
+
+    public static FileChannel getFileChannel() throws Exception {
+        List<StandardOpenOption> arry = new ArrayList<StandardOpenOption>();
+        arry.add(READ);
+        arry.add(WRITE);
+        return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry));
+    }
+
+    public static void modifyJsaContentRandomly() throws Exception {
+        FileChannel fc = getFileChannel();
+        // corrupt random area in the data areas (MiscCode, ReadWrite, ReadOnly, MiscData)
+        long[] used    = new long[num_regions];       // record used bytes
+        long start0, start, end, off;
+        int used_offset, path_info_size;
+
+        int bufSize;
+        System.out.printf("%-12s%-12s%-12s%-12s%-12s\n", "Space Name", "Offset", "Used bytes", "Reg Start", "Random Offset");
+        start0 = getFileHeaderSize(fc);
+        for (int i = 0; i < num_regions; i++) {
+            used_offset = sp_offset + space_info_size * i + sp_used_offset;
+            // read 'used'
+            used[i] = readInt(fc, used_offset, size_t_size);
+            start = start0;
+            for (int j = 0; j < i; j++) {
+                start += align_up_page(used[j]);
+            }
+            end = start + used[i];
+            off = getRandomBetween(start, end);
+            System.out.printf("%-12s%-12d%-12d%-12d%-12d\n", shared_region_name[i], used_offset, used[i], start, off);
+            if (end - off < 1024) {
+                bufSize = (int)(end - off + 1);
+            } else {
+                bufSize = 1024;
+            }
+            ByteBuffer bbuf = ByteBuffer.wrap(new byte[bufSize]);
+            writeData(fc, off, bbuf);
+        }
+        if (fc.isOpen()) {
+            fc.close();
+        }
+    }
+
+    public static void modifyJsaContent() throws Exception {
+        FileChannel fc = getFileChannel();
+        byte[] buf = new byte[4096];
+        ByteBuffer bbuf = ByteBuffer.wrap(buf);
+
+        long total = 0L;
+        long used_offset = 0L;
+        long[] used = new long[num_regions];
+        System.out.printf("%-12s%-12s\n", "Space name", "Used bytes");
+        for (int i = 0; i < num_regions; i++) {
+            used_offset = sp_offset + space_info_size* i + sp_used_offset;
+            // read 'used'
+            used[i] = readInt(fc, used_offset, size_t_size);
+            System.out.printf("%-12s%-12d\n", shared_region_name[i], used[i]);
+            total += used[i];
+        }
+        System.out.printf("%-12s%-12d\n", "Total: ", total);
+        long corrupt_used_offset =  getFileHeaderSize(fc);
+        System.out.println("Corrupt RO section, offset = " + corrupt_used_offset);
+        while (used_offset < used[0]) {
+            writeData(fc, corrupt_used_offset, bbuf);
+            bbuf.clear();
+            used_offset += 4096;
+        }
+        fc.force(true);
+        if (fc.isOpen()) {
+            fc.close();
+        }
+    }
+
+    public static void modifyJsaHeader() throws Exception {
+        FileChannel fc = getFileChannel();
+        // screw up header info
+        byte[] buf = new byte[getFileHeaderSize(fc)];
+        ByteBuffer bbuf = ByteBuffer.wrap(buf);
+        writeData(fc, 0L, bbuf);
+        if (fc.isOpen()) {
+            fc.close();
+        }
+    }
+
+    public static void copyFile(File from, File to) throws Exception {
+        if (to.exists()) {
+            if(!to.delete()) {
+                throw new IOException("Could not delete file " + to);
+            }
+        }
+        to.createNewFile();
+        setReadWritePermission(to);
+        Files.copy(from.toPath(), to.toPath(), REPLACE_EXISTING);
+    }
+
+    // Copy file with bytes deleted or inserted
+    // del -- true, deleted, false, inserted
+    public static void copyFile(File from, File to, boolean del) throws Exception {
+        FileChannel inputChannel = null;
+        FileChannel outputChannel = null;
+        try {
+            inputChannel = new FileInputStream(from).getChannel();
+            outputChannel = new FileOutputStream(to).getChannel();
+            long size = inputChannel.size();
+            int init_size = getFileHeaderSize(inputChannel);
+            outputChannel.transferFrom(inputChannel, 0, init_size);
+            int n = (int)getRandomBetween(0, 1024);
+            if (del) {
+                System.out.println("Delete " + n + " bytes at data start section");
+                inputChannel.position(init_size + n);
+                outputChannel.transferFrom(inputChannel, init_size, size - init_size - n);
+            } else {
+                System.out.println("Insert " + n + " bytes at data start section");
+                outputChannel.position(init_size);
+                outputChannel.write(ByteBuffer.wrap(new byte[n]));
+                outputChannel.transferFrom(inputChannel, init_size + n , size - init_size);
+            }
+        } finally {
+            inputChannel.close();
+            outputChannel.close();
+        }
+    }
+
+    public static void restoreJsaFile() throws Exception {
+        Files.copy(orgJsaFile.toPath(), jsa.toPath(), REPLACE_EXISTING);
+    }
+
+    public static void setReadWritePermission(File file) throws Exception {
+        if (!file.canRead()) {
+            if (!file.setReadable(true)) {
+                throw new IOException("Cannot modify file " + file + " as readable");
+            }
+        }
+        if (!file.canWrite()) {
+            if (!file.setWritable(true)) {
+                throw new IOException("Cannot modify file " + file + " as writable");
+            }
+        }
+    }
+
+    public static void testAndCheck(String[] execArgs) throws Exception {
+        OutputAnalyzer output = TestCommon.execCommon(execArgs);
+        String stdtxt = output.getOutput();
+        System.out.println("Note: this test may fail in very rare occasions due to CRC32 checksum collision");
+        for (String message : matchMessages) {
+            if (stdtxt.contains(message)) {
+                // match any to return
+                return;
+            }
+        }
+        TestCommon.checkExec(output);
+    }
+
+    // dump with hello.jsa, then
+    // read the jsa file
+    //   1) run normal
+    //   2) modify header
+    //   3) keep header correct but modify content
+    //   4) update both header and content, test
+    //   5) delete bytes in data begining
+    //   6) insert bytes in data begining
+    //   7) randomly corrupt data in four areas: RO, RW. MISC DATA, MISC CODE
+    public static void main(String... args) throws Exception {
+        // must call to get offset info first!!!
+        getFileOffsetInfo();
+        Path currentRelativePath = Paths.get("");
+        String currentDir = currentRelativePath.toAbsolutePath().toString();
+        System.out.println("Current relative path is: " + currentDir);
+        // get jar file
+        String jarFile = JarBuilder.getOrCreateHelloJar();
+
+        // dump (appcds.jsa created)
+        TestCommon.testDump(jarFile, null);
+
+        // test, should pass
+        System.out.println("1. Normal, should pass but may fail\n");
+        String[] execArgs = {"-cp", jarFile, "Hello"};
+
+        OutputAnalyzer output = TestCommon.execCommon(execArgs);
+
+        try {
+            TestCommon.checkExecReturn(output, 0, true, "Hello World");
+        } catch (Exception e) {
+            TestCommon.checkExecReturn(output, 1, true, matchMessages[0]);
+        }
+
+        // get current archive name
+        jsa = new File(TestCommon.getCurrentArchiveName());
+        if (!jsa.exists()) {
+            throw new IOException(jsa + " does not exist!");
+        }
+
+        setReadWritePermission(jsa);
+
+        // save as original untouched
+        orgJsaFile = new File(new File(currentDir), "appcds.jsa.bak");
+        copyFile(jsa, orgJsaFile);
+
+
+        // modify jsa header, test should fail
+        System.out.println("\n2. Corrupt header, should fail\n");
+        modifyJsaHeader();
+        output = TestCommon.execCommon(execArgs);
+        output.shouldContain("The shared archive file has the wrong version");
+        output.shouldNotContain("Checksum verification failed");
+
+        // modify content
+        System.out.println("\n3. Corrupt Content, should fail\n");
+        copyFile(orgJsaFile, jsa);
+        modifyJsaContent();
+        testAndCheck(execArgs);
+
+        // modify both header and content, test should fail
+        System.out.println("\n4. Corrupt Header and Content, should fail\n");
+        copyFile(orgJsaFile, jsa);
+        modifyJsaHeader();
+        modifyJsaContent();  // this will not be reached since failed on header change first
+        output = TestCommon.execCommon(execArgs);
+        output.shouldContain("The shared archive file has the wrong version");
+        output.shouldNotContain("Checksum verification failed");
+
+        // delete bytes in data sectoin
+        System.out.println("\n5. Delete bytes at begining of data section, should fail\n");
+        copyFile(orgJsaFile, jsa, true);
+        testAndCheck(execArgs);
+
+        // insert bytes in data sectoin forward
+        System.out.println("\n6. Insert bytes at begining of data section, should fail\n");
+        copyFile(orgJsaFile, jsa, false);
+        testAndCheck(execArgs);
+
+        System.out.println("\n7. modify Content in random areas, should fail\n");
+        copyFile(orgJsaFile, jsa);
+        modifyJsaContentRandomly();
+        testAndCheck(execArgs);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveFile.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+/*
+ * @test
+ * @summary The diagnostic option, -XX:SharedArchiveFile can be unlocked using -XX:+UseAppCDS
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main SharedArchiveFile
+ */
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import java.util.Properties;
+
+public class SharedArchiveFile {
+    public static void main(String[] args) throws Exception {
+        boolean isProduct = !Platform.isDebugBuild();
+        String appJar = JarBuilder.getOrCreateHelloJar();
+
+        // 1) Using -XX:SharedArchiveFile without -XX:+UseAppCDS should fail
+        //    on product binary without -XX:+UnlockDiagnosticVMOptions.
+        if (isProduct) {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
+                "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-Xshare:dump");
+            OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "dump");
+            out.shouldContain("Error: VM option 'SharedArchiveFile' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.");
+        }
+
+        // 2) Dumping with -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile
+        //    should always succeed.
+        CDSTestUtils.createArchive("-XX:+UnlockDiagnosticVMOptions")
+            .shouldContain("Dumping");
+
+        // 3) Using -XX:SharedArchiveFile with -XX:+UseAppCDS should work
+        //    on product binary by default.
+        OutputAnalyzer output3 = TestCommon.dump(appJar, TestCommon.list("Hello"));
+        output3.shouldContain("Dumping");
+        output3 = TestCommon.exec(appJar, "Hello");
+        TestCommon.checkExec(output3, "Hello World");
+
+        // 4) Using -XX:+UseAppCDS should not affect other diagnostic flags,
+        //    such as LogEvents
+        OutputAnalyzer output4 = TestCommon.exec(appJar, "-XX:+LogEvents", "Hello");
+        if (isProduct) {
+            output4.shouldContain("Error: VM option 'LogEvents' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.");
+        } else {
+            TestCommon.checkExec(output4, "Hello World");
+        }
+
+        // 5) 8066921 - Extra -XX:+UseAppCDS
+        TestCommon.testDump(appJar, TestCommon.list("Hello"), "-XX:+UseAppCDS");
+        OutputAnalyzer output5 = TestCommon.exec(appJar, "-XX:+UseAppCDS", "Hello");
+        TestCommon.checkExec(output5);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/SharedBaseAddress.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test SharedBaseAddress
+ * @summary Test variety of values for SharedBaseAddress, in AppCDS mode,
+ *          making sure VM handles normal values as well as edge values
+ *          w/o a crash.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main/timeout=240 SharedBaseAddress
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class SharedBaseAddress {
+
+    // shared base address test table
+    private static final String[] testTable = {
+        "1g", "8g", "64g","512g", "4t",
+        "32t", "128t", "0",
+        "1", "64k", "64M"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+
+        for (String testEntry : testTable) {
+            System.out.println("sharedBaseAddress = " + testEntry);
+
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+                appJar, new String[] {"Hello"}, "-XX:SharedBaseAddress=" + testEntry);
+            TestCommon.checkDump(dumpOutput, "Loading classes to share");
+
+            OutputAnalyzer execOutput = TestCommon.exec(appJar, "Hello");
+            TestCommon.checkExec(execOutput, "Hello World");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/SharedPackages.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of package.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/PackageTest.java
+ * @compile test-classes/JimageClassPackage.java
+ * @run main SharedPackages
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class SharedPackages {
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("pkg", "p/PackageTest", "JimageClassPackage");
+
+        String appJar = TestCommon.getTestJar("pkg.jar");
+        TestCommon.testDump(appJar, TestCommon.list("p/PackageTest",
+                                                    "java/util/Dictionary",
+                                                    "sun/tools/javac/Main",
+                                                    "jdk/nio/zipfs/ZipInfo",
+                                                    "java/net/URL",
+                                                    "sun/rmi/rmic/Main",
+                                                    "com/sun/jndi/dns/DnsName"));
+
+        OutputAnalyzer output;
+
+        // Test 1: shared class from Jar on the -cp
+        output = TestCommon.exec(appJar, "-verbose:class", "p.PackageTest");
+        TestCommon.checkExec(output, "Expected package");
+        if (!TestCommon.isUnableToMap(output))
+            output.shouldContain("Package is not sealed");
+
+        // Test 2: shared classes from "modules" jimage
+        output = TestCommon.exec(appJar, "-verbose:class",
+                                 "JimageClassPackage");
+        if (!TestCommon.isUnableToMap(output)) {
+            output.shouldNotContain("Unexpected package");
+            output.shouldNotContain("Package is not sealed");
+        }
+
+        // Test 3: shared class from Jar on the -Xbootclasspath/a
+        TestCommon.dump(
+            appJar, TestCommon.list("p/PackageTest"), "-Xbootclasspath/a:" + appJar);
+        output = TestCommon.exec(appJar, "-Xbootclasspath/a:" + appJar, "p.PackageTest");
+        if (!TestCommon.isUnableToMap(output)) {
+            output.shouldNotContain("Unexpected package");
+            output.shouldContain("Package is not sealed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/SignedJar.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of signed JAR.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main SignedJar
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import java.io.File;
+
+public class SignedJar {
+    public static void main(String[] args) throws Exception {
+        String unsignedJar = JarBuilder.getOrCreateHelloJar();
+        JarBuilder.signJar();
+
+        // Test class exists in signed JAR
+        String signedJar = TestCommon.getTestJar("signed_hello.jar");
+        OutputAnalyzer output;
+        output = TestCommon.dump(signedJar, TestCommon.list("Hello"));
+        TestCommon.checkDump(output, "Preload Warning: Skipping Hello from signed JAR");
+
+        // At runtime, the Hello class should be loaded from the jar file
+        // instead of from the shared archive since a class from a signed
+        // jar shouldn't be dumped into the archive.
+        output = TestCommon.exec(signedJar, "-verbose:class", "Hello");
+        String expectedOutput = ".class,load. Hello source: file:.*signed_hello.jar";
+
+        try {
+            output.shouldMatch(expectedOutput);
+        } catch (Exception e) {
+            TestCommon.checkCommonExecExceptions(output, e);
+        }
+
+        // Test class exists in both signed JAR and unsigned JAR
+        String jars = signedJar + System.getProperty("path.separator") + unsignedJar;
+        output = TestCommon.dump(jars, TestCommon.list("Hello"));
+        TestCommon.checkDump(output, "Preload Warning: Skipping Hello from signed JAR");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/SpecifySysLoaderProp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ *  @test
+ *  @summary If -Djava.system.class.loader=xxx is specified in command-line, disable UseAppCDS
+ *  AppCDS does not support uncompressed oops
+ *  @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ *  @library /test/lib
+ *  @modules java.base/jdk.internal.misc
+ *      jdk.jartool/sun.tools.jar
+ *  @compile test-classes/TestClassLoader.java
+ *  @compile test-classes/ReportMyLoader.java
+ *  @compile test-classes/TrySwitchMyLoader.java
+ *  @run main SpecifySysLoaderProp
+ */
+
+import java.io.*;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class SpecifySysLoaderProp {
+
+  public static void main(String[] args) throws Exception {
+    JarBuilder.build("sysloader", "TestClassLoader", "ReportMyLoader", "TrySwitchMyLoader");
+
+    String jarFileName = "sysloader.jar";
+    String appJar = TestCommon.getTestJar(jarFileName);
+    TestCommon.testDump(appJar, TestCommon.list("ReportMyLoader"));
+    String warning = "VM warning: UseAppCDS is disabled because the java.system.class.loader property is specified";
+
+
+    // (0) Baseline. Do not specify -Djava.system.class.loader
+    //     The test class should be loaded from archive
+    OutputAnalyzer output = TestCommon.execCommon(
+        "-verbose:class",
+        "-cp", appJar,
+        "ReportMyLoader");
+    TestCommon.checkExec(output,
+                         "[class,load] ReportMyLoader source: shared objects file",
+                         "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@");
+
+    // (1) Try to execute the archive with -Djava.system.class.loader=no.such.Klass,
+    //     it should fail
+    output = TestCommon.execCommon(
+        "-cp", appJar,
+        "-Djava.system.class.loader=no.such.Klass",
+        "ReportMyLoader");
+    try {
+        output.shouldContain(warning);
+        output.shouldContain("ClassNotFoundException: no.such.Klass");
+    } catch (Exception e) {
+        TestCommon.checkCommonExecExceptions(output, e);
+    }
+
+    // (2) Try to execute the archive with -Djava.system.class.loader=TestClassLoader,
+    //     it should run, but AppCDS should be disabled
+    output = TestCommon.execCommon(
+        "-verbose:class",
+        "-cp", appJar,
+        "-Djava.system.class.loader=TestClassLoader",
+        "ReportMyLoader");
+    TestCommon.checkExec(output,
+                         "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@", //<-this is still printed because TestClassLoader simply delegates to Launcher$AppLoader, but ...
+                         "TestClassLoader.called = true", //<-but this proves that TestClassLoader was indeed called.
+                         "TestClassLoader: loadClass(\"ReportMyLoader\","); //<- this also proves that TestClassLoader was indeed called.
+    try {
+        output.shouldMatch(".class,load. TestClassLoader source: file:");
+        output.shouldMatch(".class,load. ReportMyLoader source: file:.*" + jarFileName);
+    } catch (Exception e) {
+        TestCommon.checkCommonExecExceptions(output, e);
+    }
+
+    // (3) Try to change the java.system.class.loader programmatically after
+    //     the app's main method is executed. This should have no effect in terms of
+    //     changing or switching the actual system class loader that's already in use.
+    output = TestCommon.execCommon(
+        "-verbose:class",
+        "-cp", appJar,
+        "TrySwitchMyLoader");
+    TestCommon.checkExec(output,
+                         "[class,load] ReportMyLoader source: shared objects file",
+                         "TrySwitchMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
+                         "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
+                         "TestClassLoader.called = false");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/TestCommon.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.Platform;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * This is a test utility class for common AppCDS test functionality.
+ *
+ * Various methods use (String ...) for passing VM options. Note that the order
+ * of the VM options are important in certain cases. Many methods take arguments like
+ *
+ *    (String prefix[], String suffix[], String... opts)
+ *
+ * Note that the order of the VM options is:
+ *
+ *    prefix + opts + suffix
+ */
+public class TestCommon extends CDSTestUtils {
+    private static final String JSA_FILE_PREFIX = System.getProperty("user.dir") +
+        File.separator + "appcds-";
+
+    private static final SimpleDateFormat timeStampFormat =
+        new SimpleDateFormat("HH'h'mm'm'ss's'SSS");
+
+    private static final String timeoutFactor =
+        System.getProperty("test.timeout.factor", "1.0");
+
+    private static String currentArchiveName;
+
+    // Call this method to start new archive with new unique name
+    public static void startNewArchiveName() {
+        deletePriorArchives();
+        currentArchiveName = JSA_FILE_PREFIX +
+            timeStampFormat.format(new Date()) + ".jsa";
+    }
+
+    // Call this method to get current archive name
+    public static String getCurrentArchiveName() {
+        return currentArchiveName;
+    }
+
+    // Attempt to clean old archives to preserve space
+    // Archives are large artifacts (20Mb or more), and much larger than
+    // most other artifacts created in jtreg testing.
+    // Therefore it is a good idea to clean the old archives when they are not needed.
+    // In most cases the deletion attempt will succeed; on rare occasion the
+    // delete operation will fail since the system or VM process still holds a handle
+    // to the file; in such cases the File.delete() operation will silently fail, w/o
+    // throwing an exception, thus allowing testing to continue.
+    public static void deletePriorArchives() {
+        File dir = new File(System.getProperty("user.dir"));
+        String files[] = dir.list();
+        for (String name : files) {
+            if (name.startsWith("appcds-") && name.endsWith(".jsa")) {
+                if (!(new File(dir, name)).delete())
+                    System.out.println("deletePriorArchives(): delete failed for file " + name);
+            }
+        }
+    }
+
+
+    // Create AppCDS archive using most common args - convenience method
+    // Legacy name preserved for compatibility
+    public static OutputAnalyzer dump(String appJar, String appClasses[],
+                                               String... suffix) throws Exception {
+        return createArchive(appJar, appClasses, suffix);
+    }
+
+
+    // Create AppCDS archive using most common args - convenience method
+    public static OutputAnalyzer createArchive(String appJar, String appClasses[],
+                                               String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar)
+            .setAppClasses(appClasses);
+        opts.addSuffix(suffix);
+        return createArchive(opts);
+    }
+
+
+    // Create AppCDS archive using appcds options
+    public static OutputAnalyzer createArchive(AppCDSOptions opts)
+        throws Exception {
+
+        ArrayList<String> cmd = new ArrayList<String>();
+        File classList = makeClassList(opts.appClasses);
+        startNewArchiveName();
+
+        for (String p : opts.prefix) cmd.add(p);
+
+        if (opts.appJar != null) {
+            cmd.add("-cp");
+            cmd.add(opts.appJar);
+        } else {
+            cmd.add("-cp");
+            cmd.add("\"\"");
+        }
+
+        cmd.add("-Xshare:dump");
+        cmd.add("-Xlog:cds,cds+hashtables");
+        cmd.add("-XX:+UseAppCDS");
+        cmd.add("-XX:ExtraSharedClassListFile=" + classList.getPath());
+
+        if (opts.archiveName == null)
+            opts.archiveName = getCurrentArchiveName();
+
+        cmd.add("-XX:SharedArchiveFile=" + opts.archiveName);
+
+        for (String s : opts.suffix) cmd.add(s);
+
+        String[] cmdLine = cmd.toArray(new String[cmd.size()]);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        return executeAndLog(pb, "dump");
+    }
+
+
+    // Execute JVM using AppCDS archive with specified AppCDSOptions
+    public static OutputAnalyzer runWithArchive(AppCDSOptions opts)
+        throws Exception {
+
+        ArrayList<String> cmd = new ArrayList<String>();
+
+        for (String p : opts.prefix) cmd.add(p);
+
+        cmd.add("-Xshare:" + opts.xShareMode);
+        cmd.add("-XX:+UseAppCDS");
+        cmd.add("-showversion");
+        cmd.add("-XX:SharedArchiveFile=" + getCurrentArchiveName());
+        cmd.add("-Dtest.timeout.factor=" + timeoutFactor);
+
+        if (opts.appJar != null) {
+            cmd.add("-cp");
+            cmd.add(opts.appJar);
+        }
+
+        for (String s : opts.suffix) cmd.add(s);
+
+        String[] cmdLine = cmd.toArray(new String[cmd.size()]);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        return executeAndLog(pb, "exec");
+    }
+
+
+    public static OutputAnalyzer execCommon(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix);
+        return runWithArchive(opts);
+    }
+
+
+    public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
+        opts.addSuffix(suffix);
+        return runWithArchive(opts);
+    }
+
+
+    public static OutputAnalyzer execAuto(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix).setXShareMode("auto");
+        return runWithArchive(opts);
+    }
+
+    public static OutputAnalyzer execOff(String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.addSuffix(suffix).setXShareMode("off");
+        return runWithArchive(opts);
+    }
+
+    public static OutputAnalyzer execModule(String prefix[], String upgrademodulepath, String modulepath,
+                                            String mid, String... testClassArgs)
+        throws Exception {
+
+        AppCDSOptions opts = (new AppCDSOptions());
+
+        opts.addPrefix(prefix);
+        if (upgrademodulepath == null) {
+            opts.addSuffix("-p", modulepath, "-m", mid);
+        } else {
+            opts.addSuffix("--upgrade-module-path", upgrademodulepath,
+                           "-p", modulepath, "-m", mid);
+        }
+        opts.addSuffix(testClassArgs);
+
+        return runWithArchive(opts);
+    }
+
+
+    // A common operation: dump, then check results
+    public static OutputAnalyzer testDump(String appJar, String appClasses[],
+                                          String... suffix) throws Exception {
+        OutputAnalyzer output = dump(appJar, appClasses, suffix);
+        output.shouldContain("Loading classes to share");
+        output.shouldHaveExitValue(0);
+        return output;
+    }
+
+
+    /**
+     * Simple test -- dump and execute appJar with the given appClasses in classlist.
+     */
+    public static OutputAnalyzer test(String appJar, String appClasses[], String... args)
+        throws Exception {
+        testDump(appJar, appClasses);
+
+        OutputAnalyzer output = exec(appJar, args);
+        return checkExec(output);
+    }
+
+
+    public static OutputAnalyzer checkExecReturn(OutputAnalyzer output, int ret,
+                           boolean checkContain, String... matches) throws Exception {
+        try {
+            for (String s : matches) {
+                if (checkContain) {
+                    output.shouldContain(s);
+                } else {
+                    output.shouldNotContain(s);
+                }
+            }
+            output.shouldHaveExitValue(ret);
+        } catch (Exception e) {
+            checkCommonExecExceptions(output, e);
+        }
+
+        return output;
+    }
+
+
+    // Convenience concatenation utils
+    public static String[] list(String ...args) {
+        return args;
+    }
+
+
+    public static String[] list(String arg, int count) {
+        ArrayList<String> stringList = new ArrayList<String>();
+        for (int i = 0; i < count; i++) {
+            stringList.add(arg);
+        }
+
+        String outputArray[] = stringList.toArray(new String[stringList.size()]);
+        return outputArray;
+    }
+
+
+    public static String[] concat(String... args) {
+        return list(args);
+    }
+
+
+    public static String[] concat(String prefix[], String... extra) {
+        ArrayList<String> list = new ArrayList<String>();
+        for (String s : prefix) {
+            list.add(s);
+        }
+        for (String s : extra) {
+            list.add(s);
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
+
+
+    // ===================== Concatenate paths
+    public static String concatPaths(String... paths) {
+        String prefix = "";
+        String s = "";
+        for (String p : paths) {
+            s += prefix;
+            s += p;
+            prefix = File.pathSeparator;
+        }
+        return s;
+    }
+
+
+    public static String getTestJar(String jar) {
+        File jarFile = CDSTestUtils.getTestArtifact(jar, true);
+        if (!jarFile.isFile()) {
+            throw new RuntimeException("Not a regular file: " + jarFile.getPath());
+        }
+        return jarFile.getPath();
+    }
+
+
+    public static String getTestDir(String d) {
+        File dirFile = CDSTestUtils.getTestArtifact(d, true);
+        if (!dirFile.isDirectory()) {
+            throw new RuntimeException("Not a directory: " + dirFile.getPath());
+        }
+        return dirFile.getPath();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary ensure -XX:+TraceClassPaths showing entire expecting app classpath
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main TraceLongClasspath
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TraceLongClasspath {
+
+    final static String ps = File.pathSeparator;
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+
+        String longClassPath =
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/user-patch.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/abc-startup.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/features/com.foobar.db.jdbc7-dms.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/server/lib/someapps.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/../foobar_common/modules/net.xy.batcontrib_1.1.0.0_1-0b3/lib/bat-contrib.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/modules/features/foobar.aas.common.kkkkkkkkkkk.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.common.adapters_11.1.1/foobar.abc.common.adapters.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.plane.adapter_12.1.3/foobar.plane.adapter.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/lib/ccccccccar-common.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/communications/modules/config.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/communications/modules/userprefs-config.jar" + ps +
+            "/scratch/xxxx/yyyy/XXXXXX/aaaaaaaa/xxxxxxx/xxxxxxxx.us.foobar.com/CommonDomain/config/abc-infra" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/qqqqqq-all-1.6.5.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.thread_11.1.1/foobar.abc.thread.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.thread_11.1.1/thread-rrrrrrr-ext-aas.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.adapter_11.1.1/foobar.abc.adapter.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.ccc_11.1.1/foobar.abc.ccc.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/bbb/lib/commons-configuration.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/bbb/lib/commons-lang.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/bbb/lib/commons-logging.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.wccore/foobar-ppppppp-api.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/internal/features/rrr_aaxyxx_foobar.rrr.aas.classpath.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.thread_11.1.1/rrrrrrrr-api.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/commons-xxx-1.1.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/abc/abc/modules/foobar.abc.mgmt_11.1.1/abc-infra-mgmt.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/eee/archives/eee-eee.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/common/march/lib/marchnet.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/common/march/lib/marchclient.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/aaserver/common/march/lib/march.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/jlib/iiiloader.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/xxxxxxyyzzzzz/classes-xxxxxxyyzzzzz.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/mmmmmmm/lib/abc_core.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/mmmmmmm/lib/abc_codec.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/wwcontent/cde/iii/components/mmmmmmm/lib/abc_imageio.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
+            "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar";
+
+        longClassPath += ps + appJar;
+        // Dump an archive with a specified JAR file in -classpath
+        TestCommon.testDump(longClassPath, TestCommon.list("Hello"));
+
+        // Then try to execute the archive with a different classpath and with -XX:+TraceClassPaths.
+        // The diagnosis "expecting" app classpath trace should show the entire classpath.
+        OutputAnalyzer output = TestCommon.execCommon(
+            "-XX:+TraceClassPaths",
+            "-cp", appJar,
+            "Hello");
+        output.shouldContain("Unable to use shared archive");
+        output.shouldContain("shared class paths mismatch");
+        // the "expecting" app classpath from -XX:+TraceClassPaths should not
+        // be truncated
+        output.shouldContain(longClassPath);
+        output.shouldHaveExitValue(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/UseAppCDS.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Testing use of UseAppCDS flag
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build UseAppCDS_Test
+ * @run main UseAppCDS
+ */
+
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.*;
+
+public class UseAppCDS {
+
+    // Class UseAppCDS_Test is loaded by the App loader
+
+    static final String TEST_OUT = "UseAppCDS_Test.main--executed";
+
+    private static final String TESTJAR = "./test.jar";
+    private static final String TESTNAME = "UseAppCDS_Test";
+    private static final String TESTCLASS = TESTNAME + ".class";
+
+    private static final String CLASSES_DIR = System.getProperty("test.classes", ".");
+    private static final String CLASSLIST_FILE = "./UseAppCDS.classlist";
+    private static final String ARCHIVE_FILE = "./shared.jsa";
+    private static final String BOOTCLASS = "java.lang.Class";
+
+    public static void main(String[] args) throws Exception {
+
+        // First create a jar file for the application "test" class
+        JDKToolLauncher jar = JDKToolLauncher.create("jar")
+            .addToolArg("-cf")
+            .addToolArg(TESTJAR)
+            .addToolArg("-C")
+            .addToolArg(CLASSES_DIR)
+            .addToolArg(TESTCLASS);
+
+        ProcessBuilder pb = new ProcessBuilder(jar.getCommand());
+        TestCommon.executeAndLog(pb, "jar01").shouldHaveExitValue(0);
+
+        pb = new ProcessBuilder(jar.getCommand());
+        TestCommon.executeAndLog(pb, "jar02").shouldHaveExitValue(0);
+
+        // In all tests the BOOTCLASS should be loaded/dumped/used
+
+        // Test 1: No AppCDS - dumping loaded classes excludes the "test" classes
+        dumpLoadedClasses(false, new String[] { BOOTCLASS },
+                          new String[] { TESTNAME });
+
+        // Test 2:    AppCDS - dumping loaded classes includes "test" classes
+        dumpLoadedClasses(true, new String[] { BOOTCLASS, TESTNAME },
+                          new String[0]);
+
+        // Next tests rely on the classlist we just dumped
+
+        // Test 3: No AppCDS - "test" classes in classlist ignored when dumping
+        dumpArchive(false, new String[] { BOOTCLASS },
+                    new String[] { TESTNAME});
+
+        // Test 4:    AppCDS - "test" classes in classlist are dumped
+        dumpArchive(true, new String[] { BOOTCLASS, TESTNAME },
+                    new String[0]);
+
+        // Next tests rely on the archive we just dumped
+
+        // Test 5: No AppCDS - Using archive containing "test" classes ignores them
+        useArchive(false, new String[] { BOOTCLASS },
+                   new String[] { TESTNAME });
+
+        // Test 6:    AppCDS - Using archive containing "test" classes loads them
+        useArchive(true, new String[] { BOOTCLASS, TESTNAME },
+                   new String[0]);
+    }
+
+    public static List<String> toClassNames(String filename) throws IOException {
+        ArrayList<String> classes = new ArrayList<>();
+        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
+        for (; ; ) {
+            String line = br.readLine();
+            if (line == null)
+                break;
+            classes.add(line.replaceAll("/", "."));
+        }
+        return classes;
+    }
+
+    static void dumpLoadedClasses(boolean useAppCDS, String[] expectedClasses,
+                                  String[] unexpectedClasses) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            true,
+            "-XX:DumpLoadedClassList=" + CLASSLIST_FILE,
+            "-cp",
+            TESTJAR,
+            useAppCDS ? "-XX:+UseAppCDS" : "-XX:-UseAppCDS",
+            TESTNAME,
+            TEST_OUT);
+
+        OutputAnalyzer output = TestCommon.executeAndLog(pb, "dump-loaded-classes")
+            .shouldHaveExitValue(0).shouldContain(TEST_OUT);
+
+        List<String> dumpedClasses = toClassNames(CLASSLIST_FILE);
+
+        for (String clazz : expectedClasses) {
+            if (!dumpedClasses.contains(clazz)) {
+                throw new RuntimeException(clazz + " missing in " +
+                                           CLASSLIST_FILE);
+            }
+        }
+        for (String clazz : unexpectedClasses) {
+            if (dumpedClasses.contains(clazz)) {
+                throw new RuntimeException("Unexpectedly found " + clazz +
+                                           " in " + CLASSLIST_FILE);
+            }
+        }
+    }
+
+    static void dumpArchive(boolean useAppCDS, String[] expectedClasses,
+                            String[] unexpectedClasses) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            true,
+            useAppCDS ? "-XX:-UnlockDiagnosticVMOptions" :
+                        "-XX:+UnlockDiagnosticVMOptions",
+            "-cp",
+            TESTJAR,
+            useAppCDS ? "-XX:+UseAppCDS" : "-XX:-UseAppCDS",
+            "-XX:SharedClassListFile=" + CLASSLIST_FILE,
+            "-XX:SharedArchiveFile=" + ARCHIVE_FILE,
+            "-Xlog:cds",
+            "-Xshare:dump");
+
+        OutputAnalyzer output = TestCommon.executeAndLog(pb, "dump-archive")
+            .shouldHaveExitValue(0);
+
+        for (String clazz : expectedClasses) {
+            String failed = "Preload Warning: Cannot find " + clazz;
+            output.shouldNotContain(failed);
+        }
+        for (String clazz : unexpectedClasses) {
+            String failed = "Preload Warning: Cannot find " + clazz;
+            output.shouldContain(failed);
+        }
+    }
+
+    static void useArchive(boolean useAppCDS, String[] expectedClasses,
+                           String[] unexpectedClasses) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            true,
+            useAppCDS ? "-XX:-UnlockDiagnosticVMOptions" :
+                        "-XX:+UnlockDiagnosticVMOptions",
+            "-cp",
+            TESTJAR,
+            useAppCDS ? "-XX:+UseAppCDS" : "-XX:-UseAppCDS",
+            "-XX:SharedArchiveFile=" + ARCHIVE_FILE,
+            "-verbose:class",
+            "-Xshare:on",
+            TESTNAME,
+            TEST_OUT );
+
+        OutputAnalyzer output = TestCommon.executeAndLog(pb, "use-archive");
+        if (CDSTestUtils.isUnableToMap(output))
+            System.out.println("Unable to map: test case skipped");
+        else
+            output.shouldHaveExitValue(0).shouldContain(TEST_OUT);
+
+        // Quote the class name in the regex as it may contain $
+        String prefix = ".class,load. ";
+        String archive_suffix = ".*source: shared objects file.*";
+        String jar_suffix = ".*source: .*\\.jar";
+
+        for (String clazz : expectedClasses) {
+            String pattern = prefix + clazz + archive_suffix;
+            try {
+                output.shouldMatch(pattern);
+            } catch (Exception e) {
+                TestCommon.checkCommonExecExceptions(output, e);
+            }
+        }
+
+        for (String clazz : unexpectedClasses) {
+            String pattern = prefix + clazz + archive_suffix;
+            try {
+                output.shouldNotMatch(pattern);
+            } catch (Exception e) {
+                TestCommon.checkCommonExecExceptions(output, e);
+            }
+            pattern = prefix + clazz + jar_suffix;
+            try {
+                output.shouldMatch(pattern);
+            } catch (Exception e) {
+                TestCommon.checkCommonExecExceptions(output, e);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/UseAppCDS_Test.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+public class UseAppCDS_Test {
+    // args are from UseAppCDS:
+    // args[0] = TEST_OUT
+    public static void main(String[] args) {
+        System.out.println(args[0]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.nio.file.Files;
+
+import java.util.*;
+import jdk.internal.org.objectweb.asm.*;
+
+/**
+ * The testsets contained in this class are executed by ./VerifierTest_*.java, so that
+ * individual testsets can be executed in parallel to shorten the total time required.
+ */
+public class VerifierTest implements Opcodes {
+    // Test verification settings for dumping & runtime
+    static final String VFY_ALL = "-Xverify:all";
+    static final String VFY_REMOTE = "-Xverify:remote"; // default
+    static final String VFY_NONE = "-Xverify:none";
+
+    static final String ERR =
+        "ERROR: class VerifierTestC was loaded unexpectedly";
+    static final String MAP_FAIL =
+        "shared archive file was created with less restrictive verification setting";
+    static final String VFY_ERR = "java.lang.VerifyError";
+
+    enum Testset1Part {
+        A, B
+    }
+
+    public static void main(String[] args) throws Exception {
+        String subCaseId = args[0];
+        String jarName_verifier_test_tmp = "verifier_test_tmp" + "_" + subCaseId;
+        String jarName_verifier_test = "verifier_test" + "_" + subCaseId;
+        String jarName_greet = "greet" + "_" + subCaseId;
+        String jarName_hi = "hi" + "_" + subCaseId;
+
+
+        JarBuilder.build(jarName_verifier_test_tmp, "VerifierTest0", "VerifierTestA",
+                         "VerifierTestB", "VerifierTestC", "VerifierTestD", "VerifierTestE",
+                         "UnverifiableBase", "UnverifiableIntf", "UnverifiableIntfSub");
+        JarBuilder.build(jarName_greet, "Greet");
+        JarBuilder.build(jarName_hi, "Hi", "Hi$MyClass");
+
+        File dir = new File(System.getProperty("test.classes", "."));
+        File jarSrcFile = new File(dir, jarName_verifier_test_tmp + ".jar");
+        File jarFile = new File(dir, jarName_verifier_test + ".jar");
+        String jar = jarFile.getPath();
+
+        if (!jarFile.exists() || jarFile.lastModified() < jarSrcFile.lastModified()) {
+            createTestJarFile(jarSrcFile, jarFile);
+        } else {
+            System.out.println("Already up-to-date: " + jarFile);
+        }
+
+        String noAppClasses[] = TestCommon.list("");
+        String appClasses[] = TestCommon.list("UnverifiableBase",
+                                              "UnverifiableIntf",
+                                              "UnverifiableIntfSub",
+                                              "VerifierTestA",
+                                              "VerifierTestB",
+                                              "VerifierTestC",
+                                              "VerifierTestD",
+                                              "VerifierTestE",
+                                              "VerifierTest0");
+
+
+        switch (subCaseId) {
+        case "0":         testset_0(jar, noAppClasses, appClasses);                 return;
+        case "1A":        testset_1(jar, noAppClasses, appClasses, Testset1Part.A); return;
+        case "1B":        testset_1(jar, noAppClasses, appClasses, Testset1Part.B); return;
+        case "2":         testset_2(jarName_greet, jarName_hi);                   return;
+        default:
+            throw new RuntimeException("Unknown option: " + subCaseId);
+        }
+    }
+
+    static void testset_0(String jar, String[] noAppClasses, String[] appClasses) throws Exception {
+        // Dumping should fail if the IgnoreUnverifiableClassesDuringDump
+        // option is not enabled.
+        OutputAnalyzer output = TestCommon.dump(jar, appClasses,
+                            "-XX:+UnlockDiagnosticVMOptions",
+                            "-XX:-IgnoreUnverifiableClassesDuringDump");
+        output.shouldContain("Please remove the unverifiable classes");
+        output.shouldHaveExitValue(1);
+
+        // By default, bad classes should be ignored during dumping.
+        TestCommon.testDump(jar, appClasses);
+    }
+
+    static void testset_1(String jar, String[] noAppClasses, String[] appClasses, Testset1Part part)
+        throws Exception
+    {
+        String config[][] = {
+            // {dump_list, dumptime_verification_setting,
+            //  runtime_verification_setting, runtime_output},
+
+            // Dump app/ext with -Xverify:remote
+            {"app",   VFY_REMOTE, VFY_REMOTE, VFY_ERR},
+            {"app",   VFY_REMOTE, VFY_ALL,    MAP_FAIL},
+            {"app",   VFY_REMOTE, VFY_NONE,   ERR },
+            // Dump app/ext with -Xverify:all
+            {"app",   VFY_ALL,    VFY_REMOTE, VFY_ERR },
+            {"app",   VFY_ALL,    VFY_ALL,    VFY_ERR },
+            {"app",   VFY_ALL,    VFY_NONE,   ERR },
+            // Dump app/ext with -Xverify:none
+            {"app",   VFY_NONE,   VFY_REMOTE, MAP_FAIL},
+            {"app",   VFY_NONE,   VFY_ALL,    MAP_FAIL},
+            {"app",   VFY_NONE,   VFY_NONE,   ERR },
+            // Dump sys only with -Xverify:remote
+            {"noApp", VFY_REMOTE, VFY_REMOTE, VFY_ERR},
+            {"noApp", VFY_REMOTE, VFY_ALL,    VFY_ERR},
+            {"noApp", VFY_REMOTE, VFY_NONE,   ERR},
+            // Dump sys only with -Xverify:all
+            {"noApp", VFY_ALL, VFY_REMOTE,    VFY_ERR},
+            {"noApp", VFY_ALL, VFY_ALL,       VFY_ERR},
+            {"noApp", VFY_ALL, VFY_NONE,      ERR},
+            // Dump sys only with -Xverify:none
+            {"noApp", VFY_NONE, VFY_REMOTE,   VFY_ERR},
+            {"noApp", VFY_NONE, VFY_ALL,      VFY_ERR},
+            {"noApp", VFY_NONE, VFY_NONE,     ERR},
+        };
+
+        int loop_start, loop_stop;
+
+        // Further break down testset_1 into two parts (to be invoked from VerifierTest_1A.java
+        // and VerifierTest_1B.java) to improve parallel test execution time.
+        switch (part) {
+        case A:
+            loop_start = 0;
+            loop_stop  = 9;
+            break;
+        case B:
+        default:
+            assert part == Testset1Part.B;
+            loop_start = 9;
+            loop_stop  = config.length;
+            break;
+        }
+
+        String prev_dump_setting = "";
+        for (int i = loop_start; i < loop_stop; i ++) {
+            String dump_list[] = config[i][0].equals("app") ? appClasses :
+                noAppClasses;
+            String dump_setting = config[i][1];
+            String runtime_setting = config[i][2];
+            String runtime_output = config[i][3];
+            System.out.println("Test case [" + i + "]: dumping " + config[i][0] +
+                               " with " + dump_setting +
+                               ", run with " + runtime_setting);
+            if (!dump_setting.equals(prev_dump_setting)) {
+                OutputAnalyzer dumpOutput = TestCommon.dump(
+                                                            jar, dump_list, dump_setting,
+                                                            // FIXME: the following options are for working around a GC
+                                                            // issue - assert failure when dumping archive with the -Xverify:all
+                                                            "-Xms256m",
+                                                            "-Xmx256m");
+            }
+            OutputAnalyzer runtimeOutput = TestCommon.execCommon(
+                                                                 "-cp", jar,
+                                                                 runtime_setting,
+                                                                 "VerifierTest0");
+            try {
+                runtimeOutput.shouldContain(runtime_output);
+            } catch (RuntimeException re) {
+                // Check if the failure is due to archive mapping failure.
+                // If not, a RuntimeException will be thrown.
+                runtimeOutput.shouldContain("Unable to use shared archive");
+            }
+            prev_dump_setting = dump_setting;
+        }
+    }
+
+    static void testset_2(String jarName_greet, String jarName_hi) throws Exception {
+        String appClasses[];
+        String jar;
+
+        // The following section is for testing the scenarios where
+        // the classes are verifiable during dump time.
+        appClasses = TestCommon.list("Hi",
+                                     "Greet",
+                                     "Hi$MyClass");
+        jar = TestCommon.getTestJar(jarName_hi + ".jar") + File.pathSeparator +
+            TestCommon.getTestJar(jarName_greet + ".jar");
+        final String PASS_RESULT = "Hi, how are you?";
+        String config2[][] = {
+            // {dump_list, dumptime_verification_setting,
+            //  runtime_verification_setting, runtime_output},
+
+            // Dump app/ext with -Xverify:remote
+            {"app",   VFY_REMOTE, VFY_REMOTE, PASS_RESULT},
+            {"app",   VFY_REMOTE, VFY_ALL,    MAP_FAIL},
+            {"app",   VFY_REMOTE, VFY_NONE,   PASS_RESULT },
+            // Dump app/ext with -Xverify:all
+            {"app",   VFY_ALL,    VFY_REMOTE, PASS_RESULT },
+            {"app",   VFY_ALL,    VFY_ALL,    PASS_RESULT },
+            {"app",   VFY_ALL,    VFY_NONE,   PASS_RESULT },
+            // Dump app/ext with -Xverify:none
+            {"app",   VFY_NONE,   VFY_REMOTE, MAP_FAIL},
+            {"app",   VFY_NONE,   VFY_ALL,    MAP_FAIL},
+            {"app",   VFY_NONE,   VFY_NONE,   PASS_RESULT },
+        };
+        for (int i = 0; i < config2.length; i ++) {
+            // config2[i][0] is always set to "app" in this test
+            String dump_setting = config2[i][1];
+            String runtime_setting = config2[i][2];
+            String runtime_output = config2[i][3];
+            System.out.println("Test case [" + i + "]: dumping " + config2[i][0] +
+                               " with " + dump_setting +
+                               ", run with " + runtime_setting);
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+                                                        jar, appClasses, dump_setting,
+                                                        "-XX:+UnlockDiagnosticVMOptions",
+                                                        // FIXME: the following options are for working around a GC
+                                                        // issue - assert failure when dumping archive with the -Xverify:all
+                                                        "-Xms256m",
+                                                        "-Xmx256m");
+            OutputAnalyzer runtimeOutput = TestCommon.execCommon(
+                                                                 "-cp", jar,
+                                                                 runtime_setting,
+                                                                 "Hi");
+            try {
+                runtimeOutput.shouldContain(runtime_output);
+            } catch (RuntimeException re) {
+                // Check if the failure is due to archive mapping failure.
+                // If not, a RuntimeException will be thrown.
+                runtimeOutput.shouldContain("Unable to use shared archive");
+            }
+        }
+
+    }
+
+    static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {
+        jarFile.delete();
+        Files.copy(jarSrcFile.toPath(), jarFile.toPath());
+
+        File dir = new File(System.getProperty("test.classes", "."));
+        File outdir = new File(dir, "verifier_test_classes");
+        outdir.mkdir();
+
+        writeClassFile(new File(outdir, "UnverifiableBase.class"), makeUnverifiableBase());
+        writeClassFile(new File(outdir, "UnverifiableIntf.class"), makeUnverifiableIntf());
+
+        JarBuilder.update(jarFile.getPath(), outdir.getPath());
+    }
+
+    static void writeClassFile(File file, byte bytecodes[]) throws Exception {
+        try (FileOutputStream fos = new FileOutputStream(file)) {
+            fos.write(bytecodes);
+        }
+    }
+
+    // This was obtained using JDK8: java jdk.internal.org.objectweb.asm.util.ASMifier tmpclasses/UnverifiableBase.class
+    static byte[] makeUnverifiableBase() throws Exception {
+        ClassWriter cw = new ClassWriter(0);
+        FieldVisitor fv;
+        MethodVisitor mv;
+        AnnotationVisitor av0;
+
+        cw.visit(V1_6, ACC_SUPER, "UnverifiableBase", null, "java/lang/Object", null);
+        {
+            fv = cw.visitField(ACC_FINAL + ACC_STATIC, "x", "LVerifierTest;", null, null);
+            fv.visitEnd();
+        }
+        {
+            mv = cw.visitMethod(0, "<init>", "()V", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(1, 1);
+            mv.visitEnd();
+        }
+        {
+            mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+            mv.visitCode();
+            //WAS mv.visitTypeInsn(NEW, "VerifierTest");
+            mv.visitTypeInsn(NEW, "java/lang/Object");
+            mv.visitInsn(DUP);
+            mv.visitMethodInsn(INVOKESPECIAL, "VerifierTest0", "<init>", "()V", false);
+            mv.visitFieldInsn(PUTSTATIC, "UnverifiableBase", "x", "LVerifierTest;");
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(2, 0);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    // This was obtained using JDK8: java jdk.internal.org.objectweb.asm.util.ASMifier tmpclasses/UnverifiableIntf.class
+    static byte[] makeUnverifiableIntf() throws Exception {
+        ClassWriter cw = new ClassWriter(0);
+        FieldVisitor fv;
+        MethodVisitor mv;
+        AnnotationVisitor av0;
+
+        cw.visit(V1_6, ACC_ABSTRACT + ACC_INTERFACE, "UnverifiableIntf", null, "java/lang/Object", null);
+
+        {
+            fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "x", "LVerifierTest0;", null, null);
+            fv.visitEnd();
+        }
+        {
+            mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+            mv.visitCode();
+            //WAS mv.visitTypeInsn(NEW, "VerifierTest");
+            mv.visitTypeInsn(NEW, "java/lang/Object");
+            mv.visitInsn(DUP);
+            mv.visitMethodInsn(INVOKESPECIAL, "VerifierTest0", "<init>", "()V", false);
+            mv.visitFieldInsn(PUTSTATIC, "UnverifiableIntf", "x", "LVerifierTest0;");
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(2, 0);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest_0.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Unverfiable app classes should not be archived.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.jartool/sun.tools.jar
+ *          java.base/jdk.internal.org.objectweb.asm
+ * @compile test-classes/Greet.java
+ * @compile test-classes/Hi.java
+ * @compile test-classes/VerifierTest0.java
+ * @run main/othervm/timeout=3600 VerifierTest 0
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest_1A.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Unverfiable app classes should not be archived.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.jartool/sun.tools.jar
+ *          java.base/jdk.internal.org.objectweb.asm
+ * @compile test-classes/Greet.java
+ * @compile test-classes/Hi.java
+ * @compile test-classes/VerifierTest0.java
+ * @run main/othervm/timeout=3600 VerifierTest 1A
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest_1B.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Unverfiable app classes should not be archived.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.jartool/sun.tools.jar
+ *          java.base/jdk.internal.org.objectweb.asm
+ * @compile test-classes/Greet.java
+ * @compile test-classes/Hi.java
+ * @compile test-classes/VerifierTest0.java
+ * @run main/othervm/timeout=3600 VerifierTest 1B
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest_2.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Unverfiable app classes should not be archived.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.jartool/sun.tools.jar
+ *          java.base/jdk.internal.org.objectweb.asm
+ * @compile test-classes/Greet.java
+ * @compile test-classes/Hi.java
+ * @compile test-classes/VerifierTest0.java
+ * @run main/othervm/timeout=3600 VerifierTest 2
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/WideIloadTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/**
+ * @test
+ * @summary Test 'iload_w' bytecode in shared class
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Iloadw.jasm
+ * @compile test-classes/IloadwMain.java
+ * @run main WideIloadTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class WideIloadTest {
+    public static void main(String args[]) throws Exception {
+        JarBuilder.build("iload_w", "Iloadw", "IloadwMain");
+        String appJar = TestCommon.getTestJar("iload_w.jar");
+        OutputAnalyzer dumpOutput = TestCommon.dump(appJar, TestCommon.list(
+                                        "Iloadw", "IloadwMain"));
+        TestCommon.checkDump(dumpOutput);
+        OutputAnalyzer execOutput = TestCommon.exec(appJar, "IloadwMain");
+        TestCommon.checkExec(execOutput, "Passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary classpath mismatch between dump time and execution time
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main WrongClasspath
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class WrongClasspath {
+
+  public static void main(String[] args) throws Exception {
+    String appJar = JarBuilder.getOrCreateHelloJar();
+
+    // Dump an archive with a specified JAR file in -classpath
+    TestCommon.testDump(appJar, TestCommon.list("Hello"));
+
+    // Then try to execute the archive without -classpath -- it should fail
+    OutputAnalyzer output = TestCommon.execCommon(
+        /* "-cp", appJar, */ // <- uncomment this and the execution should succeed
+        "Hello");
+    output.shouldContain("Unable to use shared archive");
+    output.shouldContain("shared class paths mismatch");
+    output.shouldHaveExitValue(1);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/XShareAutoWithChangedJar.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test -Xshare:auto for AppCDS
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @run main XShareAutoWithChangedJar
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class XShareAutoWithChangedJar {
+  public static void main(String[] args) throws Exception {
+    String appJar = JarBuilder.build("XShareAutoWithChangedJar", "Hello");
+
+    // 1. dump
+    OutputAnalyzer output = TestCommon.dump(appJar, TestCommon.list("Hello"));
+    TestCommon.checkDump(output);
+
+    // 2. change the jar
+    JarBuilder.build("XShareAutoWithChangedJar", "Hello");
+
+    // 3. exec
+    output = TestCommon.execAuto("-cp", appJar, "Hello");
+    output.shouldContain("Hello World");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/CheckCachedResolvedReferences.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test resolved_references
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox
+ * @compile CheckCachedResolvedReferencesApp.java
+ * @compile ../test-classes/Hello.java
+ * @run main ClassFileInstaller -jar app.jar CheckCachedResolvedReferencesApp
+ * @run main ClassFileInstaller -jar hello.jar Hello
+ * @run main ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run main CheckCachedResolvedReferences
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+public class CheckCachedResolvedReferences {
+    public static void main(String[] args) throws Exception {
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+        String appJar = ClassFileInstaller.getJarPath("app.jar");
+        String helloJarPath = ClassFileInstaller.getJarPath("hello.jar");
+
+        String classlist[] = new String[] {
+            "CheckCachedResolvedReferencesApp",            // built-in app loader
+            "java/lang/Object id: 1",                      // boot loader
+            "Hello id: 2 super: 1 source: " + helloJarPath // custom loader
+        };
+
+        TestCommon.testDump(appJar, classlist, use_whitebox_jar);
+        OutputAnalyzer output = TestCommon.exec(appJar, use_whitebox_jar,
+                                                "-XX:+UnlockDiagnosticVMOptions",
+                                                "-XX:+WhiteBoxAPI",
+                                                "CheckCachedResolvedReferencesApp",
+                                                helloJarPath);
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/CheckCachedResolvedReferencesApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import sun.hotspot.WhiteBox;
+
+public class CheckCachedResolvedReferencesApp {
+    public static void main(String args[]) throws Exception {
+        String path = args[0];
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+
+        URLClassLoader loader = new URLClassLoader(urls);
+        Class hello = loader.loadClass("Hello");
+        System.out.println("Loaded " + hello + " from " + url + " using loader " + loader);
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        if (!wb.areOpenArchiveHeapObjectsMapped()) {
+            System.out.println("Archived open_archive_heap objects are not mapped.");
+            System.out.println("This may happen during normal operation. Test Skipped.");
+            return;
+        }
+
+        // CheckCachedResolvedReferencesApp is shared class and loaded by the
+        // AppClassLoader. It should have cached resolved_references.
+        if (wb.isSharedClass(CheckCachedResolvedReferencesApp.class)) {
+            Object refs1 = wb.getResolvedReferences(CheckCachedResolvedReferencesApp.class);
+            if (refs1 != null && wb.isShared(refs1)) {
+                System.out.println(
+                    "resolved references from CheckCachedResolvedReferencesApp is cached");
+            } else {
+                throw new RuntimeException(
+                    "FAILED. CheckCachedResolvedReferencesApp has no cached resolved references");
+            }
+        }
+
+        // Hello is shared class and loaded by the 'loader' defined in current app.
+        // It should not have cached resolved_references.
+        if (wb.isSharedClass(hello)) {
+            Object refs2 = wb.getResolvedReferences(hello);
+            if (refs2 != null) {
+                if (!wb.isShared(refs2)) {
+                    System.out.println("resolved references from hello is not cached");
+                } else {
+                    throw new RuntimeException(
+                        "FAILED. Hello has unexpected cached resolved references");
+                }
+            } else {
+                throw new RuntimeException("FAILED. Hello has no resolved references");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/DumpTimeVerifyFailure.config.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,3 @@
+VERSION: 1.0
+@SECTION: String
+26: shared_string_from_MyInner
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/DumpTimeVerifyFailure.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Dump time should not crash if any class with shared strings fails verification due to missing dependencies.
+ * @bug 8186789
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile MyOuter.java MyException.java
+ * @run main DumpTimeVerifyFailure
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class DumpTimeVerifyFailure {
+    public static void main(String[] args) throws Exception {
+        // App classes (see MyOuter.java):
+        //   MyOuter
+        //   MyInnder$MyOuter extends MyOuter
+        //   MyException
+        //
+        // MyOuter$MyInner.test() throws MyException.
+        // The missingMyException.jar file only includes MyOuter and
+        // MyOuter$MyInner classes, but not the MyException class.
+        // At dump time, MyOuter and MyOuter$MyInner classes fail
+        // verification due to missing MyException class.
+        String[] ARCHIVE_CLASSES = {"MyOuter", "MyOuter$MyInner"};
+        String appJar = JarBuilder.build("missingMyException", ARCHIVE_CLASSES);
+
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+                appJar, ARCHIVE_CLASSES,
+                "-Xlog:verification",
+                "-XX:SharedArchiveConfigFile=" + TestCommon.getSourceFile("DumpTimeVerifyFailure.config.txt"));
+        TestCommon.checkDump(dumpOutput, "Loading classes to share");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStress.config.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,3 @@
+VERSION: 1.0
+@SECTION: String
+25: GCStressApp_shared_string
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStressApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import java.io.*;
+import java.util.*;
+import sun.hotspot.WhiteBox;
+
+// All strings in archived classes are shared
+public class GCStressApp {
+    static WhiteBox wb = WhiteBox.getWhiteBox();
+    static int[] arr;
+
+    static String get_shared_string() {
+        String shared_str = "GCStressApp_shared_string";
+        return shared_str;
+    }
+
+    static String get_shared_string1() {
+        String shared_str1 = "GCStressApp_shared_string1";
+        return shared_str1;
+    }
+
+    static void allocAlot() {
+        try {
+            Random random = new Random();
+            for (int i = 0; i < 1024 * 1024; i++) {
+                int len = random.nextInt(10000);
+                arr = new int[len];
+            }
+        } catch (java.lang.OutOfMemoryError e) { }
+    }
+
+    static void runGC() {
+        wb.fullGC();
+    }
+
+    public static void main(String args[]) throws Exception {
+        if (!wb.isSharedClass(GCStressApp.class)) {
+           System.out.println("GCStressApp is not shared. Possibly there was a mapping failure.");
+           return;
+        }
+
+        if (wb.areSharedStringsIgnored()) {
+          System.out.println("Shared strings are ignored.");
+          return;
+        }
+
+        Object refs = wb.getResolvedReferences(GCStressApp.class);
+        if (wb.isShared(refs)) {
+            String shared_str = get_shared_string();
+            String shared_str1 = get_shared_string1();
+
+            if (!wb.isShared(shared_str)) {
+                throw new RuntimeException("FAILED. GCStressApp_shared_string is not shared");
+            }
+
+            if (!wb.isShared(shared_str1)) {
+                throw new RuntimeException("FAILED. GCStressApp_shared_string1 is not shared");
+            }
+
+            allocAlot();
+            runGC();
+            runGC();
+            runGC();
+
+            System.out.println("Passed");
+        } else {
+            System.out.println(
+                "No cached resolved references. Open archive heap data is not used.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStressTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox
+ * @compile GCStressApp.java
+ * @run main ClassFileInstaller -jar gcstress.jar GCStressApp
+ * @run main ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run main GCStressTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class GCStressTest {
+    public static void main(String[] args) throws Exception {
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+        String appJar = ClassFileInstaller.getJarPath("gcstress.jar");
+        String appClasses[] = TestCommon.list("GCStressApp");
+
+        OutputAnalyzer output = TestCommon.dump(appJar, appClasses,
+                                                use_whitebox_jar,
+                                                "-Xms20M", "-Xmx20M");
+        output = TestCommon.exec(appJar, use_whitebox_jar,
+                                 "-Xlog:cds=info",
+                                 "-Xms20M", "-Xmx20M",
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI","GCStressApp");
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/InstrumentationAgent.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Premain-Class: InstrumentationRegisterClassFileTransformer
+Agent-Class: InstrumentationRegisterClassFileTransformer
+Can-Retransform-Classes: true
+Can-Redefine-Classes: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/MyException.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+public class MyException extends Exception {
+    public MyException(String msg) {
+        super(msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/MyOuter.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+public class MyOuter {
+   public void exp() throws MyException {
+       throw new MyException("MyOuter exception");
+   }
+
+   public void test() throws Exception {
+       System.out.println("MyOuter");
+       try {
+          exp();
+       } catch (MyException e) {
+       }
+   }
+
+   public static final class MyInner extends MyOuter {
+       static String myString = "shared_string_from_MyInner";
+       public void test() {
+           System.out.println("MyInner");
+       }
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/OpenArchiveRegion.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test open archive heap regions
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @run main OpenArchiveRegion
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class OpenArchiveRegion {
+    public static void main(String[] args) throws Exception {
+        JarBuilder.getOrCreateHelloJar();
+        String appJar = TestCommon.getTestJar("hello.jar");
+        String appClasses[] = TestCommon.list("Hello");
+
+        // Dump with open archive heap region, requires G1 GC
+        OutputAnalyzer output = TestCommon.dump(appJar, appClasses);
+        TestCommon.checkDump(output, "oa0 space:");
+        output.shouldNotContain("oa0 space:         0 [");
+        output = TestCommon.exec(appJar, "Hello");
+        TestCommon.checkExec(output, "Hello World");
+        output = TestCommon.exec(appJar, "-XX:+UseSerialGC", "Hello");
+        TestCommon.checkExec(output, "Hello World");
+
+        // Dump with open archive heap region disabled when G1 GC is not in use
+        output = TestCommon.dump(appJar, appClasses, "-XX:+UseParallelGC");
+        TestCommon.checkDump(output);
+        output.shouldNotContain("oa0 space:");
+        output = TestCommon.exec(appJar, "Hello");
+        TestCommon.checkExec(output, "Hello World");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RangeNotWithinHeap.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Shared classes can still be used when archived heap regions cannot be
+ *          mapped due to out of range, and -Xshare:on should not fail. Test on
+ *          linux 64-bit only since the HeapBaseMinAddress value is platform specific.
+ *          The value used in the test may cause different behavior on other platforms.
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires (os.family == "linux") & (os.arch == "amd64") & (sun.arch.data.model == "64")
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @run main RangeNotWithinHeap
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RangeNotWithinHeap {
+    public static void main(String[] args) throws Exception {
+        JarBuilder.getOrCreateHelloJar();
+        String appJar = TestCommon.getTestJar("hello.jar");
+        String appClasses[] = TestCommon.list("Hello");
+
+        OutputAnalyzer output = TestCommon.dump(appJar, appClasses,
+                    "-XX:HeapBaseMinAddress=0x600000000", "-Xmx6G", "-Xlog:gc+heap=trace");
+        TestCommon.checkDump(output, "oa0 space:");
+
+        // Force archive region out of runtime java heap
+        output = TestCommon.exec(appJar, "Hello");
+        TestCommon.checkExec(output, "Hello World");
+        output = TestCommon.exec(appJar,
+                    "-XX:HeapBaseMinAddress=0x600000000", "-Xmx2G", "-Xlog:gc+heap=trace,cds", "Hello");
+        TestCommon.checkExec(output, "Hello World");
+        try {
+            output.shouldContain(
+                "UseSharedSpaces: Unable to allocate region, range is not within java heap.");
+        } catch (Exception e) {
+            // In rare case the heap data is not used.
+            if (output.getOutput().contains("Cached heap data from the CDS archive is being ignored")) {
+                return;
+            }
+            // Check for common shared class data mapping failures.
+            TestCommon.checkCommonExecExceptions(output, e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.UnmodifiableClassException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.io.File;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import sun.hotspot.WhiteBox;
+
+public class RedefineClassApp {
+    static WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static interface Intf {            // Loaded from Boot class loader (-Xbootclasspath/a).
+        public String get();
+    }
+    public static class Bar implements Intf { // Loaded from Boot class loader.
+        public String get() {
+            return "buzz";
+        }
+    }
+    public static class Foo implements Intf { // Loaded from AppClassLoader
+        public String get() {
+            return "buzz";
+        }
+    }
+
+    static int numTests = 0;
+    static int failed = 0;
+    static Instrumentation instrumentation;
+
+    public static void main(String args[]) throws Throwable {
+        if (wb.areSharedStringsIgnored()) {
+          System.out.println("Shared strings are ignored.");
+          return;
+        }
+
+        File bootJar = new File(args[0]);
+        File appJar  = new File(args[1]);
+
+        instrumentation = InstrumentationRegisterClassFileTransformer.getInstrumentation();
+        System.out.println("INFO: instrumentation = " + instrumentation);
+
+        testBootstrapCDS("Bootstrap Loader", bootJar);
+        testAppCDSv1("Application Loader", appJar);
+
+        if (failed > 0) {
+            throw new RuntimeException("FINAL RESULT: " + failed + " out of " + numTests + " test case(s) have failed");
+        } else {
+            System.out.println("FINAL RESULT: All " + numTests + " test case(s) have passed!");
+        }
+
+        // Full GC. The cached objects in adjustable archive heap regions are
+        // scanned. The archive regions are verified. No error should be
+        // reported.
+        wb.fullGC();
+    }
+
+    static void testBootstrapCDS(String group, File jar) throws Throwable {
+        doTest(group, new Bar(), jar);
+    }
+
+    static void testAppCDSv1(String group, File jar) throws Throwable {
+        doTest(group, new Foo(), jar);
+    }
+
+    static void doTest(String group, Intf object, File jar) throws Throwable {
+        numTests ++;
+
+        Class klass = object.getClass();
+        System.out.println();
+        System.out.println("++++++++++++++++++++++++++");
+        System.out.println("Test group: " + group);
+        System.out.println("Testing with classloader = " + klass.getClassLoader());
+        System.out.println("Testing with class       = " + klass);
+        System.out.println("Test is shared           = " + wb.isSharedClass(klass));
+        System.out.println("++++++++++++++++++++++++++");
+
+        // Call get() before redefine. All strings in archived classes are shared.
+        String res = object.get();
+        System.out.println("get() returns " + res);
+        if (res.equals("buzz") && wb.isShared(res)) {
+            System.out.println("get() returns " + res + ", string is shared");
+        } else {
+            if (!res.equals("buzz")) {
+                System.out.println("FAILED. buzz is expected but got " + res);
+            } else {
+                System.out.println("FAILED. " + res + " is not shared");
+            }
+            failed ++;
+            return;
+        }
+        res = null; // release the local reference to the string
+
+        // Run GC
+        System.gc();
+        System.gc();
+        System.gc();
+
+        // Redefine the shared class
+        byte[] buff = Util.getClassFileFromJar(jar, klass.getName());
+        Util.replace(buff, "buzz", "huzz");
+        String f = "(failed)";
+        try {
+            instrumentation.redefineClasses(new ClassDefinition(klass, buff));
+            f = object.get();
+        } catch (UnmodifiableClassException|UnsupportedOperationException e) {
+            e.printStackTrace();
+        }
+        if (f.equals("huzz")) {
+            System.out.println("PASSED: object.get() after redefinition returns " + f);
+        } else {
+            System.out.println("FAILED: object.get() after redefinition returns " + f);
+            failed ++;
+        }
+
+        // Run GC. Should not crash.
+        System.gc();
+        System.gc();
+        System.gc();
+
+        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++ (done)\n\n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Redefine shared class. GC should not cause crash with cached resolved_references.
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes /test/hotspot/jtreg/runtime/appcds/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @requires vm.flavor != "minimal"
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ * @build sun.hotspot.WhiteBox
+ *        RedefineClassApp
+ *        InstrumentationClassFileTransformer
+ *        InstrumentationRegisterClassFileTransformer
+ * @run main/othervm RedefineClassTest
+ */
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.VirtualMachineDescriptor;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class RedefineClassTest {
+    public static String bootClasses[] = {
+        "RedefineClassApp$Intf",
+        "RedefineClassApp$Bar",
+        "sun.hotspot.WhiteBox",
+    };
+    public static String appClasses[] = {
+        "RedefineClassApp",
+        "RedefineClassApp$Foo",
+    };
+    public static String sharedClasses[] = TestCommon.concat(bootClasses, appClasses);
+
+    public static String agentClasses[] = {
+        "InstrumentationClassFileTransformer",
+        "InstrumentationRegisterClassFileTransformer",
+        "Util",
+    };
+
+    public static void main(String[] args) throws Throwable {
+        runTest();
+    }
+
+    public static void runTest() throws Throwable {
+        String bootJar =
+            ClassFileInstaller.writeJar("RedefineClassBoot.jar", bootClasses);
+        String appJar =
+            ClassFileInstaller.writeJar("RedefineClassApp.jar", appClasses);
+        String agentJar =
+            ClassFileInstaller.writeJar("InstrumentationAgent.jar",
+                                        ClassFileInstaller.Manifest.fromSourceFile("InstrumentationAgent.mf"),
+                                        agentClasses);
+
+        String bootCP = "-Xbootclasspath/a:" + bootJar;
+
+        String agentCmdArg;
+        agentCmdArg = "-javaagent:" + agentJar;
+
+        TestCommon.testDump(appJar, sharedClasses, bootCP, "-Xlog:gc+region=trace");
+
+        OutputAnalyzer out = TestCommon.execAuto("-cp", appJar,
+                bootCP,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-Xlog:gc+region=trace,cds=info",
+                agentCmdArg,
+               "RedefineClassApp", bootJar, appJar);
+        out.reportDiagnosticSummary();
+
+        CDSOptions opts = (new CDSOptions()).setXShareMode("auto");
+        TestCommon.checkExec(out, opts);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatA.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Tests the format checking of class list format.
+ *
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
+ * @run main ClassListFormatA
+ */
+
+public class ClassListFormatA extends ClassListFormatBase {
+    static {
+        // Uncomment the following line to run only one of the test cases
+        // ClassListFormatBase.RUN_ONLY_TEST = "TESTCASE A1";
+    }
+
+    public static void main(String[] args) throws Throwable {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String customJarPath = JarBuilder.build("ClassListFormatA", "CustomLoadee",
+                                            "CustomLoadee2", "CustomInterface2_ia", "CustomInterface2_ib");
+        //----------------------------------------------------------------------
+        // TESTGROUP A: general bad input
+        //----------------------------------------------------------------------
+        dumpShouldFail(
+            "TESTCASE A1: bad input - interface: instead of interfaces:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee interface: 1"
+            ),
+            "Unknown input:");
+
+        dumpShouldFail(
+            "TESTCASE A2: bad input - negative IDs not allowed",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: -1"
+            ),
+            "Error: negative integers not allowed");
+
+        dumpShouldFail(
+            "TESTCASE A3: bad input - bad ID (not an integer)",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: xyz"
+            ),
+            "Error: expected integer");
+
+        if (false) {
+              // FIXME - classFileParser.cpp needs fixing.
+            dumpShouldFail(
+                "TESTCASE A4: bad input - bad ID (integer too big)",
+                appJar, classlist(
+                    "Hello",
+                    "java/lang/Object id: 2147483648" // <- this is 0x80000000
+                ),
+                "Error: expected integer");
+
+              // FIXME
+            dumpShouldFail(
+                "TESTCASE A5: bad input - bad ID (integer too big)",
+                appJar, classlist(
+                    "Hello",
+                    "java/lang/Object id: 21474836489" // bigger than 32-bit!
+                ),
+                "Error: expected integer");
+        }
+
+        // Good input:
+        dumpShouldPass(
+            "TESTCASE A6: extraneous spaces, tab characters and trailing new line characters",
+            appJar, classlist(
+                "Hello   ",                   // trailing spaces
+                "java/lang/Object\tid:\t1",   // \t instead of ' '
+                "CustomLoadee id: 2 super: 1 source: " + customJarPath,
+                "CustomInterface2_ia id: 3 super: 1 source: " + customJarPath + " ",
+                "CustomInterface2_ib id: 4 super: 1 source: " + customJarPath + "\t\t\r" ,
+                "CustomLoadee2 id: 5 super: 1 interfaces: 3 4 source: " + customJarPath      // preceding spaces
+            ));
+
+        int _max_allowed_line = 4096; // Must match ClassListParser::_max_allowed_line in C code.
+        int _line_buf_extra = 10;     // Must match ClassListParser::_line_buf_extra in C code.
+        StringBuffer sbuf = new StringBuffer();
+        for (int i=0; i<_max_allowed_line+1; i++) {
+          sbuf.append("x");
+        }
+
+        dumpShouldFail(
+            "TESTCASE A7: bad input - line too long",
+            appJar, classlist(
+                sbuf.toString()
+            ),
+            "input line too long (must be no longer than " + _max_allowed_line + " chars");
+
+        for (int i=0; i<_line_buf_extra + 1000; i++) {
+          sbuf.append("X");
+        }
+
+        dumpShouldFail(
+            "TESTCASE A8: bad input - line too long: try to overflow C buffer",
+            appJar, classlist(
+                sbuf.toString()
+            ),
+            "input line too long (must be no longer than " + _max_allowed_line + " chars");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatB.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Tests the format checking of hotspot/src/closed/share/vm/classfile/classListParser.cpp.
+ *
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
+ * @run main ClassListFormatB
+ */
+
+public class ClassListFormatB extends ClassListFormatBase {
+    static {
+        // Uncomment the following line to run only one of the test cases
+        // ClassListFormatBase.RUN_ONLY_TEST = "TESTCASE B1";
+    }
+
+    public static void main(String[] args) throws Throwable {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String customJarPath = JarBuilder.build("ClassListFormatB", "CustomLoadee",
+                                            "CustomLoadee2", "CustomInterface2_ia", "CustomInterface2_ib");
+        //----------------------------------------------------------------------
+        // TESTGROUP B if source IS specified
+        //----------------------------------------------------------------------
+        dumpShouldFail(
+            "TESTCASE B1: if source: is specified, must specify super:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee id: 2 source: " + customJarPath
+            ),
+            "If source location is specified, super class must be also specified");
+
+        dumpShouldFail(
+            "TESTCASE B2: if source: is specified, must specify id:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee super: 1 source: " + customJarPath
+            ),
+            "If source location is specified, id must be also specified");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatBase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+/**
+ * Base class for ClassListFormat[A,B,C...].java
+ */
+public class ClassListFormatBase {
+    protected static String RUN_ONLY_TEST = null;
+
+    static void dumpShouldFail(String caseHelp, String appJar, String[] appClasses,
+                               String... expected_errors) throws Throwable {
+        if (RUN_ONLY_TEST != null && !caseHelp.startsWith(RUN_ONLY_TEST)) {
+            System.out.println("Skipped via RUN_ONLY_TEST: " + caseHelp);
+            return;
+        }
+        System.out.println("------------------------------");
+        System.out.println(caseHelp);
+        System.out.println("------------------------------");
+
+        try {
+            OutputAnalyzer output = TestCommon.dump(appJar, appClasses);
+            output.shouldHaveExitValue(1);
+            for (String s : expected_errors) {
+                output.shouldContain(s);
+            }
+        } catch (Throwable t) {
+            System.out.println("FAILED CASE: " + caseHelp);
+            throw t;
+        }
+    }
+
+    static void dumpShouldPass(String caseHelp, String appJar, String[] appClasses,
+                               String... expected_msgs) throws Throwable {
+        if (RUN_ONLY_TEST != null && !caseHelp.startsWith(RUN_ONLY_TEST)) {
+            System.out.println("Skipped via RUN_ONLY_TEST: " + caseHelp);
+            return;
+        }
+        System.out.println("------------------------------");
+        System.out.println(caseHelp);
+        System.out.println("------------------------------");
+
+        try {
+            OutputAnalyzer output = TestCommon.dump(appJar, appClasses);
+            output.shouldHaveExitValue(0);
+            output.shouldContain("Dumping");
+            for (String s : expected_msgs) {
+                output.shouldContain(s);
+            }
+        } catch (Throwable t) {
+            System.out.println("FAILED CASE: " + caseHelp);
+            throw t;
+        }
+    }
+
+    static String[] classlist(String... args) {
+        return TestCommon.list(args);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatC.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Tests the format checking of hotspot/src/closed/share/vm/classfile/classListParser.cpp.
+ *
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
+ * @run main ClassListFormatC
+ */
+
+public class ClassListFormatC extends ClassListFormatBase {
+    static {
+        // Uncomment the following line to run only one of the test cases
+        // ClassListFormatBase.RUN_ONLY_TEST = "TESTCASE C1";
+    }
+
+    public static void main(String[] args) throws Throwable {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String customJarPath = JarBuilder.build("ClassListFormatC", "CustomLoadee",
+                                                "CustomLoadee2", "CustomInterface2_ia",
+                                                "CustomInterface2_ib");
+
+        //----------------------------------------------------------------------
+        // TESTGROUP C: if source IS NOT specified
+        //----------------------------------------------------------------------
+        dumpShouldFail(
+            "TESTCASE C1: if source: is NOT specified, must NOT specify super:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee super: 1"
+            ),
+            "If source location is not specified, super class must not be specified");
+
+        dumpShouldFail(
+            "TESTCASE C2: if source: is NOT specified, must NOT specify interface:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee interfaces: 1"
+            ),
+            "If source location is not specified, interface(s) must not be specified");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatD.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Tests the format checking of hotspot/src/closed/share/vm/classfile/classListParser.cpp.
+ *
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
+ * @run main ClassListFormatD
+ */
+
+public class ClassListFormatD extends ClassListFormatBase {
+    static {
+        // Uncomment the following line to run only one of the test cases
+        // ClassListFormatBase.RUN_ONLY_TEST = "TESTCASE D1";
+    }
+
+    public static void main(String[] args) throws Throwable {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String customJarPath = JarBuilder.build("ClassListFormatD", "CustomLoadee",
+                                                "CustomLoadee2", "CustomInterface2_ia",
+                                                "CustomInterface2_ib");
+
+        //----------------------------------------------------------------------
+        // TESTGROUP D: bad use of IDs
+        //----------------------------------------------------------------------
+        dumpShouldFail(
+            "TESTCASE D1: duplicated id:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee id: 1 super: 1 source: " + customJarPath
+            ),
+            "Duplicated ID 1 for class CustomLoadee");
+
+        dumpShouldFail(
+            "TESTCASE D2: bad ID for super:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee id: 2 super: 2 source: " + customJarPath
+            ),
+            "Super class id 2 is not yet loaded");
+
+        dumpShouldFail(
+            "TESTCASE D3: bad ID in interfaces:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee id: 2 super: 1 interfaces: 2 source: " + customJarPath
+            ),
+            "Interface id 2 is not yet loaded");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ClassListFormatE.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Tests the format checking of hotspot/src/closed/share/vm/classfile/classListParser.cpp.
+ *
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
+ * @run main ClassListFormatE
+ */
+
+public class ClassListFormatE extends ClassListFormatBase {
+    static {
+        // Uncomment the following line to run only one of the test cases
+        // ClassListFormatBase.RUN_ONLY_TEST = "TESTCASE E1";
+    }
+
+    public static void main(String[] args) throws Throwable {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String customJarPath = JarBuilder.build("ClassListFormatE", "CustomLoadee",
+                                                "CustomLoadee2", "CustomInterface2_ia",
+                                                "CustomInterface2_ib");
+
+        //----------------------------------------------------------------------
+        // TESTGROUP E: super class and interfaces
+        //----------------------------------------------------------------------
+        dumpShouldFail(
+            "TESTCASE E1: missing interfaces: keyword",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomLoadee2 id: 1 super: 1 source: " + customJarPath
+            ),
+            "Class CustomLoadee2 implements the interface CustomInterface2_ia, but no interface has been specified in the input line");
+
+        dumpShouldFail(
+            "TESTCASE E2: missing one interface",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomInterface2_ia id: 2 super: 1 source: " + customJarPath,
+                "CustomInterface2_ib id: 3 super: 1 source: " + customJarPath,
+                "CustomLoadee2 id: 4 super: 1 interfaces: 2 source: " + customJarPath
+            ),
+            "The interface CustomInterface2_ib implemented by class CustomLoadee2 does not match any of the specified interface IDs");
+
+        dumpShouldFail(
+            "TESTCASE E3: specifying an interface that's not implemented by the class",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomInterface2_ia id: 2 super: 1 source: " + customJarPath,
+                "CustomLoadee id: 2 super: 1 interfaces: 2 source: " + customJarPath
+            ),
+            "The number of interfaces (1) specified in class list does not match the class file (0)");
+
+        dumpShouldFail(
+            "TESTCASE E4: repeating an ID in the interfaces: keyword",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomInterface2_ia id: 2 super: 1 source: " + customJarPath,
+                "CustomInterface2_ib id: 3 super: 1 source: " + customJarPath,
+                "CustomLoadee2 id: 4 super: 1 interfaces: 2 2 3 source: " + customJarPath
+            ),
+            "The number of interfaces (3) specified in class list does not match the class file (2)");
+
+        dumpShouldFail(
+            "TESTCASE E5: wrong super class",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                "CustomInterface2_ia id: 2 super: 1 source: " + customJarPath,
+                "CustomInterface2_ib id: 3 super: 1 source: " + customJarPath,
+                "CustomLoadee id: 4 super: 1 source: " + customJarPath,
+                "CustomLoadee2 id: 5 super: 4 interfaces: 2 3 source: " + customJarPath
+            ),
+            "The specified super class CustomLoadee (id 4) does not match actual super class java.lang.Object");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/CustomLoaderApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+// This is a utlitity test class for loading classes-under-test
+// by means of custom class loader.
+// See AppCDS/jvmti/transformRelatedClasses/TransformRelatedClasses.java
+// for an example.
+// Use this test app in conjunction with other tests
+// to load and exercise classes using custom class loader(s).
+// This class is intended to be called by the "main test driver"
+// inside a child process, normally with sharing enabled.
+//
+// Arguments: customJarPath, loaderType, testClass
+//     customJarPath - a path to jar file containing classes for
+//         loading via this custom class loader, including the
+//         testClass
+//     loaderType - Currently only "unregistered"
+//         (Fingerprint verification method) is allowed
+//     testClass - the class to be loader; the test method with
+//         signature 'public static void test()' will be called
+//         on this class, so class must contain such method
+
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.logging.Logger;
+
+public class CustomLoaderApp {
+    public static void ping() {};
+
+    private static void log(String msg) {
+        System.out.println("CustomLoaderApp: " + msg);
+    }
+
+    public static void main(String[] args) throws Exception {
+        String path = args[0];
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+
+        String loaderType = args[1];
+        log("loaderType = " + loaderType);
+
+        String testClass = args[2];
+        log("testClass = " + testClass);
+
+        switch(loaderType) {
+        case "unregistered":
+            loadAndUseWithUnregisteredLoader(urls, testClass);
+            break;
+        default:
+            throw new IllegalArgumentException("loader type is wrong: " + loaderType);
+        }
+    }
+
+
+    // Load the test classes using unregistered loader
+    // (i.e. loader that is not using AppCDS API)
+    private static void loadAndUseWithUnregisteredLoader(URL[] urls, String testClass)
+        throws Exception {
+        URLClassLoader urlClassLoader = new URLClassLoader(urls);
+        callTestMethod(loadAndCheck(urlClassLoader, testClass));
+    }
+
+    private static Class loadAndCheck(ClassLoader loader, String className)
+        throws ClassNotFoundException {
+        Class c = loader.loadClass(className);
+        log("class =" + c);
+        log("loader = " + c.getClassLoader());
+
+        // Check that c is defined by the correct loader
+        if (c.getClassLoader() != loader) {
+            String msg = String.format("c.getClassLoader() equals to <%s>, expected <%s>",
+                                       c.getClassLoader(), loader);
+            throw new RuntimeException(msg);
+        }
+        return c;
+    }
+
+    private static void callTestMethod(Class c) throws Exception {
+        Method[] methods = c.getDeclaredMethods();
+        for (Method m : methods) {
+            log("method = " + m.getName());
+            if (m.getName().equals("test"))
+                m.invoke(null);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/HelloCustom.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Hello World test for AppCDS custom loader support
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @compile test-classes/Hello.java test-classes/CustomLoadee.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller -jar hello.jar Hello
+ * @run main ClassFileInstaller -jar hello_custom.jar CustomLoadee
+ * @run main ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
+ * @run main HelloCustom
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+public class HelloCustom {
+    public static void main(String[] args) throws Exception {
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        String appJar = ClassFileInstaller.getJarPath("hello.jar");
+        String customJarPath = ClassFileInstaller.getJarPath("hello_custom.jar");
+
+        // Dump the archive
+        String classlist[] = new String[] {
+            "Hello",
+            "java/lang/Object id: 1",
+            "CustomLoadee id: 2 super: 1 source: " + customJarPath
+        };
+
+        OutputAnalyzer output;
+        TestCommon.testDump(appJar, classlist,
+                            // command-line arguments ...
+                            use_whitebox_jar);
+
+        output = TestCommon.exec(appJar,
+                                 // command-line arguments ...
+                                 use_whitebox_jar,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 "Hello", customJarPath);
+        TestCommon.checkExec(output);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/LoaderSegregationTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Check that during dumping, the classes for BOOT/EXT/APP loaders are segregated from the
+ *          custom loader classes.
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/LoaderSegregation.java
+ *          test-classes/CustomLoadee.java test-classes/CustomLoadee2.java
+ *          test-classes/CustomInterface2_ia.java test-classes/CustomInterface2_ib.java
+ *          test-classes/CustomLoadee3.java test-classes/CustomLoadee3Child.java
+ *          test-classes/OnlyBuiltin.java
+ *          test-classes/OnlyUnregistered.java
+ *          ../test-classes/Util.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main LoaderSegregationTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+/**
+ * See "Handling of the classes in the AppCDS archive" at the top of
+ * systemDicrionatyShared.hpp.
+ *
+ * This test ensure that the 2 types of archived classes (BUILTIN and UNREGISTERED)
+ * are segregated at both dump-time and run time:
+ *
+ * [A] An archived BUILTIN class cannot be a subclass of a non-BUILTIN class.
+ * [B] An archived BUILTIN class cannot implement a non-BUILTIN interface.
+ * [C] BUILTIN and UNREGISTERED classes can be loaded only by their corresponding
+ *     type of loaders.
+ *
+ */
+public class LoaderSegregationTest {
+    public static void main(String[] args) throws Exception {
+        String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        String appJar = JarBuilder.build("LoaderSegregation_app", "LoaderSegregation",
+                                         "CustomLoadee", "CustomLoadee2", "CustomLoadee3Child", "CustomInterface2_ia",
+                                         "OnlyBuiltin", "Util");
+
+        String app2Jar = JarBuilder.build("LoaderSegregation_app2", "CustomLoadee3", "CustomInterface2_ib");
+
+        String customJarPath = JarBuilder.build("LoaderSegregation_custom", "CustomLoadee",
+                                                "CustomLoadee2", "CustomInterface2_ia", "CustomInterface2_ib",
+                                                "CustomLoadee3", "CustomLoadee3Child",
+                                                "OnlyBuiltin", "OnlyUnregistered");
+
+        // Dump the archive
+        String classlist[] = new String[] {
+            "LoaderSegregation",
+            "java/lang/Object id: 1",
+
+            // These are the UNREGISTERED classes: they have "source:"
+            // but they don't have "loader:".
+            "CustomLoadee id: 2 super: 1 source: " + customJarPath,
+
+            "CustomInterface2_ia id: 3 super: 1 source: " + customJarPath,
+            "CustomInterface2_ib id: 4 super: 1 source: " + customJarPath,
+            "CustomLoadee2 id: 5 super: 1 interfaces: 3 4 source: " + customJarPath,
+
+            "CustomLoadee3 id: 6 super: 1 source: " + customJarPath,
+            "CustomLoadee3Child id: 7 super: 6 source: " + customJarPath,
+
+            // At dump time, the following BUILTIN classes are loaded after the UNREGISTERED
+            // classes from above. However, at dump time, they cannot use the UNREGISTERED classes are their
+            // super or interface.
+            "CustomLoadee",          // can be loaded at dump time
+            "CustomLoadee2",         // cannot be loaded at dump time (interface missing)
+            "CustomLoadee3Child",    // cannot be loaded at dump time (super missing)
+
+            // Check that BUILTIN and UNREGISTERED classes can be loaded only by their
+            // corresponding type of loaders.
+            "OnlyBuiltin",
+            "OnlyUnregistered id: 9 super: 1 source: " + customJarPath,
+        };
+
+        OutputAnalyzer output;
+        TestCommon.testDump(appJar, classlist,
+                            // command-line arguments ...
+                            use_whitebox_jar);
+
+        output = TestCommon.exec(TestCommon.concatPaths(appJar, app2Jar),
+                                 // command-line arguments ...
+                                 "--add-opens=java.base/java.lang=ALL-UNNAMED",
+                                 "--add-opens=java.base/java.security=ALL-UNNAMED",
+                                 use_whitebox_jar,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 "LoaderSegregation", customJarPath);
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ParallelTestBase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+/*
+ * This is a base class for the following test cases:
+ *   ParallelTestMultiFP.java
+ *   ParallelTestSingleFP.java
+ */
+public class ParallelTestBase {
+    public static final int MAX_CLASSES = 40; // must match ../test-classes/ParallelLoad.java
+    public static int NUM_THREADS = 4;        // must match ../test-classes/ParallelLoad.java
+
+    public static final int SINGLE_CUSTOM_LOADER = 1;
+    public static final int MULTI_CUSTOM_LOADER  = 2;
+
+    public static final int FINGERPRINT_MODE = 1;
+
+    public static void run(String[] args, int loaderType, int mode) throws Exception {
+        String[] cust_classes = new String[MAX_CLASSES];
+        String[] cust_list;
+
+        if (mode == FINGERPRINT_MODE) {
+            cust_list = new String[MAX_CLASSES];
+        } else {
+            cust_list = new String[MAX_CLASSES * NUM_THREADS];
+        }
+
+        for (int i = 0; i<MAX_CLASSES; i++) {
+            cust_classes[i] = "ParallelClass" + i;
+        }
+        String customJarPath = JarBuilder.build("ParallelTestBase", cust_classes);
+
+        for (int i = 0, n=0; i<MAX_CLASSES; i++) {
+            int super_id = 1;
+            if (mode == FINGERPRINT_MODE) {
+                // fingerprint mode -- no need to use the "loader:" option.
+                int id = i + 2;
+                cust_list[i] = cust_classes[i] + " id: " + id + " super: " + super_id + " source: " + customJarPath;
+            } else {
+                throw new RuntimeException("Only FINGERPRINT_MODE is supported");
+            }
+        }
+
+        String app_list[];
+        String mainClass;
+        String appJar;
+
+        if (mode == FINGERPRINT_MODE) {
+            appJar = JarBuilder.build("parallel_fp",
+                                      "ParallelLoad",
+                                      "ParallelLoadThread",
+                                      "ParallelLoadWatchdog");
+            app_list = new String[] {
+                "java/lang/Object id: 1",
+                "ParallelLoad",
+                "ParallelLoadThread",
+                "ParallelLoadWatchdog"
+            };
+            mainClass = "ParallelLoad";
+        } else {
+            throw new RuntimeException("Currently only FINGERPRINT_MODE is supported");
+        }
+
+        OutputAnalyzer output;
+        TestCommon.testDump(appJar, TestCommon.concat(app_list, cust_list));
+
+        String loaderTypeArg = (loaderType == SINGLE_CUSTOM_LOADER) ? "SINGLE_CUSTOM_LOADER" : "MULTI_CUSTOM_LOADER";
+        String modeArg = "FINGERPRINT_MODE";
+
+        output = TestCommon.exec(appJar,
+                                 // command-line arguments ...
+                                 "--add-opens=java.base/java.security=ALL-UNNAMED",
+                                 mainClass, loaderTypeArg, modeArg, customJarPath);
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ParallelTestMultiFP.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load classes from CDS archive into multiple custom loader using parallel threads
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/ParallelLoad.java ../test-classes/ParallelClasses.java
+ * @run main ParallelTestMultiFP
+ */
+
+public class ParallelTestMultiFP extends ParallelTestBase {
+    public static void main(String[] args) throws Exception {
+        ParallelTestBase.run(args, MULTI_CUSTOM_LOADER, FINGERPRINT_MODE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ParallelTestSingleFP.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load classes from CDS archive into a single custom loader using parallel threads (finger print)
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/ParallelLoad.java ../test-classes/ParallelClasses.java
+ * @run main ParallelTestSingleFP
+ */
+
+public class ParallelTestSingleFP extends ParallelTestBase {
+    public static void main(String[] args) throws Exception {
+        ParallelTestBase.run(args, SINGLE_CUSTOM_LOADER, FINGERPRINT_MODE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ProhibitedPackageNamesTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Make sure prohibited packages cannot be stored into archive for custom loaders.
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ClassListFormatBase.java test-classes/Hello.java test-classes/InProhibitedPkg.java
+ * @run main ProhibitedPackageNamesTest
+ */
+
+public class ProhibitedPackageNamesTest extends ClassListFormatBase {
+    static {
+        // Uncomment the following line to run only one of the test cases
+        // ClassListFormatBase.RUN_ONLY_TEST = "TESTCASE PPN1";
+    }
+
+    public static void main(String[] args) throws Throwable {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String customJarPath = JarBuilder.build("ProhibitedPackageNames_custom", "java/InProhibitedPkg");
+
+        dumpShouldPass(
+            "TESTCASE PPN1: prohibited package name without loader:",
+            appJar, classlist(
+                "Hello",
+                "java/lang/Object id: 1",
+                // Without "loader:" keyword.
+                "java/InProhibitedPkg id: 2 super: 1 source: " + customJarPath
+            ),
+            "Prohibited package for non-bootstrap classes: java/InProhibitedPkg.class");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/ProtectionDomain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary AppCDS handling of protection domain in custom loaders.
+ *
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ *
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/ProtDomain.java
+ * @run main ProtectionDomain
+ */
+
+public class ProtectionDomain {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.build("ProtectionDomain-app", "ProtDomain");
+
+        String customJar = JarBuilder.build("ProtectionDomain-custom",
+            "ProtDomainClassForArchive", "ProtDomainNotForArchive");
+        String[] classlist = new String[] {
+            "java/lang/Object id: 1",
+            "ProtDomain id: 2 super: 1 source: " + appJar,
+            "ProtDomainClassForArchive id: 3 super: 1 source: " + customJar
+        };
+
+        TestCommon.testDump(appJar, classlist);
+
+        // First class is loaded from CDS, second class is loaded from JAR
+        TestCommon.checkExec(TestCommon.exec(appJar, "-verbose:class", "ProtDomain", customJar),
+            "[class,load] ProtDomainClassForArchive source: shared objects file",
+            "[class,load] ProtDomainNotForArchive source: file");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/SameNameInTwoLoadersTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Testing the loading of a class with the same name in two different class loaders.
+ *
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ *
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/CustomLoadee.java
+ *     test-classes/CustomLoadee3.java
+ *     test-classes/SameNameUnrelatedLoaders.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main SameNameInTwoLoadersTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+
+public class SameNameInTwoLoadersTest {
+    private static String appJar;
+    private static String customJar;
+    private static String useWbParam;
+
+    public static void main(String[] args) throws Exception {
+        appJar = JarBuilder.build("SameNameInTwoLoadersTest",
+            "SameNameUnrelatedLoaders");
+
+        customJar = JarBuilder.build("SameNameInTwoLoadersTest_custom", "CustomLoadee", "CustomLoadee3");
+
+        useWbParam = "-Xbootclasspath/a:" +
+            JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");;
+
+        // ====== unrelated loaders
+        executeTestCase(getClassList_FP(),
+            "SameNameUnrelatedLoaders", "FpBoth");
+    }
+
+    private static void executeTestCase(String[] classlist,
+        String testClass, String testCaseId) throws Exception {
+        classlist[0] = testClass;
+
+        TestCommon.testDump(appJar, classlist, useWbParam);
+
+        OutputAnalyzer output = TestCommon.exec(appJar,
+                                 // command-line arguments ...
+                                 "--add-opens=java.base/java.security=ALL-UNNAMED",
+                                 useWbParam,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 testClass,
+                                 customJar, testCaseId);
+        TestCommon.checkExec(output);
+    }
+
+    // Single entry, no loader specified (FP method)
+    private static String[] getClassList_FP() {
+        return new String[] {
+            "SameNameUnrelatedLoaders",
+            "java/lang/Object id: 1",
+            "CustomLoadee id: 10 super: 1 source: " + customJar,
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/UnintendedLoadersTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Make sure classes intended for custom loaders cannot be loaded by BOOT/EXT/APP loaders
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/UnintendedLoaders.java test-classes/CustomLoadee.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main UnintendedLoadersTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+public class UnintendedLoadersTest {
+    public static void main(String[] args) throws Exception {
+        String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        String appJar = JarBuilder.build("UnintendedLoaders_app", "UnintendedLoaders");
+        String customJarPath = JarBuilder.build("UnintendedLoaders_custom", "CustomLoadee");
+
+        // Dump the archive
+        String classlist[] = new String[] {
+            "UnintendedLoadersTest",
+            "java/lang/Object id: 1",
+
+            // Without "loader:" keyword.
+            "CustomLoadee id: 2 super: 1 source: " + customJarPath,
+        };
+
+        OutputAnalyzer output;
+        TestCommon.testDump(appJar, classlist,
+                            // command-line arguments ...
+                            use_whitebox_jar);
+
+        output = TestCommon.exec(appJar,
+                                 // command-line arguments ...
+                                 use_whitebox_jar,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 "UnintendedLoaders");
+        TestCommon.checkExec(output);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/UnloadUnregisteredLoaderTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test the behavior when shared classes loaded by custom loaders are
+ *          unloaded.
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds.custom.loaders
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox ClassUnloadCommon
+ * @compile test-classes/UnloadUnregisteredLoader.java test-classes/CustomLoadee.java
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller ClassUnloadCommon
+ * @run main ClassFileInstaller ClassUnloadCommon$1
+ * @run main ClassFileInstaller ClassUnloadCommon$TestFailure
+ * @run main UnloadUnregisteredLoaderTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+public class UnloadUnregisteredLoaderTest {
+    public static void main(String[] args) throws Exception {
+        String appJar1 = JarBuilder.build("UnloadUnregisteredLoader_app1", "UnloadUnregisteredLoader");
+        String appJar2 = JarBuilder.build(true, "UnloadUnregisteredLoader_app2",
+                                          "ClassUnloadCommon", "ClassUnloadCommon$1", "ClassUnloadCommon$TestFailure");
+        String customJarPath = JarBuilder.build("UnloadUnregisteredLoader_custom", "CustomLoadee");
+        String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        String classpath = TestCommon.concatPaths(appJar1, appJar2);
+        String classlist[] = new String[] {
+            "UnloadUnregisteredLoader",
+            "ClassUnloadCommon",
+            "ClassUnloadCommon$1",
+            "ClassUnloadCommon$TestFailure",
+            "java/lang/Object id: 1",
+            "CustomLoadee id: 2 super: 1 source: " + customJarPath,
+        };
+
+        OutputAnalyzer output;
+        TestCommon.testDump(classpath, classlist,
+                            // command-line arguments ...
+                            use_whitebox_jar);
+
+        output = TestCommon.exec(classpath,
+                                 // command-line arguments ...
+                                 use_whitebox_jar,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 "UnloadUnregisteredLoader",
+                                 customJarPath);
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/UnsupportedPlatforms.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Ensure that support for AppCDS custom class loaders are not enabled on unsupported platforms.
+ * (NOTE: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/SimpleHello.java
+ * @run main UnsupportedPlatforms
+ */
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class UnsupportedPlatforms {
+    public static String PLATFORM_NOT_SUPPORTED_WARNING =
+        "AppCDS custom class loaders not supported on this platform";
+
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.build("UnsupportedPlatforms", "SimpleHello");
+
+        // Dump the archive
+        String classlist[] = new String[] {
+            "SimpleHello",
+            "java/lang/Object id: 1",
+            "CustomLoadee id: 2 super: 1 source: " + appJar
+        };
+
+        OutputAnalyzer out = TestCommon.dump(appJar, classlist);
+
+        if (Platform.areCustomLoadersSupportedForCDS()) {
+            out.shouldNotContain(PLATFORM_NOT_SUPPORTED_WARNING);
+            out.shouldHaveExitValue(0);
+        } else {
+            out.shouldContain(PLATFORM_NOT_SUPPORTED_WARNING);
+            out.shouldHaveExitValue(1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/CustomInterface2_ia.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+interface CustomInterface2_ia {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/CustomInterface2_ib.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+interface CustomInterface2_ib {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/CustomLoadee.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class CustomLoadee {
+    public String toString() {
+        return "this is CustomLoadee";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/CustomLoadee2.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class CustomLoadee2 implements CustomInterface2_ia, CustomInterface2_ib {
+    public String toString() {
+        return "this is CustomLoadee";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/CustomLoadee3.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class CustomLoadee3 {
+    public String toString() {
+        return "this is CustomLoadee3";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/CustomLoadee3Child.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class CustomLoadee3Child extends CustomLoadee3 {
+    public String toString() {
+        return "this is CustomLoadee3Child";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/Hello.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.io.*;
+import java.net.*;
+import sun.hotspot.WhiteBox;
+
+public class Hello {
+    public static void main(String args[]) throws Exception {
+        String path = args[0];
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+        System.out.println(path);
+        System.out.println(url);
+
+        URLClassLoader urlClassLoader = new URLClassLoader(urls);
+        Class c = urlClassLoader.loadClass("CustomLoadee");
+        System.out.println(c);
+        System.out.println(c.getClassLoader());
+
+        // [1] Check that CustomLoadee is defined by the correct loader
+        if (c.getClassLoader() != urlClassLoader) {
+            throw new RuntimeException("c.getClassLoader() == " + c.getClassLoader() +
+                                       ", expected == " + urlClassLoader);
+        }
+
+        // [2] Check that CustomLoadee is loaded from shared archive.
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (wb.isSharedClass(Hello.class)) {
+            if (!wb.isSharedClass(c)) {
+                throw new RuntimeException("wb.isSharedClass(c) should be true");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/InProhibitedPkg.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, 2017, 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 java;
+
+public class InProhibitedPkg {
+    static {
+        if (true) {
+            throw new RuntimeException("This class shouldn't be loaded by any loader other than BOOT");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/LoaderAPI.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
+Specification-Title: My Specification Title
+Specification-Version: 1.0
+Specification-Vendor: My Specification Vendor
+Implementation-Title: My Implementation Title
+Implementation-Version: 1.0
+Implementation-Vendor: My Implementation Vendor
+
+Name: pkg1/
+Implementation-Version: 2.0
+Sealed: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/LoaderSegregation.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.io.*;
+import java.net.*;
+import sun.hotspot.WhiteBox;
+
+public class LoaderSegregation {
+    // Use these definitions instead of literal strings, to avoid typos.
+    static final String ONLY_BUILTIN      = "OnlyBuiltin";
+    static final String ONLY_UNREGISTERED = "OnlyUnregistered";
+
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        // [A] An archived BUILTIN class cannot be a subclass of a non-BUILTIN class.
+        // [B] An archived BUILTIN class cannot implement a non-BUILTIN interface.
+        if (wb.isSharedClass(LoaderSegregation.class)) {
+            // [1] check that CustomLoadee is loadable from archive
+            if (!wb.isSharedClass(CustomLoadee.class)) {
+                throw new RuntimeException("wb.isSharedClass(CustomLoadee.class) should be true");
+            }
+
+            // [2] CustomInterface2_ia should be archived, even though it was not specified in the classlist.
+            //     It was successfully dumped as a side effect of attempting to load CustomLoadee2
+            //     during dump time. Note that CustomLoadee2 failed to dump because one of its interfaces,
+            //     CustomInterface2_ib, was not loadable from the BOOT/EXT/APP classpath. during dump time.
+            if (!wb.isSharedClass(CustomInterface2_ia.class)) {
+                throw new RuntimeException("wb.isSharedClass(CustomInterface2_ia.class) should be true");
+            }
+
+            // [3] Check that the BUILTIN versions of CustomLoadee2 and CustomLoadee3Child are loadable
+            //     at run time (since we have append LoaderSegregation_app2.jar the classpath),
+            //     but these classes must be loaded from the JAR file.
+            if (wb.isSharedClass(CustomLoadee2.class)) {
+                throw new RuntimeException("wb.isSharedClass(CustomLoadee2.class) should be false");
+            }
+            if (wb.isSharedClass(CustomLoadee3.class)) {
+                throw new RuntimeException("wb.isSharedClass(CustomLoadee3.class) should be false");
+            }
+            if (wb.isSharedClass(CustomLoadee3Child.class)) {
+                throw new RuntimeException("wb.isSharedClass(CustomLoadee3Child.class) should be false");
+            }
+        }
+
+        // [C] BUILTIN and UNREGISTERED classes can be loaded only by their corresponding
+        //     type of loaders.
+
+        String path = args[0];
+        File jarFile = new File(path);
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+        ClassLoader appLoader = LoaderSegregation.class.getClassLoader();
+
+        { // BUILTIN LOADER
+            try {
+                appLoader.loadClass(ONLY_UNREGISTERED);
+                throw new RuntimeException("BUILTIN loader cannot load archived UNREGISTERED class");
+            } catch (ClassNotFoundException expected) {}
+        }
+
+        { // UNREGISTERED LOADER
+            URLClassLoader urlClassLoader = new URLClassLoader(urls);
+            Class c2 = Util.defineClassFromJAR(urlClassLoader, jarFile, ONLY_BUILTIN);
+
+            if (c2.getClassLoader() != urlClassLoader) {
+                throw new RuntimeException("Error in test");
+            }
+
+            if (wb.isSharedClass(LoaderSegregation.class)) {
+                if (wb.isSharedClass(c2)) {
+                    throw new RuntimeException("wb.isSharedClass(c2) should be false - " +
+                                               "unregistered loader cannot load an archived BUILTIN class");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/OnlyBuiltin.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+// See ../LoaderSegregationTest.java for details.
+//
+// This class is archived only as a BUILTIN class.
+public class OnlyBuiltin {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/OnlyUnregistered.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+// See ../LoaderSegregationTest.java for details.
+//
+// This class is archived only as a UNREGISTERED class.
+public class OnlyUnregistered {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/ProtDomain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.security.ProtectionDomain;
+import java.net.URLClassLoader;
+import java.net.URL;
+import java.io.File;
+
+// Intended to be called from test ProtectionDomain.java
+//
+// ProtDomainClassForArchive is     stored in CDS archive.
+// ProtDomainNotForArchive   is NOT stored in CDS archive.
+//
+// However, they should have the same ProtectionDomain instance.
+public class ProtDomain {
+    public static void main(String args[]) throws Exception {
+        String customLdrPath = args[0];
+
+        URL[] urls = new URL[] {new File(customLdrPath).toURI().toURL()};
+        URLClassLoader ldr = new URLClassLoader(urls);
+        ProtectionDomain domain1 = ldr.loadClass("ProtDomainClassForArchive").getProtectionDomain();
+        ProtectionDomain domain2 = ldr.loadClass("ProtDomainNotForArchive").getProtectionDomain();
+
+        System.out.println("domain1 = " + domain1);
+        System.out.println("domain2  = " + domain2);
+
+        if (domain1 != domain2)
+            throw new RuntimeException("Protection Domains do not match!");
+    }
+}
+
+class ProtDomainClassForArchive {}
+
+class ProtDomainNotForArchive {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/SameNameUnrelatedLoaders.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import sun.hotspot.WhiteBox;
+
+public class SameNameUnrelatedLoaders {
+    public static void main(String args[]) throws Exception {
+        String path = args[0];
+        String testCase = args[1];
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+
+        ClassLoader appLoader = SameNameUnrelatedLoaders.class.getClassLoader();
+        URLClassLoader ldr01 = null;
+        URLClassLoader ldr02 = null;
+
+        switch (testCase) {
+            case "FpBoth":
+                ldr01 = new URLClassLoader(urls);
+                ldr02 = new URLClassLoader(urls);
+            break;
+
+            default:
+                throw new IllegalArgumentException("Invalid testCase ID");
+        }
+
+
+        Class class01 = ldr01.loadClass("CustomLoadee");
+        Class class02  = ldr02.loadClass("CustomLoadee");
+
+        System.out.println("class01 = " + class01);
+        System.out.println("class02 = " + class02);
+
+        if (class01.getClassLoader() != ldr01) {
+            throw new RuntimeException("class01 loaded by wrong loader");
+        }
+        if (class02.getClassLoader() != ldr02) {
+            throw new RuntimeException("class02 loaded by wrong loader");
+        }
+
+        if (true) {
+            if (class01.isAssignableFrom(class02)) {
+                throw new RuntimeException("assignable condition failed");
+            }
+
+            Object obj01 = class01.newInstance();
+            Object obj02 = class02.newInstance();
+
+            if (class01.isInstance(obj02)) {
+                throw new RuntimeException("instance relationship condition 01 failed");
+            }
+            if (class02.isInstance(obj01)) {
+                throw new RuntimeException("instance relationship condition 02 failed");
+            }
+        }
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (wb.isSharedClass(SameNameUnrelatedLoaders.class)) {
+            boolean class1Shared = wb.isSharedClass(class01);
+            boolean class2Shared = wb.isSharedClass(class02);
+
+            if (testCase.equals("FpBoth")) {
+                if (!class1Shared) {
+                    throw new RuntimeException("first class is not shared");
+                }
+
+                if (class2Shared) {
+                    throw new RuntimeException("second class is shared, " +
+                    "and it should not be - first come first serve violation");
+                }
+            } else {
+                if (! (class1Shared && class2Shared) )
+                    throw new RuntimeException("both classes expected to be shared, but are not");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/SimpleHello.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class SimpleHello {
+    public static void main(String[] args) {
+        System.out.println("Simple Hello");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/UnintendedLoaders.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class UnintendedLoaders {
+    public static void main(String[] args) throws Exception {
+        ClassLoader loaders[] = new ClassLoader[2];
+        loaders[0] = UnintendedLoaders.class.getClassLoader(); // app loader
+        loaders[1] = loaders[0].getParent();                   // platform loader
+
+        String[] names = {
+            "CustomLoadee",
+        };
+
+
+        for (int i=0; i<3; i++) {
+            for (String s : names) {
+                try {
+                    if (i <= 1) {
+                        System.out.println(loaders[i].loadClass(s));
+                    } else {
+                        System.out.println(Class.forName(s));
+                    }
+                } catch (ClassNotFoundException e) {
+                    System.out.println("Expected exception:" + e);
+                    continue;
+                }
+                throw new RuntimeException("The class \"" + s + "\" should not be resolved by the application or platform class loader");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/customLoader/test-classes/UnloadUnregisteredLoader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import sun.hotspot.WhiteBox;
+
+public class UnloadUnregisteredLoader {
+    public static void main(String args[]) throws Exception {
+        String path = args[0];
+        URL url = new File(path).toURI().toURL();
+        URL[] urls = new URL[] {url};
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        String className = "CustomLoadee";
+
+        for (int i=0; i<5; i++) {
+            doit(urls, className, (i == 0));
+
+            ClassUnloadCommon.triggerUnloading();
+            ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded");
+        }
+    }
+
+  public static void doit(URL urls[], String className, boolean isFirstTime) throws Exception {
+        ClassLoader appLoader = UnloadUnregisteredLoader.class.getClassLoader();
+        URLClassLoader custLoader = new URLClassLoader(urls, appLoader);
+
+        Class klass = custLoader.loadClass(className);
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (wb.isSharedClass(UnloadUnregisteredLoader.class)) {
+            if (isFirstTime) {
+                // First time: we should be able to load the class from the CDS archive
+                if (!wb.isSharedClass(klass)) {
+                    throw new RuntimeException("wb.isSharedClass(klass) should be true for first time");
+                }
+            } else {
+                // Second time:  the class in the CDS archive is not available, because it has not been cleaned
+                // up (see bug 8140287), so we must load the class dynamically.
+                //
+                // FIXME: after 8140287 is fixed, class should be shard regardless of isFirstTime.
+                if (wb.isSharedClass(klass)) {
+                    throw new RuntimeException("wb.isSharedClass(klass) should be false for second time");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/ArrayTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary test the ability to archive array classes and load them from the archive
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile ArrayTestHelper.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main ArrayTest
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ArrayTest {
+
+    static String arrayClasses[] = {
+        "ArrayTestHelper",
+        "[Ljava/lang/Comparable;",
+        "[I"
+    };
+
+    public static void main(String[] args) throws Exception {
+        JarBuilder.build("arrayTestHelper", "ArrayTestHelper");
+
+        String appJar = TestCommon.getTestJar("arrayTestHelper.jar");
+        JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
+        String bootClassPath = "-Xbootclasspath/a:" + whiteBoxJar;
+
+        // create an archive containing array classes
+        TestCommon.dump(appJar, TestCommon.list(arrayClasses), bootClassPath, "-verbose:class");
+
+        List<String> argsList = new ArrayList<String>();
+        argsList.add("-XX:+UnlockDiagnosticVMOptions");
+        argsList.add("-XX:+WhiteBoxAPI");
+        argsList.add("-cp");
+        argsList.add(appJar);
+        argsList.add(bootClassPath);
+        argsList.add("-verbose:class");
+        argsList.add("ArrayTestHelper");
+        // the following are input args to the ArrayTestHelper.
+        for (int i = 0; i < arrayClasses.length; i++) {
+            argsList.add(arrayClasses[i]);
+        }
+        String[] opts = new String[argsList.size()];
+        opts = argsList.toArray(opts);
+        OutputAnalyzer output = TestCommon.execCommon(opts);
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/ArrayTestHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class ArrayTestHelper {
+    public static void main(String[] args) throws Throwable {
+
+        // load the classes one by one and ensure each one is from
+        // the shared archive
+        for (int i = 0; i < args.length; i++) {
+
+            String cn = args[i].replace('/', '.');
+            Class cls = Class.forName(cn);
+
+            WhiteBox wb = WhiteBox.getWhiteBox();
+            if (wb.isSharedClass(cls)) {
+                System.out.println("As expected, " + args[i] + " is in shared space.");
+            } else {
+                throw new java.lang.RuntimeException(args[i] + " is not in shared space.");
+            }
+        }
+   }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/CheckAnonymousClass.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary ensure no anonymous class is being dumped into the CDS archive
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @run main CheckAnonymousClass
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class CheckAnonymousClass {
+
+  public static void main(String[] args) throws Exception {
+    JarBuilder.build("hello", "Hello");
+
+    String appJar = TestCommon.getTestJar("hello.jar");
+
+    TestCommon.dump(appJar, TestCommon.list("Hello", "org/omg/CORBA/ORB"),
+        "--add-modules", "java.corba", "-Xlog:class+load=info");
+
+    OutputAnalyzer output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions",
+        "-cp", appJar, "-Xlog:class+load=info", "--add-modules", "java.corba", "Hello");
+
+    String prefix = ".class.load. ";
+    // class name pattern like the following:
+    // jdk.internal.loader.BuiltinClassLoader$$Lambda$1/1816757085
+    // java.lang.invoke.LambdaForm$MH/1585787493
+    String class_pattern = ".*Lambda([a-z0-9$]+)/([0-9]+).*";
+    String suffix = ".*source: shared objects file.*";
+    String pattern = prefix + class_pattern + suffix;
+    // during run time, anonymous classes shouldn't be loaded from the archive
+    try {
+        output.shouldNotMatch(pattern);
+    } catch (Exception e) {
+        TestCommon.checkCommonExecExceptions(output, e);
+    }
+
+    // inspect the archive and make sure no anonymous class is in there
+    output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions",
+        "-cp", appJar, "-Xlog:class+load=info", "-XX:+PrintSharedArchiveAndExit",
+        "-XX:+PrintSharedDictionary", "--add-modules", "java.corba", "Hello");
+    try {
+        output.shouldNotMatch(class_pattern);
+    } catch (Exception e) {
+        TestCommon.checkCommonExecExceptions(output, e);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDump.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary When dumping the CDS archive, try to cause garbage collection while classes are being loaded.
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ * @build GCDuringDumpTransformer Hello
+ * @run main/othervm GCDuringDump
+ */
+
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class GCDuringDump {
+    public static String appClasses[] = {
+        "Hello",
+    };
+    public static String agentClasses[] = {
+        "GCDuringDumpTransformer",
+    };
+
+    public static void main(String[] args) throws Throwable {
+        String agentJar =
+            ClassFileInstaller.writeJar("GCDuringDumpTransformer.jar",
+                                        ClassFileInstaller.Manifest.fromSourceFile("GCDuringDumpTransformer.mf"),
+                                        agentClasses);
+
+        String appJar =
+            ClassFileInstaller.writeJar("GCDuringDumpApp.jar", appClasses);
+
+        String gcLog = "-Xlog:gc*=info,gc+region=trace,gc+alloc+region=debug";
+
+        for (int i=0; i<2; i++) {
+            // i = 0 -- run without agent = no extra GCs
+            // i = 1 -- run with agent = cause extra GCs
+
+            String extraArg = (i == 0) ? "-showversion" : "-javaagent:" + agentJar;
+
+            TestCommon.testDump(appJar, TestCommon.list("Hello"),
+                                extraArg, "-Xmx32m", gcLog);
+
+            OutputAnalyzer output = TestCommon.execCommon(
+                "-cp", appJar,
+                "-Xmx32m",
+                "-XX:+PrintSharedSpaces",
+                gcLog,
+                "Hello");
+            TestCommon.checkExec(output);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDumpTransformer.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+public class GCDuringDumpTransformer implements ClassFileTransformer {
+    static int n = 0;
+    public byte[] transform(ClassLoader loader, String name, Class<?> classBeingRedefined,
+                            ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException {
+        n++;
+
+        System.out.println("dump time loading: " + name + " in loader: " + loader);
+        System.out.println("making garbage: " + n);
+        try {
+            makeGarbage();
+        } catch (Throwable t) {
+            t.printStackTrace();
+            try {
+                Thread.sleep(200); // let GC to have a chance to run
+            } catch (Throwable t2) {}
+        }
+        System.out.println("making garbage: done");
+
+        return null;
+    }
+
+    private static Instrumentation savedInstrumentation;
+
+    public static void premain(String agentArguments, Instrumentation instrumentation) {
+        System.out.println("ClassFileTransformer.premain() is called");
+        instrumentation.addTransformer(new GCDuringDumpTransformer(), /*canRetransform=*/true);
+        savedInstrumentation = instrumentation;
+    }
+
+    public static Instrumentation getInstrumentation() {
+        return savedInstrumentation;
+    }
+
+    public static void agentmain(String args, Instrumentation inst) throws Exception {
+        premain(args, inst);
+    }
+
+    public static void makeGarbage() {
+        for (int x=0; x<10; x++) {
+            Object[] a = new Object[10000];
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDumpTransformer.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Premain-Class: GCDuringDumpTransformer
+Agent-Class: GCDuringDumpTransformer
+Can-Retransform-Classes: true
+Can-Redefine-Classes: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Similar to GCDuringDumping.java, this test adds the -XX:SharedArchiveConfigFile
+ *          option for testing the interaction with GC and shared strings.
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @requires vm.gc.G1
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ * @build sun.hotspot.WhiteBox GCDuringDumpTransformer GCSharedStringsDuringDumpWb
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm/timeout=480 GCSharedStringsDuringDump
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import sun.hotspot.WhiteBox;
+
+public class GCSharedStringsDuringDump {
+    public static String appClasses[] = {
+        "GCSharedStringsDuringDumpWb",
+    };
+    public static String agentClasses[] = {
+        "GCDuringDumpTransformer",
+    };
+
+    public static void main(String[] args) throws Throwable {
+        String agentJar =
+            ClassFileInstaller.writeJar("GCDuringDumpTransformer.jar",
+                                        ClassFileInstaller.Manifest.fromSourceFile("GCDuringDumpTransformer.mf"),
+                                        agentClasses);
+
+        String appJar =
+            ClassFileInstaller.writeJar("GCSharedStringsDuringDumpApp.jar", appClasses);
+
+        String gcLog = "-Xlog:gc*=info,gc+region=trace,gc+alloc+region=debug";
+
+        String sharedArchiveCfgFile =
+            System.getProperty("user.dir") + File.separator + "GCSharedStringDuringDump_gen.txt";
+        try (FileOutputStream fos = new FileOutputStream(sharedArchiveCfgFile)) {
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(fos));
+            out.println("VERSION: 1.0");
+            out.println("@SECTION: String");
+            out.println("31: shared_test_string_unique_14325");
+            for (int i=0; i<100000; i++) {
+                String s = "generated_string " + i;
+                out.println(s.length() + ": " + s);
+            }
+            out.close();
+        }
+
+        JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
+        String bootClassPath = "-Xbootclasspath/a:" + whiteBoxJar;
+
+        for (int i=0; i<2; i++) {
+            // i = 0 -- run without agent = no extra GCs
+            // i = 1 -- run with agent = cause extra GCs
+
+            String extraArg = (i == 0) ? "-showversion" : "-javaagent:" + agentJar;
+
+            OutputAnalyzer output = TestCommon.dump(
+                                appJar, TestCommon.list("GCSharedStringsDuringDumpWb"),
+                                bootClassPath, extraArg, "-Xmx32m", gcLog,
+                                "-XX:+UseCompressedOops", "-XX:+UseG1GC",
+                                "-XX:SharedReadOnlySize=30m",
+                                "-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
+
+            if (output.getStdout().contains("Too many string space regions") ||
+                output.getStderr().contains("Unable to write archive heap memory regions") ||
+                output.getStdout().contains("Try increasing NewSize") ||
+                !output.getStdout().contains("oa0 space:") ||
+                output.getExitValue() != 0) {
+                // Try again with larger heap and NewSize, this should increase the
+                // G1 heap region size to 2M
+                TestCommon.testDump(
+                    appJar, TestCommon.list("GCSharedStringsDuringDumpWb"),
+                    bootClassPath, extraArg, "-Xmx8g", "-XX:NewSize=8m", gcLog,
+                    "-XX:+UseCompressedOops", "-XX:+UseG1GC",
+                    "-XX:SharedReadOnlySize=30m",
+                    "-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
+            }
+
+            output = TestCommon.execCommon(
+                "-cp", appJar,
+                bootClassPath,
+                "-Xmx32m",
+                "-XX:+PrintSharedSpaces",
+                "-XX:+UseCompressedOops",
+                "-XX:+UseG1GC",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-XX:SharedReadOnlySize=30m",
+                gcLog,
+                "GCSharedStringsDuringDumpWb");
+            TestCommon.checkExec(output);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDumpWb.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class GCSharedStringsDuringDumpWb {
+    public static void main(String[] args) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        String s = "shared_test_string_unique_14325";
+        s = s.intern();
+        CheckString(wb, s);
+        for (int i=0; i<100000; i++) {
+            s = "generated_string " + i;
+            s = s.intern();
+            CheckString(wb, s);
+        }
+    }
+
+    public static void CheckString(WhiteBox wb, String s) {
+        if (!wb.areSharedStringsIgnored() && !wb.isShared(s)) {
+            throw new RuntimeException("String is not shared.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/CheckUnsupportedDumpingOptions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Abort dumping if any of the new jigsaw vm options is specified.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib ..
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @compile ../test-classes/Hello.java
+ * @run main CheckUnsupportedDumpingOptions
+ */
+
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class CheckUnsupportedDumpingOptions {
+    private static final String[] jigsawOptions = {
+        "-m",
+        "--limit-modules",
+        "--module-path",
+        "--upgrade-module-path",
+        "--patch-module"
+    };
+    private static final String[] optionValues = {
+        "mymod",
+        "mymod",
+        "mydir",
+        ".",
+        "java.naming=javax.naming.spi.NamingManger"
+    };
+    private static final int infoIdx = 1;
+
+    public static void main(String[] args) throws Exception {
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+            InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+            "mods/java.naming");
+
+        JarBuilder.build("hello", "Hello");
+        String appJar = TestCommon.getTestJar("hello.jar");
+        String appClasses[] = {"Hello"};
+        for (int i = 0; i < jigsawOptions.length; i++) {
+            OutputAnalyzer output;
+            if (i == 5) {
+                // --patch-module
+                output = TestCommon.dump(appJar, appClasses, "-Xlog:cds,cds+hashtables",
+                                         jigsawOptions[i] + optionValues[i] + appJar);
+            } else {
+                output = TestCommon.dump(appJar, appClasses, "-Xlog:cds,cds+hashtables",
+                                         jigsawOptions[i], optionValues[i]);
+            }
+            if (i < infoIdx) {
+                output.shouldContain("Cannot use the following option " +
+                    "when dumping the shared archive: " + jigsawOptions[i])
+                      .shouldHaveExitValue(1);
+            } else {
+                output.shouldContain("Info: the " + jigsawOptions[i] +
+                    " option is ignored when dumping the shared archive");
+                if (optionValues[i].equals("mymod")) {
+                      // java will throw FindException for a module
+                      // which cannot be found during init_phase2() of vm init
+                      output.shouldHaveExitValue(1)
+                            .shouldContain("java.lang.module.FindException: Module mymod not found");
+                } else {
+                      output.shouldHaveExitValue(0);
+                }
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/JigsawOptionsCombo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test combinations of jigsaw options that affect the use of AppCDS
+ *
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib ..
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @compile ../test-classes/Hello.java ../test-classes/HelloMore.java
+ * @run main JigsawOptionsCombo
+ */
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+import java.util.ArrayList;
+
+
+// Remaining WORK: TODO:
+// 1. test with -m initial-module; waiting for changes from Chris will provide
+//    utils to build modules
+// 2. Loading classes from Jmod files - waiting on utils
+// 3. Loading classes from exploded module dir"
+
+public class JigsawOptionsCombo {
+
+    public static void main(String[] args) throws Exception {
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+            InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+            "mods/java.naming");
+
+        JarBuilder.build("hello", "Hello");
+        JarBuilder.build("hello_more", "HelloMore");
+
+        (new JigsawOptionsCombo()).runTests();
+    }
+
+
+    private ArrayList<TestCase> testCaseTable = new ArrayList<TestCase>();
+
+    public static String infoDuringDump(String option) {
+        return "Info: the " + option +
+            " option is ignored when dumping the shared archive";
+    }
+
+    public void runTests() throws Exception {
+
+        testCaseTable.add(new TestCase(
+            "basic: Basic dump and execute, to verify the test plumbing works",
+            "", "", 0,
+            "", "", 0) );
+
+        String bcpArg = "-Xbootclasspath/a:" +
+        TestCommon.getTestJar("hello_more.jar");
+
+        testCaseTable.add(new TestCase(
+            "Xbootclasspath/a: is OK for both dump and run time",
+            bcpArg, "", 0,
+            bcpArg, "", 0) );
+
+        testCaseTable.add(new TestCase(
+            "module-path-01: --module-path is ignored for dump time",
+            "--module-path mods",
+            infoDuringDump("--module-path"), 0,
+            null, null, 0) );
+
+        testCaseTable.add(new TestCase(
+            "module-path-02: --module-path is ok for run time",
+            "", "", 0,
+            "--module-path mods", "", 0) );
+
+        testCaseTable.add(new TestCase(
+            "add-modules-01: --add-modules is ok at dump time",
+            "--add-modules java.management",
+            "", 0,
+            null, null, 0) );
+
+        testCaseTable.add(new TestCase(
+            "add-modules-02: --add-modules is ok at run time",
+            "", "", 0,
+            "--add-modules java.management", "", 0) );
+
+        testCaseTable.add(new TestCase(
+            "limit-modules-01: --limit-modules is ignored at dump time",
+            "--limit-modules java.base",
+            infoDuringDump("--limit-modules"), 0,
+            null, null, 0) );
+
+        testCaseTable.add(new TestCase(
+            "limit-modules-02: --limit-modules is ok at run time",
+            "", "", 0,
+            "--limit-modules java.base", "", 0) );
+
+        testCaseTable.add(new TestCase(
+            "upgrade-module-path-01: --upgrade-module-path is ignored at dump time",
+            "--upgrade-module-path mods",
+            infoDuringDump("--upgrade-module-path"), 0,
+            null, null, 0) );
+
+        testCaseTable.add(new TestCase(
+            "-upgrade-module-path-module-path-02: --upgrade-module-path is ok at run time",
+            "", "", 0,
+            "--upgrade-module-path mods", "", 0) );
+
+        for (TestCase tc : testCaseTable) tc.execute();
+    }
+
+
+    // class representing a singe test case
+    public class TestCase {
+        String description;
+        String dumpTimeArgs;
+        String dumpTimeExpectedOutput;
+        int    dumpTimeExpectedExitValue;
+        String runTimeArgs;
+        String runTimeExpectedOutput;
+        int    runTimeExpectedExitValue;
+
+        private String appJar = TestCommon.getTestJar("hello.jar");
+        private String appClasses[] = {"Hello"};
+
+
+        public TestCase(String description,
+            String dumpTimeArgs, String dumpTimeExpectedOutput, int dumpTimeExpectedExitValue,
+            String runTimeArgs, String runTimeExpectedOutput, int runTimeExpectedExitValue) {
+
+            this.description = description;
+            this.dumpTimeArgs = dumpTimeArgs;
+            this.dumpTimeExpectedOutput = dumpTimeExpectedOutput;
+            this.dumpTimeExpectedExitValue = dumpTimeExpectedExitValue;
+            this.runTimeArgs = runTimeArgs;
+            this.runTimeExpectedOutput = runTimeExpectedOutput;
+            this.runTimeExpectedExitValue = runTimeExpectedExitValue;
+        }
+
+
+        public void execute() throws Exception {
+            System.out.println("Description: " + description);
+
+            // ===== dump step - create the archive
+            OutputAnalyzer dumpOutput = TestCommon.dump(
+                appJar, appClasses, getDumpOptions());
+
+            if (dumpTimeExpectedExitValue == 0) {
+                TestCommon.checkDump(dumpOutput, dumpTimeExpectedOutput);
+            } else {
+                dumpOutput.shouldMatch(dumpTimeExpectedOutput);
+                dumpOutput.shouldHaveExitValue(dumpTimeExpectedExitValue);
+            }
+
+            // ===== exec step - use the archive
+            if (runTimeArgs != null) {
+                OutputAnalyzer execOutput = TestCommon.exec(appJar, getRunOptions());
+
+                if (runTimeExpectedExitValue == 0) {
+                    TestCommon.checkExec(execOutput, runTimeExpectedOutput, "Hello World");
+                } else {
+                    execOutput.shouldMatch(dumpTimeExpectedOutput);
+                    execOutput.shouldHaveExitValue(dumpTimeExpectedExitValue);
+                }
+            }
+        }
+
+
+        // dump command line options can be separated by a space
+        private String[] getDumpOptions() {
+            return dumpTimeArgs.split(" ");
+        }
+
+
+        // run command line options can be separated by a space
+        private String[] getRunOptions() {
+            ArrayList<String> result = new ArrayList<>();
+
+            if (runTimeArgs != "") {
+                String splitArgs[] = runTimeArgs.split(" ");
+                for (String arg : splitArgs)
+                    result.add(arg);
+            }
+
+            result.add("Hello");
+            return result.toArray(new String[1]);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/AppClassInCP.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary a test to demonstrate that an application class in the -cp
+ *          will be archived although --patch-module is specified. The class in
+ *          the -cp has no dependencies on the class in the --patch-module.
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main AppClassInCP
+ */
+
+import java.io.File;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class AppClassInCP {
+    private static String moduleJar;
+    private static String appJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        String classDir = System.getProperty("test.classes");
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+             classDir);
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        String source2 = "package mypackage; "                +
+                        "public class Hello { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"Hello!\"); " +
+                        "    } "                                    +
+                        "}";
+        ClassFileInstaller.writeClassToDisk("mypackage/Hello",
+             InMemoryJavaCompiler.compile("mypackage.Hello", source2),
+             classDir);
+
+        JarBuilder.build("hello", "mypackage/Hello");
+        appJar = TestCommon.getTestJar("hello.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        OutputAnalyzer output =
+            TestCommon.dump(appJar,
+                TestCommon.list("javax/naming/spi/NamingManager", "mypackage/Hello"),
+                "--patch-module=java.naming=" + moduleJar,
+                "-Xlog:class+load",
+                "PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        String classPath = appJar + File.pathSeparator + classDir;
+        System.out.println("classPath: " + classPath);
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-cp", classPath,
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello");
+        TestCommon.checkExec(output,
+            "I pass!",
+            "Hello!",
+            "Hello source: shared objects file");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/CustomPackage.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary if a class is defined to a package which is not defined to any
+ *          module in the jimage, the class will not be found during dump
+ *          time but it will be used during run time.
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main CustomPackage
+ */
+
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class CustomPackage {
+    private static String moduleJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.myspi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/myspi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.myspi.NamingManager", source, "--patch-module=java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming", "javax/naming/myspi/NamingManager");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        OutputAnalyzer output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/myspi/NamingManager"),
+                "--patch-module=java.naming=" + moduleJar,
+                "-Xlog:class+load",
+                "-Xlog:class+path=info",
+                "PatchMain", "javax.naming.myspi.NamingManager");
+        TestCommon.checkDump(output, "Preload Warning: Cannot find javax/naming/myspi/NamingManager");
+
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.myspi.NamingManager");
+        TestCommon.checkExec(output, "I pass!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary different settings of --patch-module at dump time and runtime are
+ *          acceptable. The class found in runtime --patch-module entry should
+ *          be used.
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main MismatchedPatchModule
+ */
+
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class MismatchedPatchModule {
+    private static String moduleJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        // Case 1: --patch-module specified for dump time and run time
+        System.out.println("Case 1: --patch-module specified for dump time and run time");
+        OutputAnalyzer output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/spi/NamingManager"),
+                "--patch-module=java.naming=" + moduleJar,
+                "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        // javax.naming.spi.NamingManager is not patched at runtime
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.naming2=" + moduleJar,
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.spi.NamingManager");
+        output.shouldNotContain("I pass!");
+
+        // Case 2: --patch-module specified for dump time but not for run time
+        System.out.println("Case 2: --patch-module specified for dump time but not for run time");
+        output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/spi/NamingManager"),
+                "--patch-module=java.naming=" + moduleJar,
+                "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        // javax.naming.spi.NamingManager is not patched at runtime
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.spi.NamingManager");
+        output.shouldNotContain("I pass!");
+
+        // Case 3: --patch-module specified for run time but not for dump time
+        System.out.println("Case 3: --patch-module specified for run time but not for dump time");
+        output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/spi/NamingManager"),
+                "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        // javax.naming.spi.NamingManager is patched at runtime
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkExec(output, "I pass!");
+
+        // Case 4: mismatched --patch-module entry counts between dump time and run time
+        System.out.println("Case 4: mismatched --patch-module entry counts between dump time and run time");
+        output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/spi/NamingManager"),
+                "--patch-module=java.naming=" + moduleJar,
+                "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        // javax.naming.spi.NamingManager is patched at runtime
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.naming=" + moduleJar,
+            "--patch-module=java.naming2=" + moduleJar,
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkExec(output, "I pass!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchDir.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary a simple test to ensure that a directory in the --patch-module
+ *          option does not affect dump process
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main PatchDir
+ */
+
+import java.io.File;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class PatchDir {
+    private static String moduleJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        String classDir = System.getProperty("test.classes");
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+             classDir);
+
+        JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        TestCommon.dump(null,
+            TestCommon.list("javax/naming/spi/NamingManager"),
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "PatchMain", "javax.naming.spi.NamingManager")
+            .shouldContain("Loading classes to share")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary sharing is disabled if java.base is patch at runtime
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main PatchJavaBase
+ */
+
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class PatchJavaBase {
+    private static String moduleJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        String source = "package java.lang; "                       +
+                        "public class NewClass { "                  +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("java/lang/NewClass",
+             InMemoryJavaCompiler.compile("java.lang.NewClass", source, "--patch-module=java.base"),
+             System.getProperty("test.classes"));
+
+        JarBuilder.build("javabase", "java/lang/NewClass");
+        moduleJar = TestCommon.getTestJar("javabase.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        OutputAnalyzer output =
+            TestCommon.dump(null, null,
+                "--patch-module=java.base=" + moduleJar,
+                "PatchMain", "java.lang.NewClass");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.base=" + moduleJar,
+            "PatchMain", "java.lang.NewClass");
+        output.shouldContain("CDS is disabled when java.base module is patched");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchMain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+// This loads the class affected by the --patch-module option.  For the test to pass
+// it must load the class from the --patch-module directory, not the jimage file.
+public class PatchMain {
+    public static void main(String[] args) throws Exception {
+        for (int i = 0; i < args.length; i++) {
+            Class.forName(args[i]);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/Simple.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary a simple test to ensure that class is loaded from jar file in --patch-module at runtime
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main Simple
+ */
+
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class Simple {
+    private static String moduleJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        OutputAnalyzer output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/spi/NamingManager"),
+                "--patch-module=java.naming=" + moduleJar,
+                "-Xlog:class+load",
+                "-Xlog:class+path=info",
+                "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkExec(output, "I pass!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/SubClassOfPatchedClass.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary the class in the -cp is a subclass of the class in --patch-module. The
+ *          patched class should be used at runtime.
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main SubClassOfPatchedClass
+ */
+
+import java.io.File;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class SubClassOfPatchedClass {
+    private static String moduleJar;
+    private static String appJar;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming; "                +
+                        "public class Reference { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        String classDir = System.getProperty("test.classes");
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/Reference",
+             InMemoryJavaCompiler.compile("javax.naming.Reference", source, "--patch-module=java.naming"),
+             classDir);
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming", "javax/naming/Reference");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        String source2 = "package mypackage; "                +
+                        "public class MyReference extends javax.naming.Reference { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"MyReference!\"); " +
+                        "    } "                                    +
+                        "    public MyReference(String mystring) { " +
+                        "        super(mystring); " +
+                        "    } " +
+                        "}";
+        ClassFileInstaller.writeClassToDisk("mypackage/MyReference",
+             InMemoryJavaCompiler.compile("mypackage.MyReference", source2),
+             classDir);
+
+        JarBuilder.build("myjavanaming", "mypackage/MyReference");
+        appJar = TestCommon.getTestJar("myjavanaming.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        OutputAnalyzer output =
+            TestCommon.dump(appJar,
+                TestCommon.list("javax/naming/Reference", "mypackage/MyReference"),
+                "--patch-module=java.naming=" + moduleJar,
+                "-Xlog:class+load",
+                "PatchMain", "javax.naming.Reference", "mypackage.MyReference");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        String classPath = appJar + File.pathSeparator + classDir;
+        System.out.println("classPath: " + classPath);
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-cp", classPath,
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "PatchMain", "javax.naming.Reference", "mypackage.MyReference");
+        TestCommon.checkExec(output,
+            "I pass!",
+            "MyReference source: file:");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/TwoJars.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @summary a patched class found in --patch-module should be used at runtime
+ * @library ../..
+ * @library /test/hotspot/jtreg/testlibrary
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchMain
+ * @run main TwoJars
+ */
+
+import java.io.File;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TwoJars {
+    private static String moduleJar;
+    private static String moduleJar2;
+
+    public static void main(String args[]) throws Throwable {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming2.jar file.
+        String source2 = "package javax.naming.spi; "                +
+                        "public class DirectoryManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I fail!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "--patch-module=java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = TestCommon.getTestJar("javanaming.jar");
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/DirectoryManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.DirectoryManager", source2, "--patch-module=java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        JarBuilder.build("javanaming2", "javax/naming/spi/DirectoryManager");
+        moduleJar2 = TestCommon.getTestJar("javanaming2.jar");
+
+        System.out.println("Test dumping with --patch-module");
+        OutputAnalyzer output =
+            TestCommon.dump(null,
+                TestCommon.list("javax/naming/spi/NamingManager"),
+                "--patch-module=java.naming=" + moduleJar2 + File.pathSeparator + moduleJar,
+                "-Xlog:class+load",
+                "-Xlog:class+path=info",
+                "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkDump(output, "Loading classes to share");
+
+        output = TestCommon.execCommon(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "--patch-module=java.naming=" + moduleJar2 + File.pathSeparator + moduleJar,
+            "-Xlog:class+load",
+            "-Xlog:class+path=info",
+            "PatchMain", "javax.naming.spi.NamingManager");
+        TestCommon.checkExec(output, "I pass");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/BootAppendTests.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * @test
+ * @summary AppCDS tests for testing -Xbootclasspath/a
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @compile src/jdk/test/Main.java
+ * @compile src/com/sun/tools/javac/Main2.jasm
+ * @compile src/sun/nio/cs/ext/MyClass.java
+ * @compile src/sun/nio/cs/ext1/MyClass.java
+ * @run main BootAppendTests
+ */
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class BootAppendTests {
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path CLASSES_DIR = Paths.get("classes");
+
+    private static final String MAIN_CLASS = "jdk.test.Main";
+    private static final String APP_MODULE_CLASS = "com/sun/tools/javac/Main2";
+    private static final String BOOT_APPEND_MODULE_CLASS = "sun/nio/cs/ext/MyClass";
+    private static final String BOOT_APPEND_CLASS = "sun/nio/cs/ext1/MyClass";
+    private static final String[] ARCHIVE_CLASSES =
+         {APP_MODULE_CLASS, BOOT_APPEND_MODULE_CLASS, BOOT_APPEND_CLASS};
+
+    private static String appJar;
+    private static String bootAppendJar;
+    private static String testArchiveName;
+
+    public static void main(String... args) throws Exception {
+        dumpArchive();
+
+        System.out.println("TESTCASE: 1: testBootAppendModuleClassWithoutAppCDS");
+        testBootAppendModuleClassWithoutAppCDS();
+
+        System.out.println("TESTCASE: 2" );
+        testBootAppendModuleClassWithAppCDS();
+
+        System.out.println("TESTCASE: 3" );
+        testBootAppendExcludedModuleClassWithoutAppCDS();
+
+        System.out.println("TESTCASE: 4" );
+        testBootAppendExcludedModuleClassWithAppCDS();
+
+        System.out.println("TESTCASE: 5" );
+        testBootAppendClassWithoutAppCDS();
+
+        System.out.println("TESTCASE: 6" );
+        testBootAppendClassWithAppCDS();
+
+        System.out.println("TESTCASE: 7" );
+        testBootAppendAppModuleClassWithoutAppCDS();
+
+        System.out.println("TESTCASE: 9" );
+        testBootAppendAppModuleClassWithAppCDS();
+
+        System.out.println("TESTCASE: 9" );
+        testBootAppendAppExcludeModuleClassWithoutAppCDS();
+
+        System.out.println("TESTCASE: 10" );
+        testBootAppendAppExcludeModuleClassAppCDS();
+    }
+
+    static void dumpArchive() throws Exception {
+        JarBuilder.build("classpathtests", "jdk/test/Main");
+        appJar = TestCommon.getTestJar("classpathtests.jar");
+
+        JarBuilder.build("bootAppend",
+                         APP_MODULE_CLASS, BOOT_APPEND_MODULE_CLASS, BOOT_APPEND_CLASS);
+        bootAppendJar = TestCommon.getTestJar("bootAppend.jar");
+
+        OutputAnalyzer output1  = TestCommon.dump(
+            appJar, TestCommon.list(ARCHIVE_CLASSES), "-Xbootclasspath/a:" + bootAppendJar);
+        TestCommon.checkDump(output1);
+
+        if (!TestCommon.isUnableToMap(output1)) {
+            // Make sure all the classes were successfully archived.
+            for (String archiveClass : ARCHIVE_CLASSES) {
+                output1.shouldNotContain("Preload Warning: Cannot find " + archiveClass);
+            }
+        }
+
+        testArchiveName = TestCommon.getCurrentArchiveName();
+    }
+
+    // Test #1: A class in package defined in boot module
+    //    - should not be loaded from the -Xbootclasspath/a without AppCDS
+    public static void testBootAppendModuleClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #1", BOOT_APPEND_MODULE_CLASS, "false");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // Test #2: A shared class in package defined in boot module that's archived
+    //          from -Xbootclasspath/a
+    //     - should not be loaded by AppCDS
+    public static void testBootAppendModuleClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "-Xbootclasspath/a:" + bootAppendJar,
+            MAIN_CLASS,
+            "Test #2", BOOT_APPEND_MODULE_CLASS, "false");
+        TestCommon.checkExec(output);
+    }
+
+
+    // Test #3: A class in excluded package defined in boot module
+    //     - should be loaded from the -Xbootclasspath/a by the boot classloader
+    public static void testBootAppendExcludedModuleClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
+                       "--limit-modules", "java.base")
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #3", BOOT_APPEND_MODULE_CLASS, "true", "BOOT");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // Test #4: A shared class in excluded package that's archived from
+    //          -Xbootclasspath/a
+    //     - should be loaded from the archive by the bootstrap classloader
+    public static void testBootAppendExcludedModuleClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "-Xbootclasspath/a:" + bootAppendJar,
+            "--limit-modules", "java.base",
+            "-XX:+TraceClassLoading",
+            MAIN_CLASS,
+            "Test #4", BOOT_APPEND_MODULE_CLASS, "true", "BOOT");
+        TestCommon.checkExec(output);
+        if (!TestCommon.isUnableToMap(output))
+            output.shouldContain("[class,load] sun.nio.cs.ext.MyClass source: shared objects file");
+    }
+
+
+    // Test #5: A class not in package defined in boot module
+    //    - should be loaded from the -Xbootclasspath/a without AppCDS
+    public static void testBootAppendClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #5", BOOT_APPEND_CLASS, "true", "BOOT");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+
+    // Test #6: A shared class not in package defined in boot module that's
+    //          archived from -Xbootclasspath/a
+    //    - should be loaded from the archive by the bootstrap class loader
+    public static void testBootAppendClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "-Xbootclasspath/a:" + bootAppendJar,
+            "-XX:+TraceClassLoading",
+            MAIN_CLASS,
+            "Test #6", BOOT_APPEND_CLASS, "true", "BOOT");
+        TestCommon.checkExec(output);
+        if (!TestCommon.isUnableToMap(output))
+            output.shouldContain("[class,load] sun.nio.cs.ext1.MyClass source: shared objects file");
+    }
+
+
+    // Test #7: A class in package defined in jimage app module
+    //    - should not be loaded from the -Xbootclasspath/a without AppCDS
+    public static void testBootAppendAppModuleClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #7", APP_MODULE_CLASS, "false");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+
+    // Test #8: A shared class in package defined in jimage app module that's
+    //          archived from -Xbootclasspath/a
+    //    - should not be loaded from the archive
+    public static void testBootAppendAppModuleClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "-Xbootclasspath/a:" + bootAppendJar,
+            MAIN_CLASS,
+            "Test #8", APP_MODULE_CLASS, "false");
+        TestCommon.checkExec(output);
+    }
+
+
+    // Test #9: A class in excluded package defined in jimage app module
+    //    - should be loaded from the -Xbootclasspath/a without AppCDS
+    public static void testBootAppendAppExcludeModuleClassWithoutAppCDS()
+        throws Exception {
+
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
+                       "--limit-modules", "java.base")
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #9", APP_MODULE_CLASS, "true", "BOOT");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // Test #10: A shared class in excluded package defined in jimage app module
+    //    - should be loaded from the -Xbootclasspath/a with AppCDS
+    public static void testBootAppendAppExcludeModuleClassAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "-Xbootclasspath/a:" + bootAppendJar,
+            "-XX:+TraceClassLoading",
+            "--limit-modules", "java.base",
+            MAIN_CLASS,
+            "Test #10", APP_MODULE_CLASS, "true", "BOOT");
+        TestCommon.checkExec(output);
+
+        if (!TestCommon.isUnableToMap(output))
+            output.shouldContain("[class,load] com.sun.tools.javac.Main2 source: shared objects file");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/ClassPathTests.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library ../..
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile src/jdk/test/Main.java
+ * @compile src/com/sun/tools/javac/Main.jasm
+ * @compile src/com/sun/tools/javac/Main2.jasm
+ * @compile src/javax/activation/UnsupportedDataTypeException2.jasm
+ * @run main ClassPathTests
+ * @summary AppCDS tests for testing classpath/package conflicts
+ */
+
+/*
+ * These tests will verify that AppCDS will correctly handle archived classes
+ * on the classpath that are in a package that is also exported by the jimage.
+ * These classes should fail to load unless --limit-modules is used to hide the
+ * package exported by the jimage. There are 8 variants of this test:
+ *   - With a jimage app package and with a jimage ext package
+ *   - With --limit-modules and without --limit-modules
+ *   - With AppCDS and without AppCDS (to verify behaviour is the same for both).
+ *
+ * There is also a 9th test to verify that when --limit-modules is used, a jimage
+ * class in the archive can be replaced by a classpath class with the
+ * same name and package.
+ */
+
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+public class ClassPathTests {
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path CLASSES_DIR = Paths.get("classes");
+
+    // the test module
+    private static final String MAIN_CLASS = "jdk.test.Main";
+    private static final String LIMITMODS_MAIN_CLASS = "jdk.test.LimitModsMain";
+
+    // test classes to archive. These are both in UPGRADED_MODULES
+    private static final String JIMAGE_CLASS      = "com/sun/tools/javac/Main";
+    private static final String APP_ARCHIVE_CLASS = "com/sun/tools/javac/Main2";
+    private static final String PLATFORM_ARCHIVE_CLASS = "javax/activation/UnsupportedDataTypeException2";
+    private static final String[] ARCHIVE_CLASSES = {APP_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, JIMAGE_CLASS};
+    private static final int NUMBER_OF_TEST_CASES = 10;
+
+    private static String appJar;
+    private static String testArchiveName;
+
+
+    public static void main(String[] args) throws Exception {
+        ClassPathTests tests = new ClassPathTests();
+        tests.dumpArchive();
+
+        Method[] methods = tests.getClass().getDeclaredMethods();
+        int numOfTestMethodsRun = 0;
+        for (Method m : methods) {
+            if (m.getName().startsWith("test")) {
+                System.out.println("About to run test method: " + m.getName());
+                m.invoke(tests);
+                numOfTestMethodsRun++;
+            }
+        }
+
+        Asserts.assertTrue((numOfTestMethodsRun == NUMBER_OF_TEST_CASES),
+            "Expected " + NUMBER_OF_TEST_CASES + " test methods to run, actual number is "
+            + numOfTestMethodsRun);
+    }
+
+    private void dumpArchive() throws Exception {
+        // Create a jar file with all the classes related to this test.
+        JarBuilder.build( "classpathtests",
+                          APP_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, JIMAGE_CLASS,
+                          "jdk/test/Main");
+        appJar = TestCommon.getTestJar("classpathtests.jar");
+
+        // dump the archive with altnernate jdk.comiler and jdk.activation classes in the class list
+        OutputAnalyzer output1  = TestCommon.dump(appJar, TestCommon.list(ARCHIVE_CLASSES));
+        TestCommon.checkDump(output1);
+        // Only a class that belongs to a module which is not defined by default
+        // can be found. In this case the PLATFORM_ARCHIVE_CLASS belongs
+        // to the java.activation which is not defined by default; it is the only
+        // class can be found during dumping.
+        for (String archiveClass : ARCHIVE_CLASSES) {
+            if (archiveClass.equals(PLATFORM_ARCHIVE_CLASS)) {
+                output1.shouldNotContain("Preload Warning: Cannot find " + archiveClass);
+            } else {
+                output1.shouldContain("Preload Warning: Cannot find " + archiveClass);
+            }
+        }
+
+        testArchiveName = TestCommon.getCurrentArchiveName();
+    }
+
+    // #1: Archived classpath class in same package as jimage app class. With AppCDS.
+    // Should fail to load.
+    public void testAppClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar, MAIN_CLASS,
+            "Test #1", APP_ARCHIVE_CLASS, "false"); // last 3 args passed to test
+        TestCommon.checkExec(output);
+    }
+
+    // #2: Archived classpath class in same package as jimage app class. Without AppCDS.
+    // Should fail to load.
+    public void testAppClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-cp", appJar)
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #2", APP_ARCHIVE_CLASS, "false");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // For tests #3 and #4, we need to "--add-modules java.activation" since the
+    // java.activation module won't be defined by default.
+
+    // #3: Archived classpath class in same package as jimage ext class. With AppCDS.
+    // Should fail to load.
+    public void testExtClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar, "--add-modules", "java.activation", MAIN_CLASS,
+            "Test #3", PLATFORM_ARCHIVE_CLASS, "false"); // last 3 args passed to test
+        TestCommon.checkExec(output);
+    }
+
+    // #4: Archived classpath class in same package as jimage ext class. Without AppCDS.
+    // Should fail to load.
+    public void testExtClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-cp", appJar, "--add-modules", "java.activation")
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #4", PLATFORM_ARCHIVE_CLASS, "false");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // #5: Archived classpath class in same package as jimage app class. With AppCDS.
+    // Should load because --limit-modules is used.
+    public void testAppClassWithLimitModsWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "--limit-modules", "java.base",
+            MAIN_CLASS,
+            "Test #5", APP_ARCHIVE_CLASS, "true"); // last 3 args passed to test
+        TestCommon.checkExec(output);
+    }
+
+    // #6: Archived classpath class in same package as jimage app class. Without AppCDS.
+    // Should load because --limit-modules is used.
+    public void testAppClassWithLimitModsWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-cp", appJar, "--limit-modules", "java.base")
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #6", APP_ARCHIVE_CLASS, "true");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // #7: Archived classpath class in same package as jimage ext class. With AppCDS.
+    // Should load because --limit-modules is used.
+    public void testExtClassWithLimitModsWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "--limit-modules", "java.base",
+            MAIN_CLASS,
+            "Test #7", PLATFORM_ARCHIVE_CLASS, "true"); // last 3 args passed to test
+        TestCommon.checkExec(output);
+    }
+
+    // #8: Archived classpath class in same package as jimage ext class. Without AppCDS.
+    // Should load because --limit-modules is used.
+    public void testExtClassWithLimitModsWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-cp", appJar, "--limit-modules", "java.base")
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #8", PLATFORM_ARCHIVE_CLASS, "true");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+    // #9: Archived classpath class with same name as jimage app class. With AppCDS.
+    // Should load because --limit-modules is used.
+    public void testReplacingJImageClassWithAppCDS() throws Exception {
+        OutputAnalyzer output = TestCommon.exec(
+            appJar,
+            "--limit-modules", "java.base", "-XX:+TraceClassLoading",
+            MAIN_CLASS,
+            "Test #9", JIMAGE_CLASS, "true"); // last 3 args passed to test
+        TestCommon.checkExec(output);
+    }
+
+    // #10: Archived classpath class with same name as jimage app class. Without AppCDS.
+    // Should load because --limit-modules is used. Note the archive will actually contain
+    // the original jimage version of the class, but AppCDS should refuse to load it
+    // since --limit-modules is used. This should result in the -cp version being used.
+    public void testReplacingJImageClassWithoutAppCDS() throws Exception {
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix("-cp", appJar, "--limit-modules", "java.base")
+            .setArchiveName(testArchiveName)
+            .addSuffix(MAIN_CLASS, "Test #10", JIMAGE_CLASS, "true");
+
+        CDSTestUtils.runWithArchiveAndCheck(opts);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/DummyClassesInBootClassPath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Ensure that classes found in jimage takes precedence over classes found in -Xbootclasspath/a.
+ * AppCDS does not support uncompressed oops
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.activation
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../../test-classes/DummyClassHelper.java
+ * @compile ../../test-classes/java/net/HttpCookie.jasm
+ * @compile ../../test-classes/javax/activation/MimeType.jasm
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main DummyClassesInBootClassPath
+ */
+
+import java.io.File;
+import java.util.List;
+import java.util.ArrayList;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class DummyClassesInBootClassPath {
+    private static final String METHOD_NAME = "thisClassIsDummy()";
+
+    public static void main(String[] args) throws Exception {
+        String classNames[] = { "java/net/HttpCookie",
+                                "javax/activation/MimeType"};
+        JarBuilder.build("dummyClasses", classNames[0], classNames[1]);
+
+        String appJar = TestCommon.getTestJar("dummyClasses.jar");
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+            appJar, classNames, "-Xbootclasspath/a:" + appJar);
+
+        List<String> argsList = new ArrayList<String>();
+        for (int i = 0; i < classNames.length; i++) {
+            argsList.add(classNames[i].replace('/', '.'));
+        }
+        String[] arguments = new String[argsList.size()];
+        arguments = argsList.toArray(arguments);
+        OutputAnalyzer execOutput = TestCommon.execCommon(
+            "-cp", TestCommon.getTestDir("."), "-verbose:class",
+            "--add-modules", "java.activation",
+            "-Xbootclasspath/a:" + appJar, "DummyClassHelper",
+            arguments[0], arguments[1]);
+        for (int i = 0; i < arguments.length; i++) {
+            TestCommon.checkExec(execOutput,
+                "java.lang.NoSuchMethodException: " + arguments[i] + "." +
+                METHOD_NAME);
+        }
+
+        JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        String whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
+        String bootClassPath = "-Xbootclasspath/a:" + appJar +
+            File.pathSeparator + whiteBoxJar;
+        argsList.add("testWithWhiteBox");
+        arguments = new String[argsList.size()];
+        arguments = argsList.toArray(arguments);
+        String[] opts = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+            bootClassPath, "-XX:+TraceClassPaths", "DummyClassHelper",
+            arguments[0], arguments[1], arguments[2]};
+        OutputAnalyzer output = TestCommon.execCommon(opts);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/EmptyClassInBootClassPath.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test a few scenarios if an empty class, which has the same name as the one in the jimage, is specified in the -Xbootclasspath/a
+ *     1) boot loader will always load the class from the bootclasspath
+ *     2) app loader will load the class from the jimage by default;
+ *        app loader will load the class from the bootclasspath if the
+ *        "--limit-modules java.base" option is specified
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @compile ../../test-classes/EmptyClassHelper.java
+ * @compile ../../test-classes/com/sun/tools/javac/Main.jasm
+ * @run main EmptyClassInBootClassPath
+ */
+
+import java.io.File;
+import java.lang.*;
+import java.lang.reflect.*;
+import java.util.List;
+import java.util.ArrayList;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class EmptyClassInBootClassPath {
+    static final String EXPECTED_EXCEPTION =
+        "java.lang.NoSuchMethodException: com.sun.tools.javac.Main.main([Ljava.lang.String;)";
+    public static void main(String[] args) throws Exception {
+        String[] className = {"com/sun/tools/javac/Main"};
+        JarBuilder.build("emptyClass", className);
+        String appJar = TestCommon.getTestJar("emptyClass.jar");
+        JarBuilder.build("EmptyClassHelper", "EmptyClassHelper");
+        String helperJar = TestCommon.getTestJar("EmptyClassHelper.jar");
+        OutputAnalyzer dumpOutput = TestCommon.dump(
+            appJar, className, "-Xbootclasspath/a:" + appJar);
+        TestCommon.checkDump(dumpOutput);
+        dumpOutput.shouldNotContain("Preload Warning: skipping class from -Xbootclasspath/a " + className[0]);
+
+        String bootclasspath = "-Xbootclasspath/a:" + appJar;
+        String classPath = "-Djava.class.path=" + appJar + File.pathSeparator + helperJar;
+        List<String> argsList = new ArrayList<String>();
+        argsList.add(classPath);
+        argsList.add(bootclasspath);
+        argsList.add("--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED");
+        argsList.add("EmptyClassHelper");
+
+        // case 1: load class in bootclasspath using app loader
+        argsList.add("useAppLoader");
+        String[] opts = new String[argsList.size()];
+        opts = argsList.toArray(opts);
+        OutputAnalyzer runOutput = TestCommon.execCommon(opts);
+        TestCommon.checkExec(runOutput, "appLoader found method main");
+
+        // case 2: load class in bootclasspath using boot loader
+        argsList.remove(argsList.size() - 1);
+        argsList.add("useBootLoader");
+        opts = new String[argsList.size()];
+        opts = argsList.toArray(opts);
+        runOutput = TestCommon.execCommon(opts);
+        TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+
+        // case 3: load class in bootclasspath using app loader with '--limit-modules java.base'
+        argsList.add(0, "--limit-modules");
+        argsList.add(1, "java.base");
+        argsList.remove(argsList.size() - 1);
+        argsList.add("useAppLoader");
+        opts = new String[argsList.size()];
+        opts = argsList.toArray(opts);
+        runOutput = TestCommon.execCommon(opts);
+        TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+
+        // case 4: load class in bootclasspath using boot loader with '--limit-modules java.base'
+        argsList.remove(argsList.size() - 1);
+        argsList.add("useBootLoader");
+        opts = new String[argsList.size()];
+        opts = argsList.toArray(opts);
+        runOutput = TestCommon.execCommon(opts);
+        TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/src/com/sun/tools/javac/Main.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 2017, 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 com/sun/tools/javac;
+
+public class Main
+    version 51:0
+{
+
+public Method "<init>":"()V"
+    stack 1 locals 1
+{
+    aload_0;
+    invokespecial   Method java/lang/Object."<init>":"()V";
+    return;
+}
+
+public Method toString:"()Ljava/lang/String;"
+    stack 1 locals 1
+{
+    ldc String "hi";
+    areturn;
+}
+
+} // end class Main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/src/com/sun/tools/javac/Main2.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 2017, 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 com/sun/tools/javac;
+
+public class Main2
+    version 51:0
+{
+
+public Method "<init>":"()V"
+    stack 1 locals 1
+{
+    aload_0;
+    invokespecial   Method java/lang/Object."<init>":"()V";
+    return;
+}
+
+public Method toString:"()Ljava/lang/String;"
+    stack 1 locals 1
+{
+    ldc String "hi";
+    areturn;
+}
+
+} // end class Main2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/src/javax/activation/UnsupportedDataTypeException2.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 2017, 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 javax/activation;
+
+public class UnsupportedDataTypeException2
+    version 51:0
+{
+
+public Method "<init>":"()V"
+    stack 1 locals 1
+{
+    aload_0;
+    invokespecial   Method java/lang/Object."<init>":"()V";
+    return;
+}
+
+public Method toString:"()Ljava/lang/String;"
+    stack 1 locals 1
+{
+    ldc String "hi";
+    areturn;
+}
+
+} // end class UnsupportedDataTypeException2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/src/jdk/test/Main.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * Tests loading an archived class that has the same class name as one in the
+ * jimage. The class should normally fail to load since a classpath class is not
+ * allowed to have the same package name as a module in the jimage. However,
+ * if --limit-modules was used then archived class should be loaded.
+ */
+
+package jdk.test;
+
+public class Main {
+    static final ClassLoader BOOT_LOADER     = null;
+    static final ClassLoader PLATFORM_LOADER = ClassLoader.getPlatformClassLoader();
+    static final ClassLoader SYS_LOADER      = ClassLoader.getSystemClassLoader();
+
+    public static void main(String[] args) throws Exception {
+        boolean shouldLoad = false;
+        ClassLoader expectedLoader = SYS_LOADER;
+
+        /*
+         * 3 Arguments are passed to this test:
+         *   1. testName: Name of the test being run.
+         *   2. className: Name of the class to load and instantiate.
+         *   3. shouldLoad: Either "true" or "false" to indicate whether the class should
+         *      successfully load ("true" indicates --limit-modules was used.)
+         * The 4th argument is optional. It specifies the classloader.
+         */
+
+        assertTrue(args.length <= 4);
+        String testName = args[0];
+        String className = args[1].replace('/', '.');
+        String shouldLoadName = args[2];  // "true" or "false"
+        String loaderName = "SYS";
+        if (args.length == 4) {
+            loaderName = args[3];
+        }
+
+        if (shouldLoadName.equals("true")) {
+            shouldLoad = true;
+        } else if (shouldLoadName.equals("false")) {
+            shouldLoad = false;
+        } else {
+            assertTrue(false);
+        }
+
+        if (loaderName.equals("SYS")) {
+            expectedLoader = SYS_LOADER;
+        } else if (loaderName.equals("EXT")) {
+            expectedLoader = PLATFORM_LOADER;
+        } else if (loaderName.equals("BOOT")) {
+            expectedLoader = BOOT_LOADER;
+        }
+
+        System.out.println(testName + ": class=" + className + " shouldLoad=" +
+                           shouldLoadName + " by loader:" + expectedLoader);
+
+        // Try to load the specified class with the default ClassLoader.
+        Class<?> clazz = null;
+        try {
+            clazz = Class.forName(className);
+        } catch (ClassNotFoundException e) {
+            System.out.println(e);
+        }
+
+        if (clazz != null) {
+            // class loaded
+            if (shouldLoad) {
+                // Make sure we got the expected defining ClassLoader
+                ClassLoader actualLoader = clazz.getClassLoader();
+                if (actualLoader != expectedLoader) {
+                    throw new RuntimeException(testName + " FAILED: " + clazz + " loaded by " + actualLoader +
+                                               ", expected " + expectedLoader);
+                }
+                // Make sure we got the right version of the class. toString() of an instance
+                // of the overridden version of the class should return "hi".
+                String s = clazz.newInstance().toString();
+                if (!s.equals("hi")) {
+                    throw new RuntimeException(testName + " FAILED: toString() returned \"" + s
+                                               + "\" instead of \"hi\"" );
+                }
+                System.out.println(testName + " PASSED: class loaded as expected.");
+            } else {
+                throw new RuntimeException(testName + " FAILED: class loaded, but should have failed to load.");
+            }
+        } else {
+            // class did not load
+            if (shouldLoad) {
+                throw new RuntimeException(testName + " FAILED: class failed to load.");
+            } else {
+                System.out.println(testName + " PASSED: ClassNotFoundException thrown as expected");
+            }
+        }
+    }
+
+    static void assertTrue(boolean expr) {
+        if (!expr)
+            throw new RuntimeException("assertion failed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/src/sun/nio/cs/ext/MyClass.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 2017, 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 sun.nio.cs.ext;
+
+public class MyClass {
+    public String toString() {
+        return "hi";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/src/sun/nio/cs/ext1/MyClass.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 2017, 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 sun.nio.cs.ext1;
+
+public class MyClass {
+    public String toString() {
+        return "hi";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/limitmods/LimitModsHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * Used with -p or --upgrade-module-path to exercise the replacement
+ * of classes in modules that are linked into the runtime image.
+ */
+
+import java.lang.*;
+import java.lang.reflect.*;
+import sun.hotspot.WhiteBox;
+
+
+public class LimitModsHelper {
+    static final ClassLoader PLATFORM_LOADER = ClassLoader.getPlatformClassLoader();
+    static final ClassLoader SYS_LOADER      = ClassLoader.getSystemClassLoader();
+
+    public static void main(String[] args) throws Exception {
+        assertTrue(args.length == 4);
+        String[] classNames = new String[3];
+        for (int i = 0; i < 3; i++) {
+            classNames[i] = args[i].replace('/', '.');
+        }
+        int excludeModIdx = Integer.parseInt(args[3]);
+
+        ClassLoader expectedLoaders[] = {null, PLATFORM_LOADER, SYS_LOADER};
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        Class<?> clazz = null;
+        for (int i = 0; i < 3; i++) {
+            try {
+                // Load the class with the default ClassLoader.
+                clazz = Class.forName(classNames[i]);
+            } catch (Exception e) {
+                if (i == excludeModIdx) {
+                    System.out.println(classNames[i] + " not found as expected because the module isn't in the --limit-modules - PASSED");
+                } else {
+                    throw(e);
+                }
+            }
+
+            if (clazz != null && i != excludeModIdx) {
+                // Make sure we got the expected defining ClassLoader
+                testLoader(clazz, expectedLoaders[i]);
+
+                // Make sure the class is in the shared space
+                if (!wb.isSharedClass(clazz)) {
+                    throw new RuntimeException(clazz.getName() +
+                        ".class should be in the shared space. " +
+                         "loader=" + clazz.getClassLoader() + " module=" + clazz.getModule().getName());
+                }
+            }
+            clazz = null;
+        }
+    }
+
+    /**
+     * Asserts that given class has the expected defining loader.
+     */
+    static void testLoader(Class<?> clazz, ClassLoader expected) {
+        ClassLoader loader = clazz.getClassLoader();
+        if (loader != expected) {
+            throw new RuntimeException(clazz + " loaded by " + loader + ", expected " + expected);
+        }
+    }
+
+    static void assertTrue(boolean expr) {
+        if (!expr)
+            throw new RuntimeException("assertion failed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/limitmods/LimitModsTests.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library ../..
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.jartool/sun.tools.jar
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @compile LimitModsHelper.java
+ * @compile ../../test-classes/java/net/HttpCookie.jasm
+ * @compile ../../test-classes/jdk/dynalink/DynamicLinker.jasm
+ * @compile ../../test-classes/com/sun/tools/javac/Main.jasm
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main LimitModsTests
+ * @summary AppCDS tests for excluding class in module by using --limit-modules.
+ */
+
+/**
+ * This is for testing the --limit-modules option with AppCDS.
+ * This test assumes the following defining class loader, module, class relations:
+ * class loader    module            class
+ * -----------------------------------------------------
+ * boot            java.base         java/net/HttpCookie
+ * platform        jdk.dynalink      jdk/dynalink/DynamicLinker
+ * app             jdk.compiler      com/sun/tools/javac/Main
+ *
+ * This test dumps the above 3 classes into a shared archive.
+ * Then it will run the following 4 -limit-modules scenarios:
+ * 1. without --limit-modules
+ *    All 3 classes should be loaded successfully.
+ *    All 3 classes should be loaded by the appropriate class loader.
+ *    All 3 classes should be found in the shared archive.
+ * 2. --limit-modules java.base,jdk.dynalink
+ *    The loading of the com/sun/tools/javac/Main class should fail.
+ *    The other 2 classes should be loaded successfully and by the appropriate class loader.
+ *    The other 2 classes should be found in the shared archive.
+ * 3. --limit-modules java.base,jdk.compiler
+ *    The loading of the jdk/nio/dynalink/DynamicLinker class should fail.
+ *    The other 2 classes should be loaded successfully and by the appropriate class loader.
+ *    The other 2 classes should be found in the shared archive.
+ * 4. --limit-modules jdk.dynalink,jdk.compiler
+ *    The java.base module can't be excluded.
+ *    The results for this case is the same as for case #1.
+ */
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+public class LimitModsTests {
+
+    // the module that is limited
+    private static final String[] LIMIT_MODULES = {"java.base", "jdk.dynalink", "jdk.compiler"};
+
+    // test classes to archive.
+    private static final String BOOT_ARCHIVE_CLASS = "java/net/HttpCookie";
+    private static final String PLATFORM_ARCHIVE_CLASS = "jdk/dynalink/DynamicLinker";
+    private static final String APP_ARCHIVE_CLASS = "com/sun/tools/javac/Main";
+    private static final String[] ARCHIVE_CLASSES = {
+        BOOT_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, APP_ARCHIVE_CLASS};
+    private String bootClassPath = null;
+    private String whiteBoxJar = null;
+    private String helperJar = null;
+    private String appJar = null;
+    private OutputAnalyzer output = null;
+
+    public static void main(String[] args) throws Exception {
+        LimitModsTests tests = new LimitModsTests();
+        tests.dumpArchive();
+        tests.runTestNoLimitMods();
+        tests.runTestLimitMods();
+    }
+
+    void dumpArchive() throws Exception {
+        JarBuilder.build("limitModsTest", BOOT_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, APP_ARCHIVE_CLASS);
+        JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
+        JarBuilder.build("limitModsHelper", "LimitModsHelper");
+
+        appJar = TestCommon.getTestJar("limitModsTest.jar");
+        whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
+        helperJar = TestCommon.getTestJar("limitModsHelper.jar");
+        bootClassPath = "-Xbootclasspath/a:" + whiteBoxJar;
+        // Dump the test classes into the archive
+        OutputAnalyzer output1  = TestCommon.dump(appJar, TestCommon.list(ARCHIVE_CLASSES), bootClassPath);
+        TestCommon.checkDump(output1);
+        // Make sure all the classes where successfully archived.
+        for (String archiveClass : ARCHIVE_CLASSES) {
+            output1.shouldNotContain("Preload Warning: Cannot find " + archiveClass);
+        }
+    }
+
+    // run the test without --limit-modules
+    public void runTestNoLimitMods() throws Exception {
+        output = TestCommon.exec(
+            appJar + File.pathSeparator + helperJar,
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", bootClassPath,
+            "LimitModsHelper",
+            BOOT_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, APP_ARCHIVE_CLASS, "-1"); // last 4 args passed to test
+        TestCommon.checkExec(output);
+    }
+
+    // run the test with --limit-modules
+    //
+    // --limit-modules jdk.dynalink,jdk.compiler
+    // It seems we can't exclude the java.base module. For this case,
+    // although the java.base module isn't in --limit-modules, the class
+    // in the java.base module (java.net.HttpCookie) can also be found.
+    //
+    // --limit-modules java.base,jdk.dynalink
+    // --limit-modules java.base,jdk.compiler
+    public void runTestLimitMods() throws Exception {
+        String limitMods = null;
+        for (int excludeModIdx = 0; excludeModIdx < 3; excludeModIdx++) {
+            for (int includeModIdx = 0; includeModIdx < 3; includeModIdx++) {
+                if (includeModIdx != excludeModIdx) {
+                    if (limitMods != null) {
+                        limitMods += ",";
+                        limitMods += LIMIT_MODULES[includeModIdx];
+                    } else {
+                        limitMods = LIMIT_MODULES[includeModIdx];
+                    }
+                }
+            }
+            output = TestCommon.exec(
+                appJar + File.pathSeparator + helperJar,
+                "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", bootClassPath,
+                "--limit-modules", limitMods,
+                "LimitModsHelper",
+                BOOT_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, APP_ARCHIVE_CLASS,
+                Integer.toString(excludeModIdx)); // last 4 args passed to test
+            TestCommon.checkExec(output);
+            limitMods = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/OverrideTests.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * @test
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @modules java.base/jdk.internal.misc
+ * @library ../..
+ * @library /test/lib
+ * @run main OverrideTests
+ * @summary AppCDS tests for overriding archived classes with -p and --upgrade-module-path
+ */
+
+/*
+ * This test consists of 4 tests:
+ *   1. Archive PLATFORM class and override with --upgrade-module-path.
+ *   2. Archive PLATFORM class and override with -p.
+ *   3. Archive APP class and override with --upgrade-module-path.
+ *   4. Archive App class and override with -p.
+ * For all 4 tests, the class is instantiatied and toString() is called
+ * to check whether the archived version or the override version was instantiatied.
+ * For tests 1 and 3, the overridden version should be instantiatied.
+ * For tests 2 and 4, the archived version should be instantiated.
+ *
+ * This test uses the same test helper class in all 4 cases. It is located in
+ * src/test/jdk/test/Main.java. It will be invoked once for each test cases,
+ * with parameters to the test determining how it is run and what the
+ * expected result is. See Main.java for a description of these 3 arguments.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+
+public class OverrideTests {
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MODS_DIR = Paths.get("mods");
+
+    // the module that is upgraded
+    private static final String[] UPGRADED_MODULES = {"jdk.compiler", "java.activation"};
+    private static final Path[] UPGRADEDMODS_DIR = {Paths.get("upgradedmod1"), Paths.get("upgradedmod2")};
+
+    // the test module
+    private static final String TEST_MODULE = "test";
+    private static final String MAIN_CLASS = "jdk.test.Main";
+
+    // test classes to archive. These are both in UPGRADED_MODULES
+    private static final String APP_ARCHIVE_CLASS = "com/sun/tools/javac/Main";
+    private static final String PLATFORM_ARCHIVE_CLASS = "javax/activation/UnsupportedDataTypeException";
+    private static final String[] ARCHIVE_CLASSES = {APP_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS};
+    private static String testArchiveName;
+
+
+    public static void main(String[] args) throws Exception {
+        OverrideTests tests = new OverrideTests();
+        tests.compileModulesAndDumpArchive();
+        tests.testAppClassOverriding();
+        tests.testPlatformClassOverriding();
+    }
+
+    void compileModulesAndDumpArchive() throws Exception {
+        boolean compiled;
+        // javac -d upgradedmods/$upgradedMod src/$upgradedMod/**
+        int i = 0;
+        for (String upgradedMod : UPGRADED_MODULES) {
+            compiled = CompilerUtils.compile(
+                SRC_DIR.resolve(upgradedMod),
+                UPGRADEDMODS_DIR[i].resolve(upgradedMod)
+            );
+            Asserts.assertTrue(compiled, upgradedMod + " did not compile");
+            i++;
+        }
+
+        // javac -d mods/test --upgrade-module-path upgradedmods ...
+        compiled = CompilerUtils.compile(
+            SRC_DIR.resolve(TEST_MODULE),
+            MODS_DIR.resolve(TEST_MODULE),
+            "--upgrade-module-path", UPGRADEDMODS_DIR[0].toString() +
+             System.getProperty("path.separator") + UPGRADEDMODS_DIR[1].toString()
+        );
+        Asserts.assertTrue(compiled, TEST_MODULE + " did not compile");
+
+        // the java.activation module is not defined by default; --add-modules is required.
+        // dumping without "--add-modules java.activation"
+        // the class in the javax.activation package cannot be found
+        OutputAnalyzer output1  = TestCommon.dump(null /* appJar*/, TestCommon.list(ARCHIVE_CLASSES));
+        TestCommon.checkDump(output1);
+        output1.shouldContain(
+            "Preload Warning: Cannot find javax/activation/UnsupportedDataTypeException");
+
+        // dump the archive with jdk.comiler and java.activation classes in the class list
+        // with "--add-modules java.activation"
+        output1  = TestCommon.dump(null /* appJar*/, TestCommon.list(ARCHIVE_CLASSES),
+            "--add-modules", "java.activation");
+        TestCommon.checkDump(output1);
+        // Make sure all the classes where successfully archived.
+        for (String archiveClass : ARCHIVE_CLASSES) {
+            output1.shouldNotContain("Preload Warning: Cannot find " + archiveClass);
+        }
+
+        testArchiveName = TestCommon.getCurrentArchiveName();
+    }
+
+    /**
+     * APP Class Overriding Tests
+     *
+     * Archive APP class com.sun.tools.javac.Main from module jdk.compiler.
+     *  -At run time, upgrade module jdk.compiler using --upgrade-module-path.
+     *   Class.forname(Main) MUST NOT load the archived Main.
+     *  -At run time, module jdk.compiler also exists in --module-path.
+     *   Class.forname(Main) MUST load the archived Main.
+     */
+    public void testAppClassOverriding() throws Exception {
+        testClassOverriding(APP_ARCHIVE_CLASS, "app");
+    }
+
+    /**
+     * PLATFORM Class Overriding Tests
+     *
+     * Archive PLATFORM class javax.activation.UnsupportedDataTypeException from module jdk.activation.
+     *  -At run time, upgrade module jdk.activation using --upgrade-module-path.
+     *   Class.forname(UnsupportedDataTypeException) MUST NOT load the archived UnsupportedDataTypeException.
+     *  -At run time, module jdk.activation also exists in --module-path.
+     *   Class.forname(UnsupportedDataTypeException) MUST load the archived UnsupportedDataTypeException.
+     */
+    public void testPlatformClassOverriding() throws Exception {
+        testClassOverriding(PLATFORM_ARCHIVE_CLASS, "platform");
+    }
+
+    /**
+     * Run the test twice. Once with upgrade module on --upgrade-module-path and once with it on -p.
+     * Only modules defined to the PlatformClassLoader are upgradeable.
+     * Modules defined to the AppClassLoader are not upgradeble; we expect the
+     * FindException to be thrown.
+     */
+    void testClassOverriding(String archiveClass, String loaderName) throws Exception {
+        String mid = TEST_MODULE + "/" + MAIN_CLASS;
+        OutputAnalyzer output;
+        boolean isAppLoader = loaderName.equals("app");
+        int upgradeModIdx = isAppLoader ? 0 : 1;
+        String expectedException = "java.lang.module.FindException: Unable to compute the hash";
+        String prefix[] = new String[4];
+        prefix[0] = "-cp";
+        prefix[1] = "\"\"";
+        prefix[2] = "--add-modules";
+        prefix[3] = "java.activation";
+
+        // Run the test with --upgrade-module-path set to alternate location of archiveClass
+        // The alternate version of archiveClass SHOULD be found.
+        output = TestCommon.execModule(
+            prefix,
+            UPGRADEDMODS_DIR[upgradeModIdx].toString(),
+            MODS_DIR.toString(),
+            mid,
+            archiveClass, loaderName, "true"); // last 3 args passed to test
+        if (isAppLoader) {
+            try {
+                output.shouldContain(expectedException);
+            } catch (Exception e) {
+                TestCommon.checkCommonExecExceptions(output, e);
+            }
+        } else {
+            TestCommon.checkExec(output);
+        }
+
+        // Now run this same test again, but this time without AppCDS. Behavior should be the same.
+        CDSOptions opts = (new CDSOptions())
+            .addPrefix(prefix)
+            .setArchiveName(testArchiveName).setUseVersion(false)
+            .addSuffix("--upgrade-module-path", UPGRADEDMODS_DIR[upgradeModIdx].toString(),
+                       "-p", MODS_DIR.toString(), "-m", mid)
+            .addSuffix(archiveClass, loaderName, "true");
+
+        output = CDSTestUtils.runWithArchive(opts);
+
+        if (isAppLoader) {
+            try {
+                output.shouldContain(expectedException);
+            } catch (Exception e) {
+                TestCommon.checkCommonExecExceptions(output, e);
+            }
+        } else {
+            if (!CDSTestUtils.isUnableToMap(output))
+                output.shouldHaveExitValue(0);
+        }
+
+        // Run the test with -p set to alternate location of archiveClass.
+        // The alternate version of archiveClass SHOULD NOT be found.
+        output = TestCommon.execModule(
+            prefix,
+            null,
+            UPGRADEDMODS_DIR[upgradeModIdx].toString() + java.io.File.pathSeparator + MODS_DIR.toString(),
+            mid,
+            archiveClass, loaderName, "false"); // last 3 args passed to test
+        TestCommon.checkExec(output);
+
+        // Now  run this same test again, but this time without AppCDS. Behavior should be the same.
+        opts = (new CDSOptions())
+            .addPrefix(prefix)
+            .setArchiveName(testArchiveName).setUseVersion(false)
+            .addSuffix("-p", MODS_DIR.toString(), "-m", mid)
+            .addSuffix(archiveClass, loaderName, "false"); // params to the test class
+
+        OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+        if (!CDSTestUtils.isUnableToMap(out))
+            out.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/src/java.activation/javax/activation/UnsupportedDataTypeException.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 2017, 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 javax.activation;
+
+import java.io.IOException;
+
+public class UnsupportedDataTypeException extends IOException {
+    public UnsupportedDataTypeException() {
+    }
+
+    public String toString() {
+        return "hi";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/src/java.activation/module-info.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+module java.activation {
+    exports javax.activation;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/src/jdk.compiler/com/sun/tools/javac/Main.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 2017, 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 com.sun.tools.javac;
+
+public class Main {
+    public String toString() {
+        return "hi";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/src/jdk.compiler/module-info.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+module jdk.compiler {
+    exports com.sun.tools.javac;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/src/test/jdk/test/Main.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/**
+ * Used with -p or --upgrade-module-path to exercise the replacement
+ * of classes in modules that are linked into the runtime image.
+ */
+
+package jdk.test;
+
+public class Main {
+    static final ClassLoader PLATFORM_LOADER = ClassLoader.getPlatformClassLoader();
+    static final ClassLoader SYS_LOADER      = ClassLoader.getSystemClassLoader();
+
+    public static void main(String[] args) throws Exception {
+        ClassLoader loader = null;
+        boolean shouldOverride = false;
+
+        /*
+         * 3 Arguments are passed to this test:
+         *   1. className: Name of the class to load.
+         *   2. loaderName: Either "platform" or "app", which specifies which ClassLoader is expected
+         *      to be the defining ClassLoader once the class is loaded. The initiating
+         *      ClassLoader is always the default ClassLoader (which should be the
+         *      app (system) ClassLoader.
+         *   3. shouldOverride: Either "true" or "false" to indicate whether the loaded class
+         *      should be the one we are attempting to override with (not the archived version).
+         */
+
+        assertTrue(args.length == 3, "Unexpected number of arguments: expected 3, actual " + args.length);
+        String className = args[0].replace('/', '.');
+        String loaderName = args[1]; // "platform" or "app"
+        String shouldOverrideName = args[2];  // "true" or "false"
+
+        if (loaderName.equals("app")) {
+            loader = SYS_LOADER;
+        } else if (loaderName.equals("platform")) {
+            loader = PLATFORM_LOADER;
+        } else {
+            assertTrue(false);
+        }
+
+        if (shouldOverrideName.equals("true")) {
+            shouldOverride = true;
+        } else if (shouldOverrideName.equals("false")) {
+            shouldOverride = false;
+        } else {
+            assertTrue(false);
+        }
+
+        // Load the class with the default ClassLoader.
+        Class<?> clazz = Class.forName(className, true, loader);
+        // Make sure we got the expected defining ClassLoader
+        testLoader(clazz, loader);
+        // Create an instance and see what toString() returns
+        String s = clazz.newInstance().toString();
+        // The overridden version of the class should return "hi". Make sure
+        // it does only if we are expecting to have loaded the overridden version.
+        assertTrue(s.equals("hi") == shouldOverride);
+    }
+
+    /**
+     * Asserts that given class has the expected defining loader.
+     */
+    static void testLoader(Class<?> clazz, ClassLoader expected) {
+        ClassLoader loader = clazz.getClassLoader();
+        if (loader != expected) {
+            throw new RuntimeException(clazz + " loaded by " + loader + ", expected " + expected);
+        }
+    }
+
+    static void assertTrue(boolean expr) {
+        assertTrue(expr, "");
+    }
+
+    static void assertTrue(boolean expr, String msg) {
+        if (!expr)
+            throw new RuntimeException("assertion failed: " + msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/overridetests/src/test/module-info.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+module test {
+    requires jdk.compiler;
+    requires java.activation;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/ClassFileLoadHook.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+class LoadMe {
+    static String getValue() {
+        return "beforeHook";
+    }
+    static String getOtherValue() {
+        return "abc-beforeHook-xyz";
+    }
+}
+
+public class ClassFileLoadHook {
+    public enum TestCaseId {
+        SHARING_OFF_CFLH_ON,   // test case to establish a baseline
+        SHARING_ON_CFLH_OFF,
+        SHARING_AUTO_CFLH_ON,
+        SHARING_ON_CFLH_ON
+    }
+
+    public static void main(String args[]) {
+        TestCaseId testCase = TestCaseId.valueOf(args[0]);
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        System.out.println("====== ClassFileLoadHook.main():testCase = " + testCase);
+        System.out.println("getValue():" + LoadMe.getValue());
+        System.out.println("getOtherValue():" + LoadMe.getOtherValue());
+
+        switch (testCase) {
+            case SHARING_OFF_CFLH_ON:
+                assertTrue("after_Hook".equals(LoadMe.getValue()) &&
+                           "abc-after_Hook-xyz".equals(LoadMe.getOtherValue()),
+                           "Not sharing, this test should replace beforeHook " +
+                           "with after_Hook");
+            break;
+
+            case SHARING_ON_CFLH_OFF:
+                assertTrue(wb.isSharedClass(LoadMe.class),
+                    "LoadMe should be shared, but is not");
+                assertTrue("beforeHook".equals(LoadMe.getValue()) &&
+                           "abc-beforeHook-xyz".equals(LoadMe.getOtherValue()),
+                           "CFLH off, bug values are redefined");
+            break;
+
+            case SHARING_AUTO_CFLH_ON:
+            case SHARING_ON_CFLH_ON:
+                // LoadMe is rewritten on CFLH
+                assertFalse(wb.isSharedClass(LoadMe.class),
+                    "LoadMe should not be shared if CFLH has modified the class");
+                assertFalse("beforeHook".equals(LoadMe.getValue()) &&
+                           "abc-beforeHook-xyz".equals(LoadMe.getOtherValue()),
+                           "Class contents should be changed if CFLH is enabled");
+             break;
+
+             default:
+                 throw new RuntimeException("Invalid testcase");
+
+        }
+    }
+
+    private static void assertTrue(boolean expr, String msg) {
+        if (!expr)
+            throw new RuntimeException(msg);
+    }
+
+    private static void assertFalse(boolean expr, String msg) {
+        if (expr)
+            throw new RuntimeException(msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/ClassFileLoadHookTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test jvmti class file loader hook interaction with AppCDS
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ * @build ClassFileLoadHook
+ * @run main/othervm/native ClassFileLoadHookTest
+ */
+
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+
+public class ClassFileLoadHookTest {
+    public static String sharedClasses[] = {
+        "ClassFileLoadHook",
+        "ClassFileLoadHook$TestCaseId",
+        "ClassFileLoadHook$1",
+        "LoadMe"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String wbJar =
+            ClassFileInstaller.writeJar("WhiteBox.jar", "sun.hotspot.WhiteBox");
+        String appJar =
+            ClassFileInstaller.writeJar("ClassFileLoadHook.jar", sharedClasses);
+        String useWb = "-Xbootclasspath/a:" + wbJar;
+
+        // First, run the test class directly, w/o sharing, as a baseline reference
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                useWb,
+                "-agentlib:SimpleClassFileLoadHook=LoadMe,beforeHook,after_Hook",
+                "ClassFileLoadHook",
+                "" + ClassFileLoadHook.TestCaseId.SHARING_OFF_CFLH_ON);
+        TestCommon.executeAndLog(pb, "no-sharing").shouldHaveExitValue(0);
+
+        // Run with AppCDS, but w/o CFLH - second baseline
+        TestCommon.testDump(appJar, sharedClasses, useWb);
+        OutputAnalyzer out = TestCommon.exec(appJar,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI", useWb,
+                "ClassFileLoadHook",
+                "" + ClassFileLoadHook.TestCaseId.SHARING_ON_CFLH_OFF);
+
+        TestCommon.checkExec(out);
+
+
+        // Now, run with AppCDS with -Xshare:auto and CFLH
+        out = TestCommon.execAuto("-cp", appJar,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI", useWb,
+                "-agentlib:SimpleClassFileLoadHook=LoadMe,beforeHook,after_Hook",
+                "ClassFileLoadHook",
+                "" + ClassFileLoadHook.TestCaseId.SHARING_AUTO_CFLH_ON);
+
+        CDSOptions opts = (new CDSOptions()).setXShareMode("auto");
+        TestCommon.checkExec(out, opts);
+
+        // Now, run with AppCDS -Xshare:on and CFLH
+        out = TestCommon.exec(appJar,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI", useWb,
+                "-agentlib:SimpleClassFileLoadHook=LoadMe,beforeHook,after_Hook",
+                "ClassFileLoadHook",
+                "" + ClassFileLoadHook.TestCaseId.SHARING_ON_CFLH_ON);
+        TestCommon.checkExec(out);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationAgent.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Premain-Class: InstrumentationRegisterClassFileTransformer
+Agent-Class: InstrumentationRegisterClassFileTransformer
+Can-Retransform-Classes: true
+Can-Redefine-Classes: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.UnmodifiableClassException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.io.File;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import sun.hotspot.WhiteBox;
+
+public class InstrumentationApp {
+    static WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static final String COO_CLASS_NAME = "InstrumentationApp$Coo";
+
+    public static interface Intf {            // Loaded from Boot class loader (-Xbootclasspath/a).
+        public String get();
+    }
+    public static class Bar implements Intf { // Loaded from Boot class loader.
+        public String get() {
+            // The initial transform:
+            //      change "buzz" -> "fuzz"
+            // The re-transform:
+            //      change "buzz" -> "guzz"
+            return "buzz";
+        }
+    }
+    public static class Foo implements Intf { // Loaded from AppClassLoader, or from a custom loader
+        public String get() {
+            // The initial transform:
+            //      change "buzz" -> "fuzz"
+            // The re-transform:
+            //      change "buzz" -> "guzz"
+            return "buzz";
+        }
+    }
+    public static class Coo implements Intf { // Loaded from custom class loader.
+        public String get() {
+            // The initial transform:
+            //      change "buzz" -> "fuzz"
+            // The re-transform:
+            //      change "buzz" -> "guzz"
+            return "buzz";
+        }
+    }
+
+    // This class file should be archived if AppCDSv2 is enabled on this platform. See
+    // the comments around the call to TestCommon.dump in InstrumentationTest.java.
+    public static class ArchivedIfAppCDSv2Enabled {}
+
+    public static boolean isAppCDSV2Enabled() {
+        return wb.isSharedClass(ArchivedIfAppCDSv2Enabled.class);
+    }
+
+    public static class MyLoader extends URLClassLoader {
+        public MyLoader(URL[] urls, ClassLoader parent, File jar) {
+            super(urls, parent);
+            this.jar = jar;
+        }
+        File jar;
+
+        @Override
+        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            synchronized (getClassLoadingLock(name)) {
+                // First, check if the class has already been loaded
+                Class<?> clz = findLoadedClass(name);
+                if (clz != null) {
+                    return clz;
+                }
+
+                if (name.equals(COO_CLASS_NAME)) {
+                    try {
+                        byte[] buff = Util.getClassFileFromJar(jar, name);
+                        return defineClass(name, buff, 0, buff.length);
+                    } catch (Throwable t) {
+                        t.printStackTrace();
+                        throw new RuntimeException("Unexpected", t);
+                    }
+                }
+            }
+            return super.loadClass(name, resolve);
+        }
+    }
+
+    static int numTests = 0;
+    static int failed = 0;
+    static boolean isAttachingAgent = false;
+    static Instrumentation instrumentation;
+
+    public static void main(String args[]) throws Throwable {
+        System.out.println("INFO: AppCDSv1 " + (wb.isSharedClass(InstrumentationApp.class) ? "enabled" :"disabled"));
+        System.out.println("INFO: AppCDSv2 " + (isAppCDSV2Enabled()                        ? "enabled" : "disabled"));
+
+        File bootJar = new File(args[0]);
+        File appJar  = new File(args[1]);
+        File custJar = new File(args[2]);
+        String flagFile = args[3];
+        waitAttach(flagFile);
+
+        instrumentation = InstrumentationRegisterClassFileTransformer.getInstrumentation();
+        System.out.println("INFO: instrumentation = " + instrumentation);
+
+        testBootstrapCDS("Bootstrap Loader", bootJar);
+        testAppCDSv1("Application Loader", appJar);
+
+        if (isAppCDSV2Enabled()) {
+          testAppCDSv2("Custom Loader (unregistered)", custJar);
+        }
+
+        if (failed > 0) {
+            throw new RuntimeException("FINAL RESULT: " + failed + " out of " + numTests + " test case(s) have failed");
+        } else {
+            System.out.println("FINAL RESULT: All " + numTests + " test case(s) have passed!");
+        }
+    }
+
+    static void waitAttach(String flagFile) throws Throwable {
+        if (!flagFile.equals("noattach")) {
+            File f = new File(flagFile);
+            long start = System.currentTimeMillis();
+            while (f.exists()) {
+                long elapsed = System.currentTimeMillis() - start;
+                System.out.println(".... (" + elapsed + ") waiting for deletion of " + f);
+                Thread.sleep(1000);
+            }
+            System.out.println("Attach succeeded (child)");
+            isAttachingAgent = true;
+        }
+    }
+
+    static void testBootstrapCDS(String group, File jar) throws Throwable {
+        doTest(group, new Bar(), jar);
+    }
+
+    static void testAppCDSv1(String group, File jar) throws Throwable {
+        doTest(group, new Foo(), jar);
+    }
+
+    static void testAppCDSv2(String group, File jar) throws Throwable {
+        URL[] urls = new URL[] {jar.toURI().toURL()};
+        MyLoader loader = new MyLoader(urls, InstrumentationApp.class.getClassLoader(), jar);
+        Class klass = loader.loadClass(COO_CLASS_NAME);
+        doTest(group, (Intf)klass.newInstance(), jar);
+    }
+
+    static void doTest(String group, Intf object, File jar) throws Throwable {
+        Class klass = object.getClass();
+        System.out.println();
+        System.out.println("++++++++++++++++++++++++++");
+        System.out.println("Test group: " + group);
+        System.out.println("Testing with classloader = " + klass.getClassLoader());
+        System.out.println("Testing with class       = " + klass);
+        System.out.println("++++++++++++++++++++++++++");
+
+        // Initial transform
+        String f = object.get();
+        assertTrue(f.equals("fuzz"), "object.get(): Initial transform should give 'fuzz'", f);
+
+        // Retransform
+        f = "(failed)";
+        try {
+            instrumentation.retransformClasses(klass);
+            f = object.get();
+        } catch (UnmodifiableClassException|UnsupportedOperationException e) {
+            e.printStackTrace();
+        }
+        assertTrue(f.equals("guzz"), "object.get(): retransformation should give 'guzz'", f);
+
+        // Redefine
+        byte[] buff = Util.getClassFileFromJar(jar, klass.getName());
+        Util.replace(buff, "buzz", "huzz");
+        f = "(failed)";
+        try {
+            instrumentation.redefineClasses(new ClassDefinition(klass, buff));
+            f = object.get();
+        } catch (UnmodifiableClassException|UnsupportedOperationException e) {
+            e.printStackTrace();
+        }
+        assertTrue(f.equals("quzz"), "object.get(): redefinition should give 'quzz'", f);
+
+        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++ (done)\n\n");
+    }
+
+    private static void assertTrue(boolean expr, String msg, String string) {
+        numTests ++;
+        System.out.printf("Test case %2d ", numTests);
+
+        if (expr) {
+            System.out.println("PASSED: " + msg + " and we got '" + string + "'");
+        } else {
+            failed ++;
+            System.out.println("FAILED: " + msg + " but we got '" + string + "'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationClassFileTransformer.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+// Note: Util is from /test/hotspot/jtreg/runtime/appcds/test-classes/TestCommon.java
+
+public class InstrumentationClassFileTransformer implements ClassFileTransformer {
+    public byte[] transform(ClassLoader loader, String name, Class<?> classBeingRedefined,
+                            ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException {
+
+        if (name.startsWith("InstrumentationApp$") && !name.equals("InstrumentationApp$NotTransformed")) {
+            System.out.println("Transforming: " + name + " class = " + classBeingRedefined);
+            try {
+                if (classBeingRedefined == null) {
+                    // Initial transform
+                    replace(buffer, "buzz", "fuzz");
+                } else {
+                    replace(buffer, "buzz", "guzz"); // Retransform
+                    replace(buffer, "huzz", "quzz"); // Redefine
+                }
+            } catch (Throwable t) {
+                t.printStackTrace();
+            }
+            return buffer;
+        }
+        return null;
+    }
+
+    static void replace(byte[] buffer, String from, String to) {
+        int n = Util.replace(buffer, from, to);
+        System.out.println("..... replaced " + n + " occurrence(s) of '" + from + "' to '" + to + "'");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationRegisterClassFileTransformer.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.Instrumentation;
+
+// This class is available on the classpath so it can be accessed by InstrumentationApp
+public class InstrumentationRegisterClassFileTransformer {
+    private static Instrumentation savedInstrumentation;
+
+    public static void premain(String agentArguments, Instrumentation instrumentation) {
+        System.out.println("InstrumentationRegisterClassFileTransformer.premain() is called");
+        instrumentation.addTransformer(new InstrumentationClassFileTransformer(), /*canRetransform=*/true);
+        savedInstrumentation = instrumentation;
+    }
+
+    public static Instrumentation getInstrumentation() {
+        return savedInstrumentation;
+    }
+
+    public static void agentmain(String args, Instrumentation inst) throws Exception {
+        premain(args, inst);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Exercise the java.lang.instrument.Instrumentation APIs on classes archived
+ *          using CDS/AppCDSv1/AppCDSv2.
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ * @build sun.hotspot.WhiteBox
+ *        InstrumentationApp
+ *        InstrumentationClassFileTransformer
+ *        InstrumentationRegisterClassFileTransformer
+ * @run main/othervm InstrumentationTest
+ */
+
+// Note: TestCommon is from /test/hotspot/jtreg/runtime/appcds/TestCommon.java
+// Note: Util       is from /test/hotspot/jtreg/runtime/appcds/test-classes/TestCommon.java
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.VirtualMachineDescriptor;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class InstrumentationTest {
+    public static String bootClasses[] = {
+        "InstrumentationApp$Intf",
+        "InstrumentationApp$Bar",
+        "sun.hotspot.WhiteBox",
+    };
+    public static String appClasses[] = {
+        "InstrumentationApp",
+        "InstrumentationApp$Foo",
+        "InstrumentationApp$MyLoader",
+    };
+    public static String custClasses[] = {
+        "InstrumentationApp$Coo",
+    };
+    public static String sharedClasses[] = TestCommon.concat(bootClasses, appClasses);
+
+    public static String agentClasses[] = {
+        "InstrumentationClassFileTransformer",
+        "InstrumentationRegisterClassFileTransformer",
+        "Util",
+    };
+
+    public static void main(String[] args) throws Throwable {
+        runTest(false);
+        runTest(true);
+    }
+
+    public static void runTest(boolean attachAgent) throws Throwable {
+        String bootJar =
+            ClassFileInstaller.writeJar("InstrumentationBoot.jar", bootClasses);
+        String appJar =
+            ClassFileInstaller.writeJar("InstrumentationApp.jar",
+                                        TestCommon.concat(appClasses,
+                                                          "InstrumentationApp$ArchivedIfAppCDSv2Enabled"));
+        String custJar =
+            ClassFileInstaller.writeJar("InstrumentationCust.jar", custClasses);
+        String agentJar =
+            ClassFileInstaller.writeJar("InstrumentationAgent.jar",
+                                        ClassFileInstaller.Manifest.fromSourceFile("InstrumentationAgent.mf"),
+                                        agentClasses);
+
+        String bootCP = "-Xbootclasspath/a:" + bootJar;
+
+        System.out.println("");
+        System.out.println("============================================================");
+        System.out.println("CDS: NO, attachAgent: " + (attachAgent ? "YES" : "NO"));
+        System.out.println("============================================================");
+        System.out.println("");
+
+        String agentCmdArg, flagFile;
+        if (attachAgent) {
+            // we will attach the agent, so don't specify -javaagent in the command line. We'll use
+            // something harmless like -showversion to make it easier to construct the command line
+            agentCmdArg = "-showversion";
+        } else {
+            agentCmdArg = "-javaagent:" + agentJar;
+        }
+
+        // First, run the test class directly, w/o sharing, as a baseline reference
+        flagFile = getFlagFile(attachAgent);
+        AgentAttachThread t = doAttach(attachAgent, flagFile, agentJar);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                bootCP,
+                "-cp", appJar,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-Xshare:off",
+                agentCmdArg,
+                "InstrumentationApp", bootJar, appJar, custJar, flagFile);
+        TestCommon.executeAndLog(pb, "no-sharing").shouldHaveExitValue(0);
+        checkAttach(t);
+
+        // Dump the AppCDS archive. On some platforms AppCDSv2 may not be enabled, so we
+        // first try the v2 classlist, and if that fails, revert to the v1 classlist.
+        // Note that the InstrumentationApp$ArchivedIfAppCDSv2Enabled class is archived
+        // only if V2 is enabled. This is tested by InstrumentationApp.isAppCDSV2Enabled().
+        String[] v2Classes = {
+            "InstrumentationApp$ArchivedIfAppCDSv2Enabled",
+            "java/lang/Object id: 0",
+            "InstrumentationApp$Intf id: 1",
+            "InstrumentationApp$Coo  id: 2 super: 0 interfaces: 1 source: " + custJar,
+        };
+        String[] sharedClassesWithV2 = TestCommon.concat(v2Classes, sharedClasses);
+        OutputAnalyzer out = TestCommon.dump(appJar, sharedClassesWithV2, bootCP);
+        if (out.getExitValue() != 0) {
+            System.out.println("Redumping with AppCDSv2 disabled");
+                TestCommon.testDump(appJar, sharedClasses, bootCP);
+        }
+
+        // Run with AppCDS.
+        System.out.println("");
+        System.out.println("============================================================");
+        System.out.println("CDS: YES, attachAgent: " + (attachAgent ? "YES" : "NO"));
+        System.out.println("============================================================");
+        System.out.println("");
+
+        flagFile = getFlagFile(attachAgent);
+        t = doAttach(attachAgent, flagFile, agentJar);
+        out = TestCommon.execAuto("-cp", appJar,
+                bootCP,
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                agentCmdArg,
+               "InstrumentationApp", bootJar, appJar, custJar, flagFile);
+
+        CDSOptions opts = (new CDSOptions()).setXShareMode("auto");
+        TestCommon.checkExec(out, opts);
+        checkAttach(t);
+    }
+
+    static int flagFileSerial = 1;
+    static private String getFlagFile(boolean attachAgent) {
+        if (attachAgent) {
+            // Do not reuse the same file name as Windows may fail to
+            // delete the file.
+            return "attach.flag." + ProcessHandle.current().pid() +
+                    "." + (flagFileSerial++) + "." + System.currentTimeMillis();
+        } else {
+            return "noattach";
+        }
+    }
+
+    static AgentAttachThread doAttach(boolean attachAgent, String flagFile, String agentJar) throws Throwable {
+        if (!attachAgent) {
+            return null;
+        }
+
+        // We use the flagFile to prevent the child process to make progress, until we have
+        // attached to it.
+        File f = new File(flagFile);
+        FileOutputStream o = new FileOutputStream(f);
+        o.write(1);
+        o.close();
+        if (!f.exists()) {
+            throw new RuntimeException("Failed to create " + f);
+        }
+
+        // At this point, the child process is not yet launched. Note that
+        // TestCommon.exec() and OutputAnalyzer.OutputAnalyzer() both block
+        // until the child process has finished.
+        //
+        // So, we will launch a AgentAttachThread which will poll the system
+        // until the child process is launched, and then do the attachment.
+        // The child process is uniquely identified by having flagFile in its
+        // command-line -- see AgentAttachThread.getPid().
+        AgentAttachThread t = new AgentAttachThread(flagFile, agentJar);
+        t.start();
+        return t;
+    }
+
+    static void checkAttach(AgentAttachThread thread) throws Throwable {
+        if (thread != null) {
+            thread.check();
+        }
+    }
+
+    static class AgentAttachThread extends Thread {
+        String flagFile;
+        String agentJar;
+        volatile boolean succeeded;
+
+        AgentAttachThread(String flagFile, String agentJar) {
+            this.flagFile = flagFile;
+            this.agentJar = agentJar;
+            this.succeeded = false;
+        }
+
+        static String getPid(String flagFile) throws Throwable {
+            while (true) {
+                // Keep polling until the child process has been launched. If for some
+                // reason the child process fails to launch, this test will be terminated
+                // by JTREG's time-out mechanism.
+                Thread.sleep(100);
+                List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
+                for (VirtualMachineDescriptor vmd : vmds) {
+                    if (vmd.displayName().contains(flagFile) && vmd.displayName().contains("InstrumentationApp")) {
+                        // We use flagFile (which has the PID of this process) as a unique identifier
+                        // to ident the child process, which we want to attach to.
+                        System.out.println("Process found: " + vmd.id() + " " + vmd.displayName());
+                        return vmd.id();
+                    }
+                }
+            }
+        }
+
+        public void run() {
+            try {
+                String pid = getPid(flagFile);
+                VirtualMachine vm = VirtualMachine.attach(pid);
+                System.out.println(agentJar);
+                vm.loadAgent(agentJar);
+            } catch (Throwable t) {
+                t.printStackTrace();
+                throw new RuntimeException(t);
+            }
+
+            // Delete the flagFile to indicate to the child process that we
+            // have attached to it, so it should proceed.
+            File f = new File(flagFile);
+            for (int i=0; i<5; i++) {
+                // The detele may fail on Windows if the child JVM is checking
+                // f.exists() at exactly the same time?? Let's do a little
+                // dance.
+                f.delete();
+                try {
+                    Thread.sleep(10);
+                } catch (Throwable t) {;}
+            }
+            if (f.exists()) {
+                throw new RuntimeException("Failed to delete " + f);
+            }
+            System.out.println("Attach succeeded (parent)");
+            succeeded = true;
+        }
+
+        void check() throws Throwable {
+            super.join();
+            if (!succeeded) {
+                throw new RuntimeException("Attaching agent to child VM failed");
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/parallelLoad/ParallelClassesTransform.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+class ParallelClassTr0  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr1  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr2  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr3  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr4  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr5  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr6  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr7  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr8  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr9  { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr10 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr11 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr12 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr13 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr14 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr15 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr16 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr17 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr18 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr19 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr20 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr21 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr22 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr23 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr24 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr25 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr26 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr27 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr28 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr29 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr30 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr31 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr32 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr33 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr34 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr35 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr36 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr37 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr38 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+class ParallelClassTr39 { public static String testString = ParallelClassesTransform.BEFORE_PATTERN; }
+
+class ParallelClassesTransform {
+    public static final int NUMBER_OF_CLASSES = 40;
+    public static final String BEFORE_PATTERN = "class-transform-check: this-should-be-transformed";
+    public static final String AFTER_PATTERN =  "class-transform-check: this-has-been--transformed";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/parallelLoad/ParallelLoadAndTransformTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Load app classes from CDS archive in parallel threads,
+ * use initial transformation (CFLH)
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ *     /test/hotspot/jtreg/runtime/appcds/test-classes /test/hotspot/jtreg/runtime/appcds/jvmti
+ *     /test/hotspot/jtreg/testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ *          java.instrument
+ * @build TransformUtil TransformerAgent ParallelLoad
+ * @run main ParallelLoadAndTransformTest
+ */
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class ParallelLoadAndTransformTest {
+
+    public static void main(String[] args) throws Exception {
+        String prop = "-Dappcds.parallel.transform.mode=cflh";
+        String appJar = ClassFileInstaller.writeJar("parallel_load.jar",
+                            getClassList(true));
+        String agentJar = prepareAgent();
+
+        TestCommon.test(appJar, getClassList(false),
+                        "-javaagent:" + agentJar + "=ParallelClassTr.*",
+                        prop, "ParallelLoad");
+    }
+
+
+    private static String[] getClassList(boolean includeWatchdog) {
+        List<String> classList =
+            IntStream.range(0, ParallelClassesTransform.NUMBER_OF_CLASSES)
+            .mapToObj(i -> "ParallelClassTr" + i)
+            .collect(Collectors.toList());
+
+        classList.add("ParallelLoad");
+        classList.add("ParallelLoadThread");
+        if (includeWatchdog)
+            classList.add("ParallelLoadWatchdog");
+
+        return classList.toArray(new String[0]);
+    }
+
+
+    // Agent is the same for all test cases
+    private static String prepareAgent() throws Exception {
+        String agentClasses[] = {
+            "TransformerAgent",
+            "TransformerAgent$SimpleTransformer",
+            "TransformUtil"
+        };
+
+        String manifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
+
+        return ClassFileInstaller.writeJar("TransformerAgent.jar",
+            ClassFileInstaller.Manifest.fromSourceFile(manifest),
+                                        agentClasses);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformInterfaceImplementorAppCDS.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Exercise initial transformation (class file loader hook)
+ *  with CDS/AppCDS with Interface/Implementor pair
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ *     /test/hotspot/jtreg/runtime/appcds/jvmti /test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability
+ *     /test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses
+ *     /test/hotspot/jtreg/runtime/SharedArchiveFile /test/hotspot/jtreg/testlibrary/jvmti
+ *     /test/hotspot/jtreg/runtime/appcds/customLoader
+ *     /test/hotspot/jtreg/runtime/appcds/customLoader/test-classes
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent Interface Implementor
+ * @run main/othervm TransformRelatedClassesAppCDS Interface Implementor
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+// Structure of the test:
+// TransformRelatedClassesAppCDS -- common main test driver
+// Invoked from test driver classes:
+//     TransformInterfaceAndImplementor, TransformSuperAndSubClasses.java
+//     prepares test artifacts, launches tests, checks results
+// SuperClazz, SubClass -- classes under test
+// Interface, Implementor -- classes under test
+// TransformerAgent -- an agent that is used when JVM-under-test is executed
+//     to transform specific strings inside specified classes
+// TransformerAgent.mf - accompanies transformer agent
+// CustomLoaderApp -- a test "application" that is used to load
+//     classes-under-test (Parent, Child) via custom class loader, using
+//     AppCDS-v2 mechanism (unregistered custom loaders, aka FP)
+//     This "app" is launched in a child process by this driver with sharing on.
+
+import java.io.File;
+import java.util.ArrayList;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+// This class is intended to test 2 parent-child relationships:
+// 1. Base Class (parent) and Derived Class (child)
+// 2. Interface (parent) and Implementor (child)
+//    Parameters to main(): parent, child
+
+public class TransformRelatedClassesAppCDS extends TransformRelatedClasses {
+    private static void log(String msg, Object... args) {
+        String msg0 = String.format(msg, args);
+        System.out.println("TransformRelatedClassesAppCDS: " + msg0);
+    }
+
+    // Initial Test Matrix:
+    // (ParentTransformed = true/false, ChildTransformed = true/false) x
+    // (BootCDS - see open tests, AppCDS-v1, AppCDS-v2-unregistered)
+    // Total cases: 2 x 4 = 8
+    public static void main(String args[]) throws Exception {
+        TransformRelatedClassesAppCDS test =
+            new TransformRelatedClassesAppCDS(args[0], args[1]);
+
+        test.prepareAgent(agentClasses);
+
+        // Test Table
+        // testCaseId |  transformParent | tranformChild | isParentExpectedShared | isChildExpectedShared
+        ArrayList<TestEntry> testTable = new ArrayList<>();
+
+        // base case - no tranformation - all expected to be shared
+        testTable.add(new TestEntry(0, false, false, true, true));
+
+        // transform parent only - both parent and child should not be shared
+        testTable.add(new TestEntry(1, true, false, false, false));
+
+        // transform parent and child - both parent and child should not be shared
+        testTable.add(new TestEntry(2, true, true, false, false));
+
+        // transform child only - parent should still be shared, but not child
+        testTable.add(new TestEntry(3, false, true, true, false));
+
+        // run the tests
+        test.runWithAppLoader(testTable);
+        test.runWithCustomLoader(testTable);
+    }
+
+
+    public TransformRelatedClassesAppCDS(String parent, String child) {
+        super(parent, child);
+
+        // a trick to get it compiled by jtreg
+        CustomLoaderApp.ping();
+    }
+
+
+    private void prepareAgent(String[] agentClasses) throws Exception {
+        String manifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
+        agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar",
+                   ClassFileInstaller.Manifest.fromSourceFile(manifest),
+                                           agentClasses);
+    }
+
+
+    private void runWithAppLoader(ArrayList<TestEntry> testTable) throws Exception {
+        String appJar = writeJar("app", testClasses);
+
+        // create an archive
+        OutputAnalyzer out = TestCommon.dump(appJar, testClasses);
+        TestCommon.checkDump(out);
+
+        // execute with archive
+        for (TestEntry entry : testTable) {
+            log("runTestWithAppLoader(): testCaseId = %d", entry.testCaseId);
+            String params = TransformTestCommon.getAgentParams(entry, parent, child);
+            String agentParam = String.format("-javaagent:%s=%s", agentJar, params);
+            out = TestCommon.execCommon("-Xlog:class+load=info", "-cp", appJar,
+                                        agentParam, child);
+
+            TransformTestCommon.checkResults(entry, out, parent, child);
+        }
+    }
+
+
+    private String[] getCustomClassList(String loaderType, String customJar) {
+        String type = child + "-" + loaderType;
+
+        switch (type) {
+
+        case "SubClass-unregistered":
+            return new String[] {
+                "CustomLoaderApp",
+                "java/lang/Object id: 0",
+                parent + " id: 1 super: 0 source: " + customJar,
+                child +  " id: 2 super: 1 source: " + customJar,
+            };
+
+        case "Implementor-unregistered":
+            return new String[] {
+                "CustomLoaderApp",
+                "java/lang/Object id: 0",
+                parent + " id: 1 super: 0 source: " + customJar,
+                child +  " id: 2 super: 0 interfaces: 1 source: " + customJar,
+            };
+
+        default:
+            throw new IllegalArgumentException("getCustomClassList - wrong type: " + type);
+        }
+    }
+
+
+    private void runWithCustomLoader(ArrayList<TestEntry> testTable) throws Exception {
+        if (!Platform.areCustomLoadersSupportedForCDS()) {
+            log("custom loader not supported for this platform" +
+                " - skipping test case for custom loader");
+            return;
+        }
+
+        String appClasses[] = {
+            "CustomLoaderApp",
+        };
+
+        String customClasses[] = { parent, child };
+
+        // create jar files: appJar, customJar (for custom loaders to load classes from)
+        String appJar = writeJar("custldr-app", appClasses);
+        String customJar = writeJar("custldr-custom", customClasses);
+
+        for (TestEntry entry : testTable) {
+            log("runTestWithCustomLoader(): testCaseId = %d", entry.testCaseId);
+            // unregistered (aka FP) case
+            String[] classList = getCustomClassList("unregistered",customJar);
+            execAndCheckWithCustomLoader(entry, "unregistered", classList,
+                                         appJar, agentJar, customJar);
+        }
+    }
+
+
+    private void
+        execAndCheckWithCustomLoader(TestEntry entry, String loaderType,
+                                     String[] classList, String appJar,
+                                     String agentJar, String customJar)
+        throws Exception {
+
+        OutputAnalyzer out = TestCommon.dump(appJar, classList);
+        TestCommon.checkDump(out);
+
+        String agentParam = "-javaagent:" + agentJar + "=" +
+            TransformTestCommon.getAgentParams(entry, parent, child);
+
+        out = TestCommon.execCommon("-Xlog:class+load=info",
+                                    "-cp", appJar,
+                                    "--add-opens=java.base/java.security=ALL-UNNAMED",
+                                    agentParam,
+                                    "CustomLoaderApp",
+                                    customJar, loaderType, child);
+        TransformTestCommon.checkResults(entry, out, parent, child);
+    }
+
+
+    private String writeJar(String type, String[] classes)
+        throws Exception {
+        String jarName = String.format("%s-%s.jar", child, type);
+        return ClassFileInstaller.writeJar(jarName, classes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformSuperSubAppCDS.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Exercise initial transformation (class file loader hook)
+ *  with CDS/AppCDS with SubClass and SuperClass
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ *     /test/hotspot/jtreg/runtime/appcds/jvmti /test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability
+ *     /test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses
+ *     /test/hotspot/jtreg/runtime/SharedArchiveFile /test/hotspot/jtreg/testlibrary/jvmti
+ *     /test/hotspot/jtreg/runtime/appcds/customLoader
+ *     /test/hotspot/jtreg/runtime/appcds/customLoader/test-classes
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent SubClass SuperClazz
+ * @run main/othervm TransformRelatedClassesAppCDS SuperClazz SubClass
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasic.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class RedefineBasic {
+
+    public static String newB =
+        " class RedefineBasic$B { " +
+        " public static void okToCallBeforeRedefine() { " +
+        "    throw new RuntimeException(\"newB: okToCallBeforeRedefine is " +
+        "    called after redefinition, test failed\"); }" +
+        " public static void okToCallAfterRedefine() { " +
+        "     System.out.println(\"newB: okToCallAfterRedefine\"); } " +
+        " } ";
+
+
+    static class B {
+        public static void okToCallBeforeRedefine() {
+            System.out.println("okToCallBeforeRedefine");
+        }
+        public static void okToCallAfterRedefine() {
+            throw new RuntimeException(
+            "okToCallAfterRedefine is called before redefinition, test failed");
+        }
+    }
+
+    static class SubclassOfB extends B {
+        public static void testAfterRedefine() {
+            B.okToCallAfterRedefine();
+        }
+    }
+
+    class Subclass2OfB extends B {
+        public void testAfterRedefine() {
+            super.okToCallAfterRedefine();
+        }
+    }
+
+    // verify that a given class is shared, report error if necessary
+    public static void
+    verifyClassIsShared(WhiteBox wb, Class c) throws Exception {
+        if (!wb.isSharedClass(c)) {
+            throw new RuntimeException(
+            "This class should be shared but isn't: " + c.getName());
+        } else {
+            System.out.println("The class is shared as expected: " +
+                c.getName());
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        verifyClassIsShared(wb, RedefineBasic.class);
+        verifyClassIsShared(wb, B.class);
+        verifyClassIsShared(wb, SubclassOfB.class);
+        verifyClassIsShared(wb, Subclass2OfB.class);
+
+        // (1) Test case: verify that original B works as expected
+        // and that redefined B is shared and works as expected,
+        // with new behavior
+        B.okToCallBeforeRedefine();
+        RedefineClassHelper.redefineClass(B.class, newB);
+        verifyClassIsShared(wb, B.class);
+        B.okToCallAfterRedefine();
+
+        // Static subclass of the super:
+        // 1. Make sure it is still shared
+        // 2. and it calls the correct super (the redefined one)
+        verifyClassIsShared(wb, SubclassOfB.class);
+        SubclassOfB.testAfterRedefine();
+
+        // Same as above, but for non-static class
+        verifyClassIsShared(wb, Subclass2OfB.class);
+        RedefineBasic thisTest = new RedefineBasic();
+        thisTest.testSubclass2OfB();
+    }
+
+    public void testSubclass2OfB() {
+        Subclass2OfB sub = new Subclass2OfB();
+        sub.testAfterRedefine();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasicTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Run /runtime/RedefineTests/RedefineRunningMethods in AppCDS mode to
+ *          make sure class redefinition works with CDS.
+ *          (Note: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/RedefineTests /test/hotspot/jtreg/runtime/appcds
+ * @modules java.compiler
+ *          java.instrument
+ *          jdk.jartool/sun.tools.jar
+ *          java.base/jdk.internal.misc
+ *          java.management
+ * @run main RedefineClassHelper
+ * @build sun.hotspot.WhiteBox RedefineBasic
+ * @run main RedefineBasicTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RedefineBasicTest {
+    public static String sharedClasses[] = {
+        "RedefineBasic",
+        "RedefineBasic$B",
+        "RedefineBasic$SubclassOfB",
+        "RedefineBasic$Subclass2OfB",
+        "RedefineClassHelper",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String wbJar =
+            ClassFileInstaller.writeJar("WhiteBox.jar", "sun.hotspot.WhiteBox");
+        String appJar =
+            ClassFileInstaller.writeJar("RedefineBasic.jar", sharedClasses);
+        String useWb = "-Xbootclasspath/a:" + wbJar;
+
+        OutputAnalyzer output;
+        TestCommon.testDump(appJar, sharedClasses, useWb);
+
+        // redefineagent.jar is created by executing "@run main RedefineClassHelper"
+        // which should be called before executing RedefineBasicTest
+        output = TestCommon.exec(appJar, useWb,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 "-javaagent:redefineagent.jar",
+                                 "RedefineBasic");
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineRunningMethods_Shared.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Run /runtime/RedefineTests/RedefineRunningMethods in AppCDS mode to
+ *          make sure class redefinition works with CDS.
+ *          (Note: AppCDS does not support uncompressed oops)
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @library /test/lib /test/hotspot/jtreg/runtime/RedefineTests /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.compiler
+ *          java.instrument
+ *          jdk.jartool/sun.tools.jar
+ * @run main RedefineClassHelper
+ * @build sun.hotspot.WhiteBox RedefineRunningMethods_SharedHelper
+ * @run main RedefineRunningMethods_Shared
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RedefineRunningMethods_Shared {
+    public static String shared_classes[] = {
+        "RedefineRunningMethods_Shared",
+        "RedefineRunningMethods_SharedHelper",
+        "RedefineRunningMethods",
+        "RedefineRunningMethods$1",
+        "RedefineRunningMethods$2",
+        "RedefineRunningMethods$3",
+        "RedefineRunningMethods$B",
+        "RedefineClassHelper",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper$1",
+        "jdk/test/lib/compiler/InMemoryJavaCompiler$MemoryJavaFileObject"
+    };
+
+    public static void main(String[] args) throws Exception {
+        String wbJar = ClassFileInstaller.writeJar("WhiteBox.jar", "sun.hotspot.WhiteBox");
+        String appJar = ClassFileInstaller.writeJar("RedefineRunningMethods_Shared.jar", shared_classes);
+        String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
+
+        OutputAnalyzer output;
+        TestCommon.testDump(appJar, shared_classes,
+                            // command-line arguments ...
+                            use_whitebox_jar);
+
+        // RedefineRunningMethods.java contained this:
+        // @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace RedefineRunningMethods
+        output = TestCommon.exec(appJar,
+                                 // command-line arguments ...
+                                 use_whitebox_jar,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 // These arguments are expected by RedefineRunningMethods
+                                 "-javaagent:redefineagent.jar",
+                                 "-Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace",
+                                 "RedefineRunningMethods_SharedHelper");
+        TestCommon.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineRunningMethods_SharedHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+/**
+ * This class is executed by RedefineRunningMethods_Shared.java in
+ * a sub-process.
+ */
+public class RedefineRunningMethods_SharedHelper {
+    public static void main(String[] args) throws Exception {
+        // (1) Validate that all classes used by RedefineRunningMethods are all shared.
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        for (String name : RedefineRunningMethods_Shared.shared_classes) {
+            name = name.replace('/', '.');
+            Class c = Class.forName(name);
+            if (!wb.isSharedClass(c)) {
+                throw new RuntimeException("Test set-up problem. " +
+                           "This class should be shared but isn't: " + name);
+            } else {
+                System.out.println("The class is shared as expected: " + name);
+            }
+        }
+
+        // (2) Run the class redefinition test.
+        RedefineRunningMethods.main(args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/ExerciseGC.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Exercise GC with shared strings
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloStringGC sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main ExerciseGC
+ */
+public class ExerciseGC {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJarAndWhiteBox("HelloStringGC");
+
+        SharedStringsUtils.dumpWithWhiteBox(TestCommon.list("HelloStringGC"),
+            "SharedStringsBasic.txt");
+
+        SharedStringsUtils.runWithArchiveAndWhiteBox("HelloStringGC",
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyBeforeGC");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/ExtraSharedInput.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,7 @@
+VERSION: 1.0
+@SECTION: Symbol
+0 -1: 
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+11 -1: linkMethod 
+18 -1: type can't be null
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/FlagCombo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test relevant combinations of command line flags with shared strings
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @run main FlagCombo
+ */
+
+import jdk.test.lib.BuildHelper;
+
+public class FlagCombo {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJar("HelloString");
+
+        SharedStringsUtils.dump(TestCommon.list("HelloString"),
+            "SharedStringsBasic.txt");
+
+        SharedStringsUtils.runWithArchive("HelloString", "-XX:+UseG1GC");
+
+        if (BuildHelper.isCommercialBuild()) {
+            SharedStringsUtils.runWithArchiveAuto("HelloString", "-XX:+UnlockCommercialFeatures",
+                "-XX:StartFlightRecording=dumponexit=true");
+        }
+
+        SharedStringsUtils.runWithArchive("HelloString", "-XX:+UnlockDiagnosticVMOptions",
+           "-XX:NativeMemoryTracking=detail", "-XX:+PrintNMTStatistics");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/HelloString.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class HelloString {
+    public static void main(String args[]) {
+        // Let's reference the string that is in the archive
+        // Make sure the string below is in the shared string data file (string list)
+        String testString = "shared_test_string_unique_14325";
+        System.out.println("Hello String: " + testString);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/HelloStringGC.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class HelloStringGC {
+    public static String[] array01 = new String[1000];
+    public static String[] array02 = new String[1000];
+
+    public static void main(String args[]) throws RuntimeException {
+        String testString1 = "shared_test_string_unique_14325";
+        String testString2 = "test123";
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (!wb.isShared(testString1) && !wb.areSharedStringsIgnored()) {
+            throw new RuntimeException("testString1 is not shared");
+        }
+
+        for (int i=0; i<5; i++) {
+            allocSomeStrings(testString1, testString2);
+            array01 = null;
+            array02 = null;
+            System.gc();
+            sleep(300);
+            array01 = new String[1000];
+            array02 = new String[1000];
+        }
+
+        wb.fullGC();
+
+        System.out.println("HelloStringGC: PASS");
+    }
+
+    private static void allocSomeStrings(String s1, String s2) {
+        for (int i = 0; i < 1000; i ++) {
+            array01[i] = new String(s1);
+            array02[i] = new String(s2);
+        }
+    }
+
+    private static void sleep(int ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/HelloStringPlus.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+// A test class to be launched in AppCDS mode, has basic+
+// coverage of string operations
+
+import sun.hotspot.WhiteBox;
+
+public class HelloStringPlus {
+    public static void main(String args[]) {
+        // Let's reference the string that is in archive
+        String testString1 = "shared_test_string_unique_14325";
+        System.out.println("Hello String: " + testString1);
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (!wb.isShared(testString1) && !wb.areSharedStringsIgnored()) {
+            throw new RuntimeException("testString1 is not shared");
+        }
+
+        // Check other basic string operations
+        // Interning and equality
+        String[] testArray = new String[] {"shared_", "test_", "string_", "intern_", "12345"};
+        String toBeInterned = "";
+
+        StringBuilder sb = new StringBuilder();
+        for (String s : testArray) {
+            sb.append(s);
+        }
+        toBeInterned = sb.toString();
+
+        System.out.println("About to intern a string: " + toBeInterned);
+        toBeInterned.intern();
+
+        // check equality
+        if (testString1.equals(toBeInterned))
+            throw new RuntimeException("Equality test 1 failed");
+
+        if (!testString1.equals("shared_test_string" + '_' + "unique_14325"))
+            throw new RuntimeException("Equality test 2 failed");
+
+        // Chech the hash code functionality; no special assertions, just make sure
+        // no crashe or exception occurs
+        System.out.println("testString1.hashCode() = " + testString1.hashCode());
+
+        // Check intern() method for "" string
+        String empty = "";
+        String empty_interned = empty.intern();
+        if (wb.isShared(empty)) {
+           throw new RuntimeException("Empty string should not be shared");
+        }
+        if (empty_interned != empty) {
+            throw new RuntimeException("Different string is returned from intern() for empty string");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/IncompatibleOptions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test options that are incompatible with use of shared strings
+ *          Also test mismatch in oops encoding between dump time and run time
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires (vm.gc=="null")
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @run main IncompatibleOptions
+ */
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class IncompatibleOptions {
+    static final String COOPS_DUMP_WARNING =
+        "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off";
+    static final String COOPS_EXEC_WARNING =
+        "UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces";
+    static final String GC_WARNING =
+        "Archived java heap is not supported";
+    static final String OBJ_ALIGNMENT_MISMATCH =
+        "The shared archive file's ObjectAlignmentInBytes of .* does not equal the current ObjectAlignmentInBytes of";
+    static final String COMPACT_STRING_MISMATCH =
+        "The shared archive file's CompactStrings setting .* does not equal the current CompactStrings setting";
+
+    static String appJar;
+
+    public static void main(String[] args) throws Exception {
+        appJar = JarBuilder.build("IncompatibleOptions", "HelloString");
+
+        // Uncompressed OOPs
+        testDump(1, "-XX:+UseG1GC", "-XX:-UseCompressedOops", COOPS_DUMP_WARNING, true);
+
+        // incompatible GCs
+        testDump(2, "-XX:+UseParallelGC", "", GC_WARNING, false);
+        testDump(3, "-XX:+UseSerialGC", "", GC_WARNING, false);
+        testDump(4, "-XX:+UseConcMarkSweepGC", "", GC_WARNING, false);
+
+        // ======= archive with compressed oops, run w/o
+        testDump(5, "-XX:+UseG1GC", "-XX:+UseCompressedOops", null, false);
+        testExec(5, "-XX:+UseG1GC", "-XX:-UseCompressedOops",
+                 COOPS_EXEC_WARNING, true);
+
+        // NOTE: No warning is displayed, by design
+        // Still run, to ensure no crash or exception
+        testExec(6, "-XX:+UseParallelGC", "", "", false);
+        testExec(7, "-XX:+UseSerialGC", "", "", false);
+        testExec(8, "-XX:+UseConcMarkSweepGC", "", "", false);
+
+        // Test various oops encodings, by varying ObjectAlignmentInBytes and heap sizes
+        testDump(9, "-XX:+UseG1GC", "-XX:ObjectAlignmentInBytes=8", null, false);
+        testExec(9, "-XX:+UseG1GC", "-XX:ObjectAlignmentInBytes=16",
+                 OBJ_ALIGNMENT_MISMATCH, true);
+
+        // See JDK-8081416 - Oops encoding mismatch with shared strings
+        // produces unclear or incorrect warning
+        // Correct the test case once the above is fixed
+        // @ignore JDK-8081416 - for tracking purposes
+        // for now, run test as is until the proper behavior is determined
+        testDump(10, "-XX:+UseG1GC", "-Xmx1g", null, false);
+        testExec(10, "-XX:+UseG1GC", "-Xmx32g", null, true);
+
+        // CompactStrings must match between dump time and run time
+        testDump(11, "-XX:+UseG1GC", "-XX:-CompactStrings", null, false);
+        testExec(11, "-XX:+UseG1GC", "-XX:+CompactStrings",
+                 COMPACT_STRING_MISMATCH, true);
+        testDump(12, "-XX:+UseG1GC", "-XX:+CompactStrings", null, false);
+        testExec(12, "-XX:+UseG1GC", "-XX:-CompactStrings",
+                 COMPACT_STRING_MISMATCH, true);
+    }
+
+    static void testDump(int testCaseNr, String collectorOption, String extraOption,
+        String expectedWarning, boolean expectedToFail) throws Exception {
+
+        System.out.println("Testcase: " + testCaseNr);
+        OutputAnalyzer output = TestCommon.dump(appJar, TestCommon.list("Hello"),
+            "-XX:+UseCompressedOops",
+            collectorOption,
+            "-XX:SharedArchiveConfigFile=" + TestCommon.getSourceFile("SharedStringsBasic.txt"),
+            extraOption);
+
+        if (expectedWarning != null)
+            output.shouldContain(expectedWarning);
+
+        if (expectedToFail) {
+            Asserts.assertNE(output.getExitValue(), 0,
+            "JVM is expected to fail, but did not");
+        }
+    }
+
+    static void testExec(int testCaseNr, String collectorOption, String extraOption,
+        String expectedWarning, boolean expectedToFail) throws Exception {
+
+        OutputAnalyzer output;
+        System.out.println("Testcase: " + testCaseNr);
+
+        // needed, otherwise system considers empty extra option as a
+        // main class param, and fails with "Could not find or load main class"
+        if (!extraOption.isEmpty()) {
+            output = TestCommon.exec(appJar, "-XX:+UseCompressedOops",
+                collectorOption, extraOption, "HelloString");
+        } else {
+            output = TestCommon.exec(appJar, "-XX:+UseCompressedOops",
+                collectorOption, "HelloString");
+        }
+
+        if (expectedWarning != null)
+            output.shouldMatch(expectedWarning);
+
+        if (expectedToFail)
+            Asserts.assertNE(output.getExitValue(), 0);
+        else
+            SharedStringsUtils.checkExec(output);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InternSharedString.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test shared strings together with string intern operation
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile InternStringTest.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main InternSharedString
+ */
+
+public class InternSharedString {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJarAndWhiteBox("InternStringTest");
+
+        SharedStringsUtils.dumpWithWhiteBox(TestCommon.list("InternStringTest"),
+            "ExtraSharedInput.txt");
+
+        String[] extraMatches = new String[]   {
+            InternStringTest.passed_output1,
+            InternStringTest.passed_output2,
+            InternStringTest.passed_output3  };
+
+        SharedStringsUtils.runWithArchiveAndWhiteBox(extraMatches, "InternStringTest");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InternStringTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class InternStringTest {
+    public static String passed_output1 = "Found shared string.";
+    public static String passed_output2 = "Shared strings are equal.";
+    public static String passed_output3 = "Found shared string containing latin1 supplement chars.";
+    public static String passed_output4 = "Found shared string containing non-western chars.";
+    public static final String latin1Sup  = "XXXX \u00a3 YYYY"; // \u00a3 = The pound sign
+    public static final String nonWestern = "XXXX \u5678 YYYY"; // \u5678 = Unicode Han Character 'ton (metric or English)'
+
+    public static void main(String[] args) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        // All string literals are shared.
+        String shared1 = "LiveOak";
+        String interned1 = shared1.intern();
+        if (wb.areSharedStringsIgnored() || wb.isShared(interned1)) {
+            System.out.println(passed_output1);
+        } else {
+            throw new RuntimeException("Failed: String is not shared.");
+        }
+
+        // Test 2: shared_string1.intern() == shared_string2.intern()
+        String shared2 = "LiveOak";
+        String interned2 = shared2.intern();
+        if (interned1 == interned2) {
+            System.out.println(passed_output2);
+        } else {
+            throw new RuntimeException("Not equal!");
+        }
+
+        // Test 3: interned strings with a char in latin1 supplement block [\u0080-\u00ff]
+        {
+            String a = "X" + latin1Sup.substring(1);
+            String b = a.intern();
+
+            if (wb.areSharedStringsIgnored() || wb.isShared(b)) {
+                System.out.println(passed_output3);
+            } else {
+                throw new RuntimeException("Failed: expected shared string with latin1-supplement chars.");
+            }
+        }
+
+        // Test 5: interned strings with non-western characters
+        {
+            String a = "X" + nonWestern.substring(1);
+            String b = a.intern();
+            if (wb.areSharedStringsIgnored() || wb.isShared(b)) {
+                System.out.println(passed_output4);
+            } else {
+                throw new RuntimeException("Failed: expected shared string with non-western chars.");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Check most common errors in file format
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @run main InvalidFileFormat
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import java.io.File;
+
+// Checking most common error use cases
+// This file is not an exhastive test of various shared data file corruption
+// Note on usability intent: the shared data file is created and handled by
+// the previledge person in the server environment.
+public class InvalidFileFormat {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJar("HelloString");
+
+        test("NonExistentFile.txt", "Unable to get hashtable dump file size");
+        test("InvalidHeader.txt", "wrong version of hashtable dump file");
+        test("InvalidVersion.txt", "wrong version of hashtable dump file");
+        test("CorruptDataLine.txt", "Unknown data type. Corrupted at line 2");
+        test("InvalidSymbol.txt", "Unexpected character. Corrupted at line 2");
+        test("InvalidSymbolFormat.txt", "Unrecognized format. Corrupted at line 9");
+        test("OverflowPrefix.txt", "Num overflow. Corrupted at line 4");
+        test("UnrecognizedPrefix.txt", "Unrecognized format. Corrupted at line 5");
+        test("TruncatedString.txt", "Truncated. Corrupted at line 3");
+    }
+
+    private static void
+        test(String dataFileName, String expectedWarning) throws Exception {
+        System.out.println("Filename for testcase: " + dataFileName);
+
+        OutputAnalyzer out = SharedStringsUtils.dumpWithoutChecks(TestCommon.list("HelloString"),
+                                 "invalidFormat" + File.separator + dataFileName);
+
+        if (!TestCommon.isUnableToMap(out))
+            out.shouldContain(expectedWarning).shouldHaveExitValue(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LargePages.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Basic shared string test with large pages
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @run main LargePages
+ */
+public class LargePages {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJar("HelloString");
+
+        SharedStringsUtils.dump(TestCommon.list("HelloString"),
+            "SharedStringsBasic.txt", "-XX:+UseLargePages");
+        SharedStringsUtils.runWithArchive("HelloString", "-XX:+UseLargePages");
+
+        SharedStringsUtils.dump(TestCommon.list("HelloString"),
+            "SharedStringsBasic.txt",
+            "-XX:+UseLargePages", "-XX:+UseLargePagesInMetaspace");
+        SharedStringsUtils.runWithArchive("HelloString",
+            "-XX:+UseLargePages", "-XX:+UseLargePagesInMetaspace");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockSharedStrings.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test locking on shared strings
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile LockStringTest.java LockStringValueTest.java
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main LockSharedStrings
+ */
+
+public class LockSharedStrings {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJarAndWhiteBox("LockStringTest", "LockStringValueTest");
+
+        SharedStringsUtils.dumpWithWhiteBox(
+            TestCommon.list("LockStringTest", "LockStringValueTest"),
+            "ExtraSharedInput.txt");
+
+        String[] extraMatch = new String[] {"LockStringTest: PASS"};
+        SharedStringsUtils.runWithArchiveAndWhiteBox(extraMatch, "LockStringTest");
+
+        extraMatch = new String[] {"LockStringValueTest: PASS"};
+        SharedStringsUtils.runWithArchiveAndWhiteBox(extraMatch, "LockStringValueTest",
+            "--add-opens=java.base/java.lang=ALL-UNNAMED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockStringTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class LockStringTest extends Thread {
+    static String lock = "StringLock";
+    static boolean done = false;
+
+    public static void main(String[] args) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (wb.areSharedStringsIgnored()) {
+            System.out.println("The shared strings are ignored");
+            System.out.println("LockStringTest: PASS");
+            return;
+        }
+
+        if (!wb.isShared(lock)) {
+            throw new RuntimeException("Failed: String is not shared.");
+        }
+
+        new LockStringTest().start();
+
+        synchronized(lock) {
+            while (!done) {
+                lock.wait();
+            }
+        }
+        System.gc();
+        System.out.println("LockStringTest: PASS");
+    }
+
+    public void run() {
+        String shared = "LiveOak";
+        synchronized (lock) {
+            for (int i = 0; i < 100; i++) {
+                new String(shared);
+                System.gc();
+                try {
+                    sleep(5);
+                } catch (InterruptedException e) {}
+            }
+            done = true;
+            lock.notify();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockStringValueTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.lang.reflect.*;
+import sun.hotspot.WhiteBox;
+
+/*
+ * Lock the 'value' field of a known shared string, java.lang.Object
+ */
+public class LockStringValueTest {
+    public static void main(String args[]) {
+        String s = "LiveOak";
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        if (wb.areSharedStringsIgnored()) {
+            System.out.println("The shared strings are ignored");
+            System.out.println("LockStringValueTest: PASS");
+            return;
+        }
+
+        if (!wb.isShared(s)) {
+            throw new RuntimeException("LockStringValueTest Failed: String is not shared.");
+        }
+
+        Class c = s.getClass();
+        try {
+            Field f = c.getDeclaredField("value");
+            f.setAccessible(true);
+            Object v = f.get(s);
+            lock(v);
+        } catch (NoSuchFieldException nfe) {
+        } catch (IllegalAccessException iae) {}
+    }
+
+    public static void lock(Object o) {
+        synchronized (o) {
+            System.out.println("LockStringValueTest: PASS");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Basic test for shared strings
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @run main SharedStringsBasic
+ */
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+// This test does not use SharedStringsUtils intentionally:
+// - in order to demonstrate the basic use of the functionality
+// - to provide sanity check and catch potential problems in the utils
+public class SharedStringsBasic {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.build("SharedStringsBasic", "HelloString");
+
+        String sharedArchiveConfigFile =
+            TestCommon.getSourceFile("SharedStringsBasic.txt").toString();
+
+        ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
+            "-XX:+UseAppCDS",
+            "-XX:+UseCompressedOops",
+            "-XX:+UseG1GC",
+            "-cp", appJar,
+            "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile,
+            "-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
+            "-Xshare:dump",
+            "-Xlog:cds,cds+hashtables");
+
+        TestCommon.executeAndLog(dumpPb, "dump")
+            .shouldContain("Shared string table stats")
+            .shouldHaveExitValue(0);
+
+        ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
+            "-XX:+UseAppCDS",
+            "-XX:+UseCompressedOops",
+            "-XX:+UseG1GC",
+            "-cp", appJar,
+            "-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
+            "-Xshare:auto",
+            "-showversion",
+            "HelloString");
+
+        TestCommon.executeAndLog(runPb, "run").shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+VERSION: 1.0
+@SECTION: String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+1: *
+1: -
+1: .
+1: /
+1: :
+1: C
+1: I
+1: J
+1: U
+1: Z
+1: _
+8: segments
+1: |
+5: cp850
+5: cp852
+5: cp855
+5: cp857
+5: cp858
+5: cp862
+5: cp866
+11: ISO_8859_13
+11: ISO_8859_15
+5: cp874
+47: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+7: CHECKED
+3: zip
+10: waitStatus
+33: java.lang.invoke.MethodHandleImpl
+7: .jimage
+5: cp912
+5: cp914
+5: cp915
+5: cp920
+5: cp923
+5: cp936
+5: euccn
+5: eucjp
+11: permissions
+5: euckr
+6: SIGNAL
+5: cp737
+17: java.library.path
+5: cp775
+13: classValueMap
+4: utf8
+9: PROPAGATE
+9: baseCount
+7: cskoi8r
+8: cyrillic
+@SECTION: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasicPlus.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Basic plus test for shared strings
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build HelloStringPlus sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main SharedStringsBasicPlus
+ */
+
+public class SharedStringsBasicPlus {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJarAndWhiteBox("HelloStringPlus");
+
+        SharedStringsUtils.dumpWithWhiteBox( TestCommon.list("HelloStringPlus"),
+            "SharedStringsBasic.txt");
+
+        SharedStringsUtils.runWithArchiveAndWhiteBox("HelloStringPlus");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Write a lots of shared strings.
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @run main SharedStringsStress
+ */
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class SharedStringsStress {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.build("SharedStringsStress", "HelloString");
+
+        String sharedArchiveConfigFile = System.getProperty("user.dir") + File.separator + "SharedStringsStress_gen.txt";
+        try (FileOutputStream fos = new FileOutputStream(sharedArchiveConfigFile)) {
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(fos));
+            out.println("VERSION: 1.0");
+            out.println("@SECTION: String");
+            out.println("31: shared_test_string_unique_14325");
+            for (int i=0; i<100000; i++) {
+                String s = "generated_string " + i;
+                out.println(s.length() + ": " + s);
+            }
+            out.close();
+        }
+
+        // Set NewSize to 8m due to dumping could fail in hs-tier6 testing with
+        // the vm options: -XX:+UnlockCommercialFeatures -XX:+UseDeterministicG1GC
+        // resulting in vm initialization error:
+        // "GC triggered before VM initialization completed. Try increasing NewSize, current value 1331K."
+        OutputAnalyzer dumpOutput = TestCommon.dump(appJar, TestCommon.list("HelloString"), "-XX:NewSize=8m",
+                                                    "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile);
+        TestCommon.checkDump(dumpOutput);
+        OutputAnalyzer execOutput = TestCommon.exec(appJar, "HelloString");
+        TestCommon.checkExec(execOutput);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsUtils.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+
+// A helper/utility class for testing shared strings
+public class SharedStringsUtils {
+    public static final String TEST_JAR_NAME =      "test";
+    public static final String TEST_JAR_NAME_FULL = "test.jar";
+    public static final String WHITEBOX_JAR_NAME =  "whitebox";
+
+    public static String getWbParam() {
+        return "-Xbootclasspath/a:" + TestCommon.getTestJar(WHITEBOX_JAR_NAME + ".jar");
+    }
+
+    // build the test jar
+    public static void buildJar(String... classes) throws Exception {
+        JarBuilder.build(TEST_JAR_NAME, classes);
+    }
+
+    // build the test jar and a whitebox jar
+    public static void buildJarAndWhiteBox(String... classes) throws Exception {
+        JarBuilder.build(true, WHITEBOX_JAR_NAME, "sun/hotspot/WhiteBox");
+        buildJar(classes);
+    }
+
+    // execute the "dump" operation, but do not check the output
+    public static OutputAnalyzer dumpWithoutChecks(String appClasses[],
+        String sharedDataFile, String... extraOptions) throws Exception {
+
+        String appJar = TestCommon.getTestJar(TEST_JAR_NAME_FULL);
+        String[] args =
+            TestCommon.concat(extraOptions, "-XX:+UseCompressedOops", "-XX:+UseG1GC",
+            "-XX:SharedArchiveConfigFile=" +
+            TestCommon.getSourceFile(sharedDataFile));
+
+        return TestCommon.dump(appJar, appClasses, args);
+    }
+
+    // execute the dump operation and check the output
+    public static OutputAnalyzer dump(String appClasses[],
+        String sharedDataFile, String... extraOptions) throws Exception {
+        OutputAnalyzer output = dumpWithoutChecks(appClasses, sharedDataFile, extraOptions);
+        checkDump(output);
+        return output;
+    }
+
+    public static OutputAnalyzer dumpWithWhiteBox(String appClasses[],
+        String sharedDataFile, String... extraOptions) throws Exception {
+        return dump(appClasses, sharedDataFile,
+            TestCommon.concat(extraOptions, getWbParam()) );
+    }
+
+    // execute/run test with shared archive
+    public static OutputAnalyzer runWithArchiveAuto(String className,
+        String... extraOptions) throws Exception {
+
+        String appJar = TestCommon.getTestJar(TEST_JAR_NAME_FULL);
+        String[] args = TestCommon.concat(extraOptions,
+            "-cp", appJar, "-XX:+UseCompressedOops", "-XX:+UseG1GC", className);
+
+        OutputAnalyzer output = TestCommon.execAuto(args);
+        checkExecAuto(output);
+        return output;
+    }
+
+    public static OutputAnalyzer runWithArchive(String className,
+        String... extraOptions) throws Exception {
+
+        return runWithArchive(new String[0], className, extraOptions);
+    }
+
+    public static OutputAnalyzer runWithArchive(String[] extraMatches,
+        String className, String... extraOptions) throws Exception {
+
+        String appJar = TestCommon.getTestJar(TEST_JAR_NAME_FULL);
+        String[] args = TestCommon.concat(extraOptions,
+            "-XX:+UseCompressedOops", "-XX:+UseG1GC", className);
+
+        OutputAnalyzer output = TestCommon.exec(appJar, args);
+        checkExec(output, extraMatches);
+        return output;
+    }
+
+
+    // execute/run test with shared archive and white box
+    public static OutputAnalyzer runWithArchiveAndWhiteBox(String className,
+        String... extraOptions) throws Exception {
+
+        return runWithArchive(className,
+            TestCommon.concat(extraOptions, getWbParam(),
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI") );
+    }
+
+    public static OutputAnalyzer runWithArchiveAndWhiteBox(String[] extraMatches,
+        String className, String... extraOptions) throws Exception {
+
+        return runWithArchive(extraMatches, className,
+            TestCommon.concat(extraOptions, getWbParam(),
+            "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI") );
+    }
+
+
+    public static void checkDump(OutputAnalyzer output) throws Exception {
+        output.shouldContain("Shared string table stats");
+        TestCommon.checkDump(output);
+    }
+
+    public static void checkExec(OutputAnalyzer output) throws Exception {
+        TestCommon.checkExec(output, new String[0]);
+    }
+
+    public static void checkExecAuto(OutputAnalyzer output) throws Exception {
+        CDSOptions opts = (new CDSOptions()).setXShareMode("auto");
+        TestCommon.checkExec(output, opts);
+    }
+
+    public static void checkExec(OutputAnalyzer output, String[] extraMatches) throws Exception {
+        TestCommon.checkExec(output, extraMatches);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsWb.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class SharedStringsWb {
+    public static void main(String[] args) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        String s = "shared_test_string_unique_14325";
+        s = s.intern();
+        if (wb.areSharedStringsIgnored() || wb.isShared(s)) {
+            System.out.println("Found shared string.");
+        } else {
+            throw new RuntimeException("String is not shared.");
+        }
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsWbTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary White box test for shared strings
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ *          jdk.jartool/sun.tools.jar
+ * @build sun.hotspot.WhiteBox SharedStringsWb
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main SharedStringsWbTest
+ */
+
+import java.io.*;
+import sun.hotspot.WhiteBox;
+
+public class SharedStringsWbTest {
+    public static void main(String[] args) throws Exception {
+        SharedStringsUtils.buildJarAndWhiteBox("SharedStringsWb");
+
+        SharedStringsUtils.dumpWithWhiteBox(TestCommon.list("SharedStringsWb"),
+            "SharedStringsBasic.txt");
+
+        SharedStringsUtils.runWithArchiveAndWhiteBox("SharedStringsWb");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+/*
+ * @test
+ * @summary Regression test for JDK-8098821
+ * @bug 8098821
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ * @modules java.management
+ * @run main SysDictCrash
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class SysDictCrash {
+    public static void main(String[] args) throws Exception {
+        // SharedBaseAddress=0 puts the archive at a very high address on solaris,
+        // which provokes the crash.
+        ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
+            "-XX:+UseG1GC", "-XX:MaxRAMPercentage=12.5",
+            "-XX:+UseAppCDS",
+            "-cp", ".",
+            "-XX:SharedBaseAddress=0", "-XX:SharedArchiveFile=./SysDictCrash.jsa",
+            "-Xshare:dump",
+            "-showversion", "-Xlog:cds,cds+hashtables");
+
+        TestCommon.checkDump(TestCommon.executeAndLog(dumpPb, "dump"));
+
+        ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
+            "-XX:+UseG1GC", "-XX:MaxRAMPercentage=12.5",
+            "-XX:+UseAppCDS",
+            "-XX:SharedArchiveFile=./SysDictCrash.jsa",
+            "-Xshare:on",
+            "-version");
+
+        TestCommon.checkExec(TestCommon.executeAndLog(runPb, "exec"));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/CorruptDataLine.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+VERSION: 1.0
+SECTION: String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+1: *
+1: -
+1: .
+1: /
+1: :
+1: C
+1: I
+1: J
+1: U
+1: Z
+1: _
+8: segments
+1: |
+5: cp850
+5: cp852
+5: cp855
+5: cp857
+5: cp858
+5: cp862
+5: cp866
+11: ISO_8859_13
+11: ISO_8859_15
+5: cp874
+47: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+7: CHECKED
+3: zip
+10: waitStatus
+33: java.lang.invoke.MethodHandleImpl
+7: .jimage
+5: cp912
+5: cp914
+5: cp915
+5: cp920
+5: cp923
+5: cp936
+5: euccn
+5: eucjp
+11: permissions
+5: euckr
+6: SIGNAL
+5: cp737
+17: java.library.path
+5: cp775
+13: classValueMap
+4: utf8
+9: PROPAGATE
+9: baseCount
+7: cskoi8r
+8: cyrillic
+#DATATYPE: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidDataType.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+VERSION: 1.0
+@SECTION: String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+1: *
+1: -
+1: .
+1: /
+1: :
+1: C
+1: I
+1: J
+1: U
+1: Z
+1: _
+8: segments
+1: |
+5: cp850
+5: cp852
+5: cp855
+5: cp857
+5: cp858
+5: cp862
+5: cp866
+11: ISO_8859_13
+11: ISO_8859_15
+5: cp874
+47: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+7: CHECKED
+3: zip
+10: waitStatus
+33: java.lang.invoke.MethodHandleImpl
+7: .jimage
+5: cp912
+5: cp914
+5: cp915
+5: cp920
+5: cp923
+5: cp936
+5: euccn
+5: eucjp
+11: permissions
+5: euckr
+6: SIGNAL
+5: cp737
+17: java.library.path
+5: cp775
+13: classValueMap
+4: utf8
+9: PROPAGATE
+9: baseCount
+7: cskoi8r
+8: cyrillic
+#DATATYPE: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidHeader.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+Garbage Header x0935#%0sl
+@SECTION: String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+1: *
+1: -
+1: .
+1: /
+1: :
+1: C
+1: I
+1: J
+1: U
+1: Z
+1: _
+8: segments
+1: |
+5: cp850
+5: cp852
+5: cp855
+5: cp857
+5: cp858
+5: cp862
+5: cp866
+11: ISO_8859_13
+11: ISO_8859_15
+5: cp874
+47: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+7: CHECKED
+3: zip
+10: waitStatus
+33: java.lang.invoke.MethodHandleImpl
+7: .jimage
+5: cp912
+5: cp914
+5: cp915
+5: cp920
+5: cp923
+5: cp936
+5: euccn
+5: eucjp
+11: permissions
+5: euckr
+6: SIGNAL
+5: cp737
+17: java.library.path
+5: cp775
+13: classValueMap
+4: utf8
+9: PROPAGATE
+9: baseCount
+7: cskoi8r
+8: cyrillic
+#DATATYPE: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidString.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,6 @@
+VERSION: 1.0
+@SECTION: String
+31: shred_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidStringFormat.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+VERSION: 1.0
+@SECTION: String
+0: 
+5:: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+1: *
+1: -
+1: .
+1: /
+1: :
+1: C
+1: I
+1: J
+1: U
+1: Z
+1: _
+8: segments
+1: |
+5: cp850
+5: cp852
+5: cp855
+5: cp857
+5: cp858
+5: cp862
+5: cp866
+11: ISO_8859_13
+11: ISO_8859_15
+5: cp874
+47: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+7: CHECKED
+3: zip
+10: waitStatus
+33: java.lang.invoke.MethodHandleImpl
+7: .jimage
+5: cp912
+5: cp914
+5: cp915
+5: cp920
+5: cp923
+5: cp936
+5: euccn
+5: eucjp
+11: permissions
+5: euckr
+6: SIGNAL
+5: cp737
+17: java.library.path
+5: cp775
+13: classValueMap
+4: utf8
+9: PROPAGATE
+9: baseCount
+7: cskoi8r
+8: cyrillic
+#DATATYPE: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidSymbol.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,12 @@
+VERSION: 1.0
+@SECTION:  String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+8: cyrillic
+@SECTION:  Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMet%%%hod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidSymbolFormat.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,11 @@
+VERSION: 1.0
+@SECTION: String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+@SECTION: Symbol
+41: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/InvalidVersion.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,60 @@
+VERSION: 0.0
+@SECTION: String
+0: 
+5: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+1: *
+1: -
+1: .
+1: /
+1: :
+1: C
+1: I
+1: J
+1: U
+1: Z
+1: _
+8: segments
+1: |
+5: cp850
+5: cp852
+5: cp855
+5: cp857
+5: cp858
+5: cp862
+5: cp866
+11: ISO_8859_13
+11: ISO_8859_15
+5: cp874
+47: java.lang.invoke.MethodHandle.TRACE_INTERPRETER
+7: CHECKED
+3: zip
+10: waitStatus
+33: java.lang.invoke.MethodHandleImpl
+7: .jimage
+5: cp912
+5: cp914
+5: cp915
+5: cp920
+5: cp923
+5: cp936
+5: euccn
+5: eucjp
+11: permissions
+5: euckr
+6: SIGNAL
+5: cp737
+17: java.library.path
+5: cp775
+13: classValueMap
+4: utf8
+9: PROPAGATE
+9: baseCount
+7: cskoi8r
+8: cyrillic
+#DATATYPE: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/OverflowPrefix.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,11 @@
+VERSION: 1.0
+@SECTION: String
+0: 
+2147483648: cp819
+31: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+@SECTION: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/TruncatedString.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,10 @@
+VERSION: 1.0
+@SECTION: String
+2147483647: s
+5: cp819
+31: shared_test_string_intern_12345
+7: test123
+@SECTION: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/UnrecognizedPrefix.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,11 @@
+VERSION: 1.0
+@SECTION: String
+0: 
+5: cp819
+3E: shared_test_string_unique_14325
+31: shared_test_string_intern_12345
+7: test123
+@SECTION: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ArrayListTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+import java.util.*;
+
+// This is a test case executed by DumpClassList.java to load classes
+// from various places to ensure that they are not written to the class list.
+public class ArrayListTest {
+    public static void main(String args[]) throws Exception {
+        // The following lambda usage should generate various classes like
+        // java.lang.invoke.LambdaForm$MH/1146743572. All of them should be excluded from
+        // the class list.
+        List<String> a = new ArrayList<>();
+        a.add("hello world.");
+        a.forEach(str -> System.out.println(str));
+
+        System.out.println(Class.forName("java.lang.NewClass")); // should be excluded from the class list.
+        System.out.println(Class.forName("boot.append.Foo"));    // should be excluded from the class list.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/BootClassPathAppendHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class BootClassPathAppendHelper {
+    public static void main(String[] args) throws ClassNotFoundException {
+        Class cls = Class.forName("Hello");
+
+        if (cls == null) {
+            throw new java.lang.RuntimeException("Cannot find Hello.class");
+        }
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (!wb.isSharedClass(cls)) {
+            System.out.println("Hello.class is not in shared space as expected.");
+        } else {
+            throw new java.lang.RuntimeException("Hello.class shouldn't be in shared space.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/C1.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 2017, 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 sealed.pkg;
+
+public class C1 {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/C2.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 2017, 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 pkg;
+
+public class C2 {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/CheckIfShared.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class CheckIfShared {
+  public static void main(String args[]) throws Exception {
+    WhiteBox wb = WhiteBox.getWhiteBox();
+    if ("true".equals(args[0])) {
+      if (!wb.isSharedClass(CheckIfShared.class)) {
+        throw new RuntimeException("wb.isSharedClass(CheckIfShared.class) should be true");
+      }
+    } else {
+      if (wb.isSharedClass(CheckIfShared.class)) {
+        throw new RuntimeException("wb.isSharedClass(CheckIfShared.class) should be false");
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Child.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class Child extends Super {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/CpAttr1.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class CpAttr1 {
+  public static void main(String args[]) {
+    System.out.println("2"); CpAttr2.doit(); // Only the version of this class defined in CpAttr2.java will not throw exception.
+    System.out.println("3"); CpAttr3.doit(); // Only the version of this class defined in CpAttr3.java will not throw exception.
+    System.out.println("4"); CpAttr4.doit(); // Only the version of this class defined in CpAttr4.java will not throw exception.
+    System.out.println("5"); CpAttr5.doit(); // Only the version of this class defined in CpAttr5.java will not throw exception.
+    System.out.println("Test passed");
+  }
+}
+
+class CpAttr2 { static void doit() {throw new RuntimeException("");} }
+class CpAttr3 { static void doit() {throw new RuntimeException("");} }
+class CpAttr4 { static void doit() {throw new RuntimeException("");} }
+class CpAttr5 { static void doit() {throw new RuntimeException("");} }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/CpAttr2.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+class CpAttr2 { static void doit() {} }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/CpAttr3.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+class CpAttr2 { static void doit() {throw new RuntimeException("");} }
+class CpAttr3 { static void doit() {} }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/CpAttr4.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+class CpAttr2 { static void doit() {throw new RuntimeException("");} }
+class CpAttr3 { static void doit() {throw new RuntimeException("");} }
+class CpAttr4 { static void doit() {} }
+class CpAttr5 { static void doit() {throw new RuntimeException("");} }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/CpAttr5.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+class CpAttr5 { static void doit() {} }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/DummyClassHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.lang.*;
+import java.lang.reflect.*;
+import sun.hotspot.WhiteBox;
+
+public class DummyClassHelper {
+    public static void main(String[] args) throws Exception {
+        String[] classNames = {args[0], args[1]};
+        Class cls = null;
+        if (args.length == 2) {
+            for (int i = 0; i < classNames.length; i++) {
+                Method m = null;
+                cls = Class.forName(classNames[i]);
+                try {
+                    m = cls.getMethod("thisClassIsDummy");
+                    throw new java.lang.RuntimeException(classNames[i] +
+                        " should be loaded from the jimage and should not have the thisClassIsDummy() method.");
+                } catch(NoSuchMethodException ex) {
+                    System.out.println(ex.toString());
+                }
+            }
+        } else {
+            WhiteBox wb = WhiteBox.getWhiteBox();
+            for (int i = 0; i < classNames.length; i++) {
+                cls = Class.forName(classNames[i]);
+                if (!wb.isSharedClass(cls)) {
+                    System.out.println(classNames[i] + ".class" + " is not in shared space as expected.");
+                } else {
+                    throw new java.lang.RuntimeException(classNames[i] +
+                        ".class shouldn't be in shared space.");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/EmptyClassHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.lang.*;
+import java.lang.reflect.*;
+import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.misc.SharedSecrets;
+
+class EmptyClassHelper {
+    static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+    static final String USE_APP = "useAppLoader";
+    public static void main(String[] args) throws Exception {
+        Class cls = null;
+        Method m = null;
+        ClassLoader appLoader = ClassLoader.getSystemClassLoader();
+        String className = "com.sun.tools.javac.Main";
+        if (args[0].equals(USE_APP)) {
+            cls = appLoader.loadClass(className);
+            System.out.println("appLoader loaded class");
+            try {
+                m = cls.getMethod("main", String[].class);
+                System.out.println("appLoader found method main");
+            } catch(NoSuchMethodException ex) {
+                System.out.println(ex.toString());
+            }
+        } else {
+            cls = jla.findBootstrapClassOrNull(appLoader, className);
+            System.out.println("bootLoader loaded class");
+            System.out.println("cls = " + cls);
+            try {
+                m = cls.getMethod("main", String[].class);
+                System.out.println("bootLoader found method main");
+            } catch(NoSuchMethodException ex) {
+                System.out.println(ex.toString());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/FieldAnnotationsApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+public class FieldAnnotationsApp {
+    @MyAnnotation(name="myField1",  value="myValue1")
+    public String myField1 = null;
+
+    @MyAnnotation(name="myField2",  value="myValue2")
+    public String myField2 = null;
+
+    public static void main(String args[]) throws Exception {
+        for (int i=1; i<=2; i++) {
+            Field field = FieldAnnotationsApp.class.getField("myField" + i);
+            Annotation[] annotations = field.getDeclaredAnnotations();
+
+            for (Annotation anno : annotations){
+                if (anno instanceof MyAnnotation){
+                    MyAnnotation myAnno = (MyAnnotation) anno;
+                    String name = myAnno.name();
+                    String value = myAnno.value();
+
+                    System.out.println("Field         : " + field.getName());
+                    System.out.println("  myAnno.name : " + name);
+                    System.out.println("  myAnno.value: " + value);
+
+                    if (!(name.equals("myField" + i) && value.equals("myValue" + i))) {
+                        throw new Exception("Unexpected annotation values: " + i + " = " + value);
+                    }
+                }
+            }
+        }
+        System.out.println("Field annotations are OK.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ForNameTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class ForNameTest {
+    public static void main(String[] args) throws Throwable {
+        // Hello is on the bootclasspath. The defining classloader is
+        // the NULL classloader. See AppCDSClassLoaderTest.
+        Class c = Class.forName("Hello");
+        ClassLoader cl = c.getClassLoader();
+        if (cl != null) {
+            throw new RuntimeException(
+                "Test Failed. Wrong classloader is used. Expect the NULL classloader.");
+        }
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (!wb.isSharedClass(c)) {
+            System.out.println("As expected, Hello.class is not in shared space.");
+        } else {
+            throw new java.lang.RuntimeException("Hello.class shouldn't be in shared space.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Greet.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class Greet {
+
+    public String Greeting() {
+        return new String(", how are you?");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Hello.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class Hello {
+  public static void main(String args[]) {
+    System.out.println("Hello World");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/HelloExt.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class HelloExt {
+   public static void main(String[] args) throws Throwable {
+
+       String className = "org.omg.CORBA.ORB";
+       Class cls = Class.forName(className);
+
+       ClassLoader loader = cls.getClassLoader();
+       if (loader != ClassLoader.getPlatformClassLoader()) {
+           throw new java.lang.RuntimeException(className + " should be load by PlatformClassLoader but it is loaded by " + loader);
+       }
+
+       WhiteBox wb = WhiteBox.getWhiteBox();
+       if (wb.isSharedClass(cls)) {
+           System.out.println("As expected, " + className + " is in shared space.");
+       } else {
+           throw new java.lang.RuntimeException(className + " is not in shared space.");
+       }
+
+       className = "[Ljava.lang.Comparable;";
+       cls = Class.forName(className);
+       loader = cls.getClassLoader();
+       if (loader != null) {
+           throw new java.lang.RuntimeException(className + " should be load by the NULL class loader but it is loaded by " + loader);
+       }
+
+       if (wb.isSharedClass(cls)) {
+           System.out.println("As expected, " + className + " is in shared space.");
+       } else {
+           throw new java.lang.RuntimeException(className + " is not in shared space.");
+       }
+   }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/HelloExtApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class HelloExtApp {
+  public static void main(String args[]) {
+    System.out.println("Hello World Ext: " + HelloExtExt.class.getProtectionDomain());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/HelloExtExt.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class HelloExtExt {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/HelloMore.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class HelloMore {
+  public static void main(String args[]) {
+      Hello.main(args);
+      System.out.println("Hello World ... More");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/HelloWB.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class HelloWB {
+    public static void main(String[] args) throws Throwable {
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (wb.isSharedClass(HelloWB.class)) {
+            System.out.println("As expected, HelloWB.class is in shared space.");
+        } else {
+            throw new java.lang.RuntimeException("HelloWB.class should be in shared space.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Hi.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class Hi extends Greet {
+    public static void main(String args[]) {
+        Greet g = new Greet();
+        MyClass.doit(g.Greeting());
+    }
+    public static class MyClass {
+        public static void doit(String greeting) {
+            System.out.println("Hi" + greeting);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Iloadw.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class Iloadw 
+    version 51: 0
+{
+    public static Method run:"()I"
+        stack 1 locals 400
+    {
+        iconst_0;
+        istore_w 300;
+        iinc_w 300,1;
+        iload_w 300;
+        ireturn;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/IloadwMain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+public class IloadwMain {
+    public static void main(String args[]) {
+        int result = Iloadw.run();
+        if (result != 1) {
+            throw new RuntimeException(
+                "Failed. Result is " + result + ", expect 1.");
+        } else {
+            System.out.println("Passed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/JimageClassPackage.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class JimageClassPackage {
+    public static void main(String args[]) throws Throwable {
+        // Test Package for boot/app/ext module classes from the "modules" jimage.
+        // The following classes are archived. See runtime/AppCDS/Package.java.
+        //     java.util.Dictionary (testcase 0),
+        //     sun.tools.javac.Main (testcase 1),
+        //     jdk.nio.zipfs.ZipInfo (testcase 2),
+        //     java.net.URL (testcase 3),
+        //     sun.rmi.rmic.Main (testcase 4),
+        //     com.sun.jndi.dns.DnsName (testcase 5)
+        String testcases[][] =
+            {{"Loading shared boot module class first", "java.util",
+              "java.util.Dictionary", "java.util.ServiceConfigurationError"},
+
+             {"Loading shared app module class first", "sun.tools.javac",
+              "sun.tools.javac.Main", "sun.tools.javac.BatchParser"},
+
+             {"Loading shared ext module class first", "jdk.nio.zipfs",
+              "jdk.nio.zipfs.ZipInfo", "jdk.nio.zipfs.ZipPath"},
+
+             {"Loading non-shared boot module class first", "java.net",
+              "java.net.HttpCookie", "java.net.URL"},
+
+             {"Loading non-shared app module class first", "sun.rmi.rmic",
+              "sun.rmi.rmic.RMIGenerator", "sun.rmi.rmic.Main"},
+
+             {"Loading non-shared ext module class first", "com.sun.jndi.dns",
+              "com.sun.jndi.dns.Resolver", "com.sun.jndi.dns.DnsName"}};
+
+        JimageClassPackage test = new JimageClassPackage();
+        for (int i = 0; i < testcases.length; i++) {
+            System.out.println("Testcase " + i + ": " + testcases[i][0]);
+            test.testPackage(testcases[i][1], testcases[i][2], testcases[i][3]);
+        }
+    }
+
+    private void testPackage (String pkg,
+                              String shared,
+                              String nonShared) throws Throwable {
+        Class c1 = Class.forName(shared);
+        ClassLoader cl = c1.getClassLoader();
+        Package pkg_from_loader;
+        if (cl != null) {
+            pkg_from_loader = cl.getDefinedPackage(pkg);
+        } else {
+            pkg_from_loader = Package.getPackage(pkg);
+        }
+
+        Package pkg_from_shared_class = c1.getPackage();
+
+        Class c2 = Class.forName(nonShared);
+        Package pkg_from_nonshared_class = c2.getPackage();
+
+        if (pkg_from_loader != null &&
+            pkg_from_shared_class != null &&
+            pkg_from_loader == pkg_from_shared_class &&
+            pkg_from_shared_class == pkg_from_nonshared_class &&
+            pkg_from_shared_class.getName().equals(pkg)) {
+            System.out.println("Expected package: " + pkg_from_shared_class.toString());
+        } else {
+            System.out.println("Unexpected package" + pkg_from_shared_class);
+            System.exit(1);
+        }
+        if (pkg_from_shared_class.isSealed()) {
+            System.out.println("Package is sealed");
+        } else {
+            System.out.println("Package is not sealed");
+            System.exit(1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/JimageClassProtDomain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class JimageClassProtDomain {
+    public static void main(String args[]) throws Throwable {
+        // Test ProtectionDomain for boot/app/ext module classes from the "modules" jimage.
+        // The following classes are archived. See runtime/AppCDS/ProtectionDomain.java.
+        //     java.util.Dictionary (testcase 0),
+        //     sun.tools.javac.Main (testcase 1),
+        //     jdk.nio.zipfs.ZipInfo (testcase 2),
+        //     java.net.URL (testcase 3),
+        //     sun.rmi.rmic.Main (testcase 4),
+        //     com.sun.jndi.dns.DnsName (testcase 5)
+        String testcases[][] =
+            {{"Loading shared boot module class first",
+              "java.util.Dictionary", "java.util.ServiceConfigurationError"},
+
+             {"Loading shared app module class first",
+              "sun.tools.javac.Main", "sun.tools.javac.BatchParser"},
+
+             {"Loading shared ext module class first",
+              "jdk.nio.zipfs.ZipInfo", "jdk.nio.zipfs.ZipPath"},
+
+             {"Loading non-shared boot module class first",
+              "java.net.HttpCookie", "java.net.URL"},
+
+             {"Loading non-shared app module class first",
+              "sun.rmi.rmic.RMIGenerator", "sun.rmi.rmic.Main"},
+
+             {"Loading non-shared ext module class first",
+              "com.sun.jndi.dns.Resolver", "com.sun.jndi.dns.DnsName"}};
+        for (int i = 0; i < testcases.length; i++) {
+            System.out.println("Testcase " + i + ": " + testcases[i][0]);
+            JimageClassProtDomain.testProtectionDomain(testcases[i][1], testcases[i][2]);
+        }
+    }
+
+    private static void testProtectionDomain(String shared, String nonShared)
+              throws Throwable {
+        Class c1 = Class.forName(shared);
+        Class c2 = Class.forName(nonShared);
+        if (c1.getProtectionDomain() != c2.getProtectionDomain()) {
+            System.out.println("Failed: Protection Domains do not match!");
+            System.out.println(c1.getProtectionDomain());
+            System.out.println(c1.getProtectionDomain().getCodeSource());
+            System.out.println(c2.getProtectionDomain());
+            System.out.println(c2.getProtectionDomain().getCodeSource());
+            System.exit(1);
+        } else {
+            System.out.println("Passed: Protection Domains match.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/JvmtiApp.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+public class JvmtiApp {
+    static Class forname() {
+        try {
+            return Class.forName("Hello");
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+
+    static void failed(String msg) {
+        System.out.println("TEST FAILED: " + msg);
+        System.exit(1);
+    }
+
+    // See ../JvmtiAddPath.java for how the classpaths are configured.
+    public static void main(String args[]) {
+        if (args[0].equals("noadd")) {
+            if (forname() != null) {
+                failed("Hello class was loaded unexpectedly");
+            }
+            // We use -verbose:class to verify that Extra.class IS loaded by AppCDS if
+            // the boot classpath HAS NOT been appended.
+            ExtraClass.doit();
+            System.exit(0);
+        }
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+
+        if (args[0].equals("bootonly")) {
+            wb.addToBootstrapClassLoaderSearch(args[1]);
+            Class cls = forname();
+            if (cls == null) {
+                failed("Cannot find Hello class");
+            }
+            if (cls.getClassLoader() != null) {
+                failed("Hello class not loaded by boot classloader");
+            }
+        } else if (args[0].equals("apponly")) {
+            wb.addToSystemClassLoaderSearch(args[1]);
+            Class cls = forname();
+            if (cls == null) {
+                failed("Cannot find Hello class");
+            }
+            if (cls.getClassLoader() != JvmtiApp.class.getClassLoader()) {
+                failed("Hello class not loaded by app classloader");
+            }
+        } else if (args[0].equals("noadd-appcds")) {
+            Class cls = forname();
+            if (cls == null) {
+                failed("Cannot find Hello class");
+            }
+            if (cls.getClassLoader() != JvmtiApp.class.getClassLoader()) {
+                failed("Hello class not loaded by app classloader");
+            }
+        } else if (args[0].equals("appandboot")) {
+            wb.addToBootstrapClassLoaderSearch(args[1]);
+            wb.addToSystemClassLoaderSearch(args[2]);
+            Class cls = forname();
+            if (cls == null) {
+                failed("Cannot find Hello class");
+            }
+            if (cls.getClassLoader() != null) {
+                failed("Hello class not loaded by boot classloader");
+            }
+        } else {
+            failed("unknown option " + args[0]);
+        }
+
+        // We use -verbose:class to verify that Extra.class IS NOT loaded by AppCDS if
+        // the boot classpath HAS been appended.
+        ExtraClass.doit();
+
+        System.out.println("Test passed: " + args[0]);
+    }
+}
+
+class ExtraClass {
+    static void doit() {}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/MethodNoReturn.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+WAS:
+
+class MethodNoReturn {
+  void badMethod() {}
+}
+*/
+
+super class MethodNoReturn
+	version 52:0
+{
+
+
+Method "<init>":"()V"
+	stack 1 locals 1
+{
+		aload_0;
+		invokespecial	Method java/lang/Object."<init>":"()V";
+		return;
+}
+
+Method badMethod:"()V"
+	stack 0 locals 1
+{
+  /*
+    should be:
+		return;
+  */
+
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		pop;
+		iconst_1;
+		iconst_1;
+		iconst_1;
+		iconst_1;
+		iconst_1;
+		iconst_1;
+		iconst_1;
+		iconst_1;
+		pop;
+		pop;
+		pop;
+		pop;
+		pop;
+		pop;
+		pop;
+		pop;
+  // no return here -- so this class will fail verification
+}
+
+} // end Class MethodNoReturn
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/MissingSuper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class MissingSuper {
+    public static void main(String args[]) {
+        try {
+            new MissingSuperSub();
+        } catch (NoClassDefFoundError e) {
+            System.out.println("Expected NoClassDefFoundError:");
+            e.printStackTrace(System.out);
+        }
+
+        try {
+            new MissingSuperImpl();
+        } catch (NoClassDefFoundError e) {
+            System.out.println("Expected NoClassDefFoundError:");
+            e.printStackTrace(System.out);
+        }
+    }
+}
+
+class MissingSuperSup {} // This class will be deleted from missing_super.jar before dumping
+
+class MissingSuperSub extends MissingSuperSup {}
+
+interface MissingSuperIntf {} // This interface will be deleted from missing_super.jar before dumping
+
+class MissingSuperImpl implements MissingSuperIntf {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/MultiProcClass.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import sun.hotspot.WhiteBox;
+
+// This class should be loaded from a shared archive.
+public class MultiProcClass {
+    private static String instanceLabel;
+
+    public static void main(String args[]) throws Exception {
+        instanceLabel = args[0];
+        String checkPmap = args[1];
+
+        long pid = ProcessHandle.current().pid();
+        System.out.println(inst("========================== Starting MultiProcClass"));
+        System.out.println(inst("My PID: " + pid ));
+        System.out.println(inst("checkPmap = <" + checkPmap + ">" ));
+
+        if ("true".equals(checkPmap)) {
+            if (runPmap(pid, true) != 0)
+                System.out.println("MultiProcClass: Pmap failed");
+        }
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        if (!wb.isSharedClass(MultiProcClass.class)) {
+            throw new RuntimeException(inst("MultiProcClass should be shared but is not."));
+        }
+
+        System.out.println(inst("========================== Leaving MultiProcClass"));
+    }
+
+    // A convenience method to append process instance label
+    private static String inst(String msg) {
+        return "process-" + instanceLabel + " : " + msg;
+    }
+
+    // Use on Linux-only; requires jdk-9 for Process.pid()
+    public static int runPmap(long pid, boolean inheritIO) throws Exception {
+        ProcessBuilder pmapPb = new ProcessBuilder("pmap", "" + pid);
+        if (inheritIO)
+            pmapPb.inheritIO();
+
+        return pmapPb.start().waitFor();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/MyAnnotation.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+
+public @interface MyAnnotation {
+    public String name();
+    public String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/PackageSealingTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.lang.Package;
+
+public class PackageSealingTest {
+    public static void main(String args[]) {
+        try {
+            Class c1 = PackageSealingTest.class.forName("sealed.pkg.C1");
+            Class c2 = PackageSealingTest.class.forName("pkg.C2");
+            Package p1 = c1.getPackage();
+            System.out.println("Package 1: " + p1.toString());
+            Package p2 = c2.getPackage();
+            System.out.println("Package 2: " + p2.toString());
+
+            if (!p1.isSealed()) {
+                System.out.println("Failed: sealed.pkg is not sealed.");
+                System.exit(0);
+            }
+
+            if (p2.isSealed()) {
+                System.out.println("Failed: pkg is sealed.");
+                System.exit(0);
+            }
+
+            System.out.println("OK");
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/PackageTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 2017, 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 p;
+
+public class PackageTest {
+    public static void main(String args[]) {
+        (new PackageTest()).test();
+    }
+
+    private void test() {
+        ClassLoader cl = PackageTest.class.getClassLoader();
+        Package pkg_from_loader;
+        if (cl != null) {
+            pkg_from_loader = cl.getDefinedPackage("p");
+        } else {
+            pkg_from_loader = Package.getPackage("p");
+        }
+
+        Package pkg = PackageTest.class.getPackage();
+        if (pkg_from_loader != null && pkg == pkg_from_loader &&
+            pkg.getName().equals("p")) {
+            System.out.println("Expected package: " + pkg);
+        } else {
+            System.out.println("Unexpected package: " + pkg);
+            System.exit(1);
+        }
+        if (pkg.isSealed()) {
+            System.out.println("Package is sealed");
+            System.exit(1);
+        } else {
+            System.out.println("Package is not sealed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ParallelClasses.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+class ParallelClass0 {}
+class ParallelClass1 {}
+class ParallelClass2 {}
+class ParallelClass3 {}
+class ParallelClass4 {}
+class ParallelClass5 {}
+class ParallelClass6 {}
+class ParallelClass7 {}
+class ParallelClass8 {}
+class ParallelClass9 {}
+class ParallelClass10 {}
+class ParallelClass11 {}
+class ParallelClass12 {}
+class ParallelClass13 {}
+class ParallelClass14 {}
+class ParallelClass15 {}
+class ParallelClass16 {}
+class ParallelClass17 {}
+class ParallelClass18 {}
+class ParallelClass19 {}
+class ParallelClass20 {}
+class ParallelClass21 {}
+class ParallelClass22 {}
+class ParallelClass23 {}
+class ParallelClass24 {}
+class ParallelClass25 {}
+class ParallelClass26 {}
+class ParallelClass27 {}
+class ParallelClass28 {}
+class ParallelClass29 {}
+class ParallelClass30 {}
+class ParallelClass31 {}
+class ParallelClass32 {}
+class ParallelClass33 {}
+class ParallelClass34 {}
+class ParallelClass35 {}
+class ParallelClass36 {}
+class ParallelClass37 {}
+class ParallelClass38 {}
+class ParallelClass39 {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ParallelLoad.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ *
+ */
+
+import java.io.*;
+import java.net.*;
+import java.lang.reflect.Field;
+
+
+// This test helper is parameterized by:
+// - class transformation mode: property "appcds.parallel.transform.mode"
+// - class loader test types
+//
+// In the case of transformMode == "cflh", the transformation is performed
+// by AppCDS/jvmti/TransformerAgent.java. The classes to be transformed, such as
+// ParallelClassTr0, are defined in ./jvmti/parallelLoad/ParallelClasses.java
+
+public class ParallelLoad {
+    public static int MAX_CLASSES = 40;
+    public static int NUM_THREADS = 4;
+
+    public final static int SYSTEM_LOADER = 0;
+    public final static int SINGLE_CUSTOM_LOADER = 1;
+    public final static int MULTI_CUSTOM_LOADER = 2;
+
+    public static final int FINGERPRINT_MODE = 1;
+    public static final int API_MODE         = 2;
+
+    public static int loaderType = SYSTEM_LOADER;
+    public static ClassLoader classLoaders[];
+    public static int mode = FINGERPRINT_MODE;
+
+    public static float timeoutFactor =
+        Float.parseFloat(System.getProperty("test.timeout.factor", "1.0"));
+
+    public static void main(String args[]) throws Throwable {
+        run(args, null);
+    }
+    public static void run(String args[], ClassLoader loaders[]) throws Throwable {
+        String customJar = null;
+        System.out.println("ParallelLoad: timeoutFactor = " + timeoutFactor);
+
+        if (args.length >= 1) {
+            if ("SINGLE_CUSTOM_LOADER".equals(args[0])) {
+                loaderType = SINGLE_CUSTOM_LOADER;
+                customJar = args[2];
+            } else if ("MULTI_CUSTOM_LOADER".equals(args[0])) {
+                loaderType = MULTI_CUSTOM_LOADER;
+                customJar = args[2];
+            } else if ("SYSTEM_LOADER".equals(args[0])) {
+                loaderType = SYSTEM_LOADER;
+            } else {
+                throw new RuntimeException("Unexpected loaderType" + args[0]);
+            }
+        }
+
+        if (customJar != null) {
+            if ("FINGERPRINT_MODE".equals(args[1])) {
+                mode = FINGERPRINT_MODE;
+                classLoaders = new ClassLoader[NUM_THREADS];
+                for (int i=0; i<NUM_THREADS; i++) {
+                    URL url = new File(customJar).toURI().toURL();
+                    URL[] urls = new URL[] {url};
+                    classLoaders[i] = new URLClassLoader(urls);
+                }
+            } else {
+                // Loaders must be supplied by caller of the run() method
+                mode = API_MODE;
+                classLoaders = loaders;
+            }
+        }
+
+        System.out.println("Start Parallel Load ...");
+
+        Thread thread[] = new Thread[NUM_THREADS];
+        for (int i=0; i<NUM_THREADS; i++) {
+            Thread t = new ParallelLoadThread(i);
+            t.start();
+            thread[i] = t;
+        }
+
+        Thread watchdog = new ParallelLoadWatchdog();
+        watchdog.setDaemon(true);
+        watchdog.start();
+
+        for (int i=0; i<NUM_THREADS; i++) {
+            thread[i].join();
+        }
+        System.out.println("Parallel Load ... done");
+        System.exit(0);
+    }
+}
+
+
+class ParallelLoadWatchdog extends Thread {
+    public void run() {
+        try {
+            long timeout = (long) (20 * 1000 * ParallelLoad.timeoutFactor);
+            Thread.sleep(timeout);
+            System.out.println("ParallelLoadWatchdog: Timeout reached: timeout(ms) = " + timeout);
+            System.exit(1);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            System.exit(1);
+        }
+    }
+};
+
+
+class ParallelLoadThread extends Thread {
+    static int num_ready[] = new int[ParallelLoad.MAX_CLASSES];
+    static Object lock = new Object();
+    static String transformMode =
+        System.getProperty("appcds.parallel.transform.mode", "none");
+
+    int thread_id;
+    ParallelLoadThread(int thread_id) {
+        this.thread_id = thread_id;
+    }
+
+    public void run() {
+        try {
+            run0();
+        } catch (Throwable t) {
+            t.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void log(String msg, Object... args) {
+        String msg0 = "ParallelLoadThread: " + String.format(msg, args);
+        System.out.println(msg0);
+    }
+
+    private void run0() throws Throwable {
+        for (int i=0; i<ParallelLoad.MAX_CLASSES; i++) {
+            synchronized(lock) {
+                num_ready[i] ++;
+                while (num_ready[i] < ParallelLoad.NUM_THREADS) {
+                    lock.wait();
+                }
+                lock.notifyAll();
+            }
+            log("this = %s %d", this, i);
+            String className = "ParallelClass" + i;
+            if (transformMode.equals("cflh"))
+                className = "ParallelClassTr" + i;
+
+            Class clazz = null;
+
+            switch (ParallelLoad.loaderType) {
+            case ParallelLoad.SYSTEM_LOADER:
+                clazz = Class.forName(className);
+                break;
+            case ParallelLoad.SINGLE_CUSTOM_LOADER:
+                clazz = ParallelLoad.classLoaders[0].loadClass(className);
+                break;
+            case ParallelLoad.MULTI_CUSTOM_LOADER:
+                clazz = ParallelLoad.classLoaders[thread_id].loadClass(className);
+                break;
+            }
+
+            log("clazz = %s", clazz);
+            testTransformation(clazz);
+        }
+    }
+
+    private void testTransformation(Class c) throws Exception {
+        if (transformMode.equals("none"))
+            return;
+
+        // currently only cflh transform mode is supported
+        if (!transformMode.equals("cflh")) {
+            String msg = "wrong transform mode: " + transformMode;
+            throw new IllegalArgumentException(msg);
+        }
+
+        Field[] fields = c.getFields();
+        boolean fieldFound = false;
+        for (Field f : fields) {
+            if (f.getName().equals("testString")) {
+                checkTransformationString(c, (String) f.get(null));
+                fieldFound = true;
+            }
+        }
+
+        if (!fieldFound)
+            throw new RuntimeException ("Expected field 'testString' not found");
+    }
+
+    private void checkTransformationString(Class c, String actual) throws Exception {
+        String expected = "class-transform-check: this-has-been--transformed";
+        if (!actual.equals(expected)) {
+            String msg1 = "Transformation failed for class" + c.getName();
+            String msg2 = String.format("Expected: %s, actual: %s", expected, actual);
+            throw new RuntimeException(msg1 + "\n" + msg2);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Prohibited.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 2017, 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 java/lang;
+
+public class Prohibited
+    version 51:0
+{
+} // end class Prohibited
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ProhibitedHelper.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+public class ProhibitedHelper {
+    public static void main(String[] args) throws Throwable {
+
+        String className = "java.lang.Prohibited";
+        ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
+        try {
+            Module unnamedModule = sysLoader.getUnnamedModule();
+            Class cls = Class.forName(unnamedModule, className);
+            System.out.println("cls " + cls);
+            throw new java.lang.RuntimeException(className +
+                "in a prohibited package shouldn't be loaded");
+        } catch (Exception e) {
+            e.printStackTrace();
+            if (!(e instanceof java.lang.SecurityException)) {
+                throw new java.lang.RuntimeException(
+                    "SecurityException is expected to be thrown while loading " + className);
+            }
+        }
+
+        try {
+            Class cls = Class.forName(className, false, sysLoader);
+            System.out.println("cls " + cls);
+            throw new java.lang.RuntimeException(className +
+                "in a prohibited package shouldn't be loaded");
+        } catch (Exception e) {
+            e.printStackTrace();
+            if (!(e instanceof java.lang.ClassNotFoundException)) {
+                throw new java.lang.RuntimeException(
+                    "ClassNotFoundException is expected to be thrown while loading " + className);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ProtDomain.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.security.ProtectionDomain;
+
+// See ../AppCDSProtectionDomain.java
+//
+// ProtDomain      is     stored in CDS archive.
+// ProtDomainOther is NOT stored in CDS archive.
+//
+// However, they should have the same ProtectionDomain instance.
+public class ProtDomain {
+  public static void main(String args[]) {
+    System.out.println("Testing ProtDomain");
+    ProtectionDomain mine = ProtDomain.class.getProtectionDomain();
+    ProtectionDomain his  = ProtDomainOther.class.getProtectionDomain();
+
+    System.out.println("mine = " + mine);
+    System.out.println("his  = " + his);
+
+    if (mine == his) {
+      System.out.println("Protection Domains match");
+    } else {
+      System.out.println("Protection Domains do not match!");
+      System.exit(1);
+    }
+  }
+}
+
+class ProtDomainOther {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ProtDomainB.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+import java.security.ProtectionDomain;
+
+// See ../AppCDSProtectionDomain.java
+//
+// ProtDomainB      is NOT stored in CDS archive.
+// ProtDomainBOther is     stored in CDS archive.
+//
+// However, they should have the same ProtectionDomain instance.
+public class ProtDomainB {
+  public static void main(String args[]) {
+    System.out.println("Testing ProtDomainB");
+    ProtectionDomain mine = ProtDomainB.class.getProtectionDomain();
+    ProtectionDomain his  = ProtDomainBOther.class.getProtectionDomain();
+
+    System.out.println("mine = " + mine);
+    System.out.println("his  = " + his);
+
+    if (mine == his) {
+      System.out.println("Protection Domains match");
+    } else {
+      System.out.println("Protection Domains do not match!");
+      System.exit(1);
+    }
+  }
+}
+
+class ProtDomainBOther {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/ReportMyLoader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class ReportMyLoader {
+    public static void main(String args[]) {
+        System.out.println("ReportMyLoader's loader = " + ReportMyLoader.class.getClassLoader());
+        System.out.println("TestClassLoader.called = " + TestClassLoader.called);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/RewriteBytecodes.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.io.File;
+import sun.hotspot.WhiteBox;
+
+public class RewriteBytecodes {
+  public static void main(String args[]) throws Throwable {
+    String from = "___xxx___";
+    String to   = "___yyy___";
+    File clsFile = new File(args[0]);
+    Class superClass = Util.defineModifiedClass(RewriteBytecodes.class.getClassLoader(), clsFile, from, to);
+
+    Child child = new Child();
+
+    if (child.getClass().getSuperclass() != superClass) {
+      throw new RuntimeException("Mismatched super class");
+    }
+    // Even if the Super class is not loaded from the CDS archive, make sure the Child class
+    // can still be loaded successfully, and properly inherits from the rewritten version
+    // of Super.
+    if (!child.toString().equals(to)) {
+      throw new RuntimeException("Wrong output, expected: " + to + ", but got: " + child.toString());
+    }
+
+    WhiteBox wb = WhiteBox.getWhiteBox();
+    if (wb.isSharedClass(superClass)) {
+      throw new RuntimeException("wb.isSharedClass(superClass) should be false");
+    }
+    if (wb.isSharedClass(child.getClass())) {
+      throw new RuntimeException("wb.isSharedClass(child.getClass()) should be false");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Super.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+public class Super {
+  public String toString() {
+    return "___xxx___";
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/TestClassLoader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+// This is a class loader that simply delegates all calls to its parent loader.
+
+public class TestClassLoader extends ClassLoader {
+    static boolean called = false;
+    ClassLoader parent;
+    public TestClassLoader(ClassLoader parent) {
+        super(parent);
+        this.parent = parent;
+    }
+
+    public Class<?> loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+        called = true;
+        System.out.println("TestClassLoader: loadClass(\"" + name + "\", " + resolve + ")");
+        return (super.loadClass(name, resolve));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/TrySwitchMyLoader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+public class TrySwitchMyLoader {
+    public static void main(String args[]) {
+        System.out.println("TrySwitchMyLoader's loader = " + ReportMyLoader.class.getClassLoader());
+        System.setProperty("java.system.class.loader", "TestClassLoader");
+
+        // This should still report the same loader as TrySwitchMyLoader.class.getClassLoader(),
+        // as setting the java.system.class.loader after main method has been executed
+        // has no effect.
+        ReportMyLoader.main(args);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/Util.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ *
+ */
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.jar.*;
+
+public class Util {
+    /**
+     * Invoke the loader.defineClass() class method to define the class stored in clsFile,
+     * with the following modification:
+     * <ul>
+     *  <li> All ASCII strings in the class file bytes that matches fromString will be replaced with toString.
+     *       NOTE: the two strings must be the exact same length.
+     * </ul>
+     */
+    public static Class defineModifiedClass(ClassLoader loader, File clsFile, String fromString, String toString)
+        throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException,
+               InvocationTargetException
+    {
+        DataInputStream dis = new DataInputStream(new FileInputStream(clsFile));
+        byte[] buff = new byte[(int)clsFile.length()];
+        dis.readFully(buff);
+        replace(buff, fromString, toString);
+
+        System.out.println("Loading from: " + clsFile + " (" + buff.length + " bytes)");
+
+        Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass",
+                                                                 buff.getClass(), int.class, int.class);
+        defineClass.setAccessible(true);
+
+        // We directly call into ClassLoader.defineClass() to define the "Super" class. Also,
+        // rewrite its classfile so that it returns ___yyy___ instead of ___xxx___. Changing the
+        // classfile will guarantee that this class will NOT be loaded from the CDS archive.
+        Class cls = (Class)defineClass.invoke(loader, buff, new Integer(0), new Integer(buff.length));
+        System.out.println("Loaded : " + cls);
+
+        return cls;
+    }
+
+    /**
+     * @return the number of occurrences of the <code>from</code> string that
+     * have been replaced.
+     */
+    public static int replace(byte buff[], String from, String to) {
+        if (to.length() != from.length()) {
+            throw new RuntimeException("bad strings");
+        }
+        byte f[] = asciibytes(from);
+        byte t[] = asciibytes(to);
+        byte f0 = f[0];
+
+        int numReplaced = 0;
+        int max = buff.length - f.length;
+        for (int i=0; i<max; ) {
+            if (buff[i] == f0 && replace(buff, f, t, i)) {
+                i += f.length;
+                numReplaced ++;
+            } else {
+                i++;
+            }
+        }
+        return numReplaced;
+    }
+
+    public static boolean replace(byte buff[], byte f[], byte t[], int i) {
+        for (int x=0; x<f.length; x++) {
+            if (buff[x+i] != f[x]) {
+                return false;
+            }
+        }
+        for (int x=0; x<f.length; x++) {
+            buff[x+i] = t[x];
+        }
+        return true;
+    }
+
+    static byte[] asciibytes(String s) {
+        byte b[] = new byte[s.length()];
+        for (int i=0; i<b.length; i++) {
+            b[i] = (byte)s.charAt(i);
+        }
+        return b;
+    }
+
+    public static Class defineClassFromJAR(ClassLoader loader, File jarFile, String className)
+        throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException,
+               InvocationTargetException {
+        return defineClassFromJAR(loader, jarFile, className, null, null);
+    }
+
+    /**
+     * Invoke the loader.defineClass() class method to define the named class stored in a JAR file.
+     *
+     * If a class exists both in the classpath, as well as in the list of URLs of a URLClassLoader,
+     * by default, the URLClassLoader will not define the class, and instead will delegate to the
+     * app loader. This method is an easy way to force the class to be defined by the URLClassLoader.
+     *
+     * Optionally, you can modify the contents of the classfile buffer. See comments in
+     * defineModifiedClass.
+     */
+    public static Class defineClassFromJAR(ClassLoader loader, File jarFile, String className,
+                                           String fromString, String toString)
+        throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException,
+               InvocationTargetException
+    {
+        byte[] buff = getClassFileFromJar(jarFile, className);
+
+        if (fromString != null) {
+            replace(buff, fromString, toString);
+        }
+
+        //System.out.println("Loading from: " + ent + " (" + buff.length + " bytes)");
+
+        Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass",
+                                                                 buff.getClass(), int.class, int.class);
+        defineClass.setAccessible(true);
+        Class cls = (Class)defineClass.invoke(loader, buff, new Integer(0), new Integer(buff.length));
+
+        //System.out.println("Loaded : " + cls);
+        return cls;
+    }
+
+    public static byte[] getClassFileFromJar(File jarFile, String className) throws FileNotFoundException, IOException {
+        JarFile jf = new JarFile(jarFile);
+        JarEntry ent = jf.getJarEntry(className.replace('.', '/') + ".class");
+
+        DataInputStream dis = new DataInputStream(jf.getInputStream(ent));
+        byte[] buff = new byte[(int)ent.getSize()];
+        dis.readFully(buff);
+        dis.close();
+
+        return buff;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/VerifierTest0.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 2017, 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.
+ *
+ */
+
+/*
+ * Note: verifier_test_tmp.jar will be processed by ../AppCDSVerifierTest.java to
+ * create verifier_test.jar, which contains invalid versions of UnverifiableBase
+ * and UnverifiableIntf.
+ */
+
+public class VerifierTest0 {
+  public static void main(String args[]) {
+    boolean good = true;
+    good &= mustBeInvalid("VerifierTestA");
+    good &= mustBeInvalid("VerifierTestB");
+    good &= mustBeInvalid("VerifierTestC");
+    good &= mustBeInvalid("VerifierTestD");
+    good &= mustBeInvalid("VerifierTestE");
+    if (!good) {
+      System.out.println("VerifierTest0 failed");
+      System.exit(1);
+    }
+  }
+
+  /** @return false means error */
+  static boolean mustBeInvalid(String className) {
+    System.out.println("Testing: " + className);
+    try {
+      Class.forName(className);
+      System.out.println("ERROR: class " + className + " was loaded unexpectedly.");
+      return false;
+    } catch (Throwable t) {
+      System.out.println("Expected exception:");
+      t.printStackTrace();
+      return true;
+    }
+  }
+}
+
+class UnverifiableBase {
+  static final VerifierTest0 x = new VerifierTest0(); // <- this static initializer will be made unverifiable by type mismatch
+}
+
+interface UnverifiableIntf {
+  static final VerifierTest0 x = new VerifierTest0(); // <- this static initializer will be made unverifiable by type mismatch
+}
+
+interface UnverifiableIntfSub extends UnverifiableIntf {}
+
+class VerifierTestA extends    UnverifiableBase {}
+class VerifierTestB extends    VerifierTestA {}
+class VerifierTestC implements UnverifiableIntf {}
+class VerifierTestD extends    VerifierTestC {}
+class VerifierTestE implements UnverifiableIntfSub {}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/com/sun/tools/javac/Main.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 2017, 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 com/sun/tools/javac;
+
+public class Main
+    version 51:0
+{
+} // end class Main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/cpattr1.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: cpattr2.jar
+Created-By: 1.9.0-internal (Oracle Corporation)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/cpattr1_long.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Class-Path: zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.ja
+ r zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz
+ .jar xx.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.j
+ ar zzzzzzz.jar xx.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar
+  zzzzzzz.jar zzzzzzz.jar xx.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar z
+ zzzzzz.jar zzzzzzz.jar zzzzzzz.jar xx.jar zzzzzzz.jar zzzzzzz.jar zzz
+ zzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar xx.jar zzzzzzz.jar zzzzz
+ zz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar xx.jar zzzzzzz
+ .jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar xx.j
+ ar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzz
+ z.jar xx.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.
+ jar zzzzzzz.jar xx.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.ja
+ r zzzzzzz.jar zzzzzzz.jar xx.jar zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar 
+ zzzzzzz.jar zzzzzzz.jar zzzzzzz.jar xx.jar cpattr2.jar cpattr1_long.j
+ ar
+Created-By: 1.9.0-internal (Oracle Corporation)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/cpattr2.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Class-Path: cpattr3.jar cpattr5_123456789_223456789_323456789_42345678
+ 9_523456789_623456789.jar
+Created-By: 1.9.0-internal (Oracle Corporation)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/cpattr3.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/cpattr4.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/cpattr5_extra_long.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/java/net/HttpCookie.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 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 java/net;
+
+public class HttpCookie
+    version 51:0
+{
+
+public Method thisClassIsDummy:"()V"
+    stack 0 locals 0
+{
+    return;
+}
+
+} // end class HttpCookie
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/javax/activation/MimeType.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 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 javax/activation;
+
+public class MimeType
+    version 51:0
+{
+
+public Method thisClassIsDummy:"()V"
+    stack 0 locals 0
+{
+    return;
+}
+
+} // end class MimeType
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/javax/transaction/InvalidTransactionException.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 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 javax/transaction;
+
+public class InvalidTransactionException
+    version 51:0
+{
+
+public Method thisClassIsDummy:"()V"
+    stack 0 locals 0
+{
+    return;
+}
+
+} // end class InvalidTransactionException
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/jdk/dynalink/DynamicLinker.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 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 jdk/dynalink;
+
+public class DynamicLinker
+    version 51:0
+{
+
+public Method thisClassIsDummy:"()V"
+    stack 0 locals 2
+{
+    return;
+}
+
+} // end class DynamicLinker
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/test-classes/package_seal.mf	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
+
+Name: sealed/pkg/
+Sealed: true
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/classFileParserBug/Class54.jasm	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/*
+ * @test
+ * @bug 8188870
+ * @summary Check that the JVM accepts class files with version 54
+ * @run main Class54
+ */
+
+super public class Class54 version 54:0 {
+
+    public Method "<init>":"()V" stack 1 locals 1 {
+        aload_0;
+        invokespecial    Method java/lang/Object."<init>":"()V";
+        return;
+    }
+
+    public static Method main:"([Ljava/lang/String;)V" stack 0 locals 1 {
+        return;
+    }
+
+} // end Class Class54
--- a/test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java	Thu Dec 07 11:54:55 2017 +0000
@@ -33,28 +33,28 @@
  * @build Common
  * @run driver TestCPUAwareness
  */
+import java.util.List;
 import jdk.test.lib.containers.docker.DockerRunOptions;
 import jdk.test.lib.containers.docker.DockerTestUtils;
 
 
 public class TestCPUAwareness {
     private static final String imageName = Common.imageName("cpu");
+    private static final int availableCPUs = Runtime.getRuntime().availableProcessors();
 
     public static void main(String[] args) throws Exception {
         if (!DockerTestUtils.canTestDocker()) {
             return;
         }
 
-        int availableCPUs = Runtime.getRuntime().availableProcessors();
         System.out.println("Test Environment: detected availableCPUs = " + availableCPUs);
         DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
 
         try {
             // cpuset, period, shares, expected Active Processor Count
-            testAPCCombo("0", 200*1000, 100*1000,   4*1024, 1);
-            testAPCCombo("0,1", 200*1000, 100*1000, 4*1024, 2);
-            testAPCCombo("0,1", 200*1000, 100*1000, 1*1024, 2);
+            testComboWithCpuSets();
 
+            // cpu shares - it should be safe to use CPU shares exceeding available CPUs
             testCpuShares(256, 1);
             testCpuShares(2048, 2);
             testCpuShares(4096, 4);
@@ -70,9 +70,11 @@
             testActiveProcessorCount(1, 1);
             testActiveProcessorCount(2, 2);
 
+            // cpu quota and period
             testCpuQuotaAndPeriod(50*1000, 100*1000);
             testCpuQuotaAndPeriod(100*1000, 100*1000);
             testCpuQuotaAndPeriod(150*1000, 100*1000);
+            testCpuQuotaAndPeriod(400*1000, 100*1000);
 
         } finally {
             DockerTestUtils.removeDockerImage(imageName);
@@ -80,6 +82,31 @@
     }
 
 
+    private static void testComboWithCpuSets() throws Exception {
+        String cpuSetStr = CPUSetsReader.readFromProcStatus("Cpus_allowed_list");
+        System.out.println("cpuSetStr = " + cpuSetStr);
+
+        if (cpuSetStr == null) {
+            System.out.printf("The cpuset test cases are skipped");
+        } else {
+            List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);
+
+            // Test subset of cpuset with one element
+            if (cpuSet.size() >= 1) {
+                String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000,   4*1024, 1);
+            }
+
+            // Test subset of cpuset with two elements
+            if (cpuSet.size() >= 2) {
+                String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 2);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 1*1024, 2);
+            }
+        }
+    }
+
+
     private static void testActiveProcessorCount(int valueToSet, int expectedValue) throws Exception {
         Common.logNewTestCase("Test ActiveProcessorCount: valueToSet = " + valueToSet);
 
@@ -99,6 +126,16 @@
     }
 
 
+    // Expected active processor count can not exceed available CPU count
+    private static int adjustExpectedAPCForAvailableCPUs(int expectedAPC) {
+        if (expectedAPC > availableCPUs) {
+            expectedAPC = availableCPUs;
+            System.out.println("Adjusted expectedAPC = " + expectedAPC);
+        }
+        return expectedAPC;
+    }
+
+
     private static void testCpuQuotaAndPeriod(int quota, int period)
         throws Exception {
         Common.logNewTestCase("test cpu quota and period: ");
@@ -107,6 +144,7 @@
 
         int expectedAPC = (int) Math.ceil((float) quota / (float) period);
         System.out.println("expectedAPC = " + expectedAPC);
+        expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
 
         DockerRunOptions opts = Common.newOpts(imageName)
             .addDockerOpts("--cpu-period=" + period)
@@ -129,6 +167,8 @@
         System.out.println("shares = " + period);
         System.out.println("expectedAPC = " + expectedAPC);
 
+        expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
+
         DockerRunOptions opts = Common.newOpts(imageName)
             .addDockerOpts("--cpuset-cpus", "" + cpuset)
             .addDockerOpts("--cpu-period=" + period)
@@ -141,6 +181,10 @@
 
     private static void testCpuShares(int shares, int expectedAPC) throws Exception {
         Common.logNewTestCase("test cpu shares, shares = " + shares);
+        System.out.println("expectedAPC = " + expectedAPC);
+
+        expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
+
         DockerRunOptions opts = Common.newOpts(imageName)
             .addDockerOpts("--cpu-shares=" + shares);
         Common.run(opts)
--- a/test/hotspot/jtreg/runtime/handshake/HandshakeTransitionTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/runtime/handshake/HandshakeTransitionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -29,13 +29,17 @@
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 
+import sun.hotspot.WhiteBox;
+
 /*
  * @test HandshakeTransitionTest
  * @summary This does a sanity test of the poll in the native wrapper.
  * @requires vm.debug
  * @library /testlibrary /test/lib
  * @build HandshakeTransitionTest
- * @run main/native HandshakeTransitionTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI HandshakeTransitionTest
  */
 
 public class HandshakeTransitionTest {
@@ -44,6 +48,7 @@
 
     public static void main(String[] args) throws Exception {
         String lib = System.getProperty("test.nativepath");
+        WhiteBox wb = WhiteBox.getWhiteBox();
         ProcessBuilder pb =
             ProcessTools.createJavaProcessBuilder(
                     true,
@@ -54,6 +59,8 @@
                     "-XX:ParallelGCThreads=1",
                     "-XX:ConcGCThreads=1",
                     "-XX:CICompilerCount=2",
+                    "-XX:+UnlockExperimentalVMOptions",
+                    (wb.getBooleanVMFlag("UseJVMCICompiler") ?  "-XX:+UseJVMCICompiler" : "-XX:-UseJVMCICompiler"),
                     "HandshakeTransitionTest$Test");
 
 
--- a/test/hotspot/jtreg/runtime/handshake/HandshakeWalkExitTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/runtime/handshake/HandshakeWalkExitTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -42,22 +42,18 @@
     }
 
     static volatile boolean exit_now = false;
-    static Thread[] threads;
 
     public static void main(String... args) throws Exception {
-        int testRuns = 100;
-        int testThreads = 500;
+        int testRuns = 20;
+        int testThreads = 128;
 
         HandshakeWalkExitTest test = new HandshakeWalkExitTest();
 
-        threads = new Thread[64];
-
         Runnable hser = new Runnable(){
             public void run(){
                 WhiteBox wb = WhiteBox.getWhiteBox();
                 while(!exit_now) {
                     wb.handshakeWalkStack(null, true);
-                    try { Thread.sleep(1); } catch(Exception e) {}
                 }
             }
         };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/handshake/HandshakeWalkOneExitTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+/*
+ * @test HandshakeWalkOneExitTest
+ * @summary This test tries to stress the handshakes with new and exiting threads
+ * @library /testlibrary /test/lib
+ * @build HandshakeWalkOneExitTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI HandshakeWalkOneExitTest
+ */
+
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+public class HandshakeWalkOneExitTest  implements Runnable {
+
+    @Override
+    public void run() {
+    }
+
+    static volatile boolean exit_now = false;
+    static Thread[] threads;
+
+    public static void main(String... args) throws Exception {
+        int testRuns = 20;
+        int testThreads = 128;
+
+        HandshakeWalkOneExitTest test = new HandshakeWalkOneExitTest();
+
+        Runnable hser = new Runnable(){
+            public void run(){
+                WhiteBox wb = WhiteBox.getWhiteBox();
+                while(!exit_now) {
+                    Thread[] t = threads;
+                    for (int i = 0; i<t.length ; i++) {
+                        wb.handshakeWalkStack(t[i], false);
+                    }
+                }
+            }
+        };
+        Thread hst = new Thread(hser);
+        for (int k = 0; k<testRuns ; k++) {
+            threads = new Thread[testThreads];
+            for (int i = 0; i<threads.length ; i++) {
+                threads[i] = new Thread(test);
+                threads[i].start();
+            }
+            if (k == 0) {
+                hst.start();
+            }
+        }
+        exit_now = true;
+        hst.join();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/AttachFailedTestBase.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+import java.nio.file.Paths;
+import jdk.test.lib.dcmd.*;
+import jdk.test.lib.Platform;
+import org.testng.annotations.Test;
+
+public abstract class AttachFailedTestBase {
+
+    public abstract void run(CommandExecutor executor);
+
+    /**
+     * Build path to shared object according to platform rules
+     */
+    public static String getSharedObjectPath(String name) {
+        String libname;
+        if (Platform.isWindows()) {
+            libname = name + ".dll";
+        } else if (Platform.isOSX()) {
+            libname = "lib" + name + ".dylib";
+        } else {
+            libname = "lib" + name + ".so";
+        }
+
+        return Paths.get(System.getProperty("test.nativepath"), libname)
+                    .toAbsolutePath()
+                    .toString();
+    }
+
+    @Test
+    public void jmx() throws Throwable {
+        run(new JMXExecutor());
+    }
+
+    @Test
+    public void cli() throws Throwable {
+        run(new PidJcmdExecutor());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/AttachIncorrectLibrary.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+import jdk.test.lib.dcmd.*;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/*
+ * @test
+ * @bug 8165736
+ * @library /test/lib
+ * @run testng AttachIncorrectLibrary
+ */
+public class AttachIncorrectLibrary extends AttachFailedTestBase {
+    @Override
+    public void run(CommandExecutor executor)  {
+        try {
+            OutputAnalyzer output = executor.execute("JVMTI.agent_load " +
+                                           getSharedObjectPath("SilverBullet"));
+            output.shouldContain(" was not loaded");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/AttachNoEntry.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+import jdk.test.lib.dcmd.*;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/*
+ * @test
+ * @bug 8165736
+ * @library /test/lib
+ * @run testng AttachNoEntry
+ */
+public class AttachNoEntry extends AttachFailedTestBase {
+    @Override
+    public void run(CommandExecutor executor)  {
+        try {
+            String libpath = getSharedObjectPath("HasNoEntryPoint");
+            OutputAnalyzer output = null;
+
+            output = executor.execute("JVMTI.agent_load " + libpath);
+            output.shouldContain("Agent_OnAttach");
+            output.shouldContain("is not available");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/AttachReturnError.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+import jdk.test.lib.dcmd.*;
+import jdk.test.lib.process.OutputAnalyzer;
+
+/*
+ * @test
+ * @bug 8165736
+ * @library /test/lib
+ * @run testng AttachReturnError
+ */
+public class AttachReturnError extends AttachFailedTestBase {
+    @Override
+    public void run(CommandExecutor executor)  {
+        try {
+            String libpath = getSharedObjectPath("ReturnError");
+            OutputAnalyzer output = null;
+
+            output = executor.execute("JVMTI.agent_load " + libpath);
+            output.shouldContain("return code: -1");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/libHasNoEntryPoint.c	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+extern int dummy() {
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/libReturnError.c	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+#include <jni.h>
+#include <jvmti.h>
+
+JNIEXPORT
+jint JNICALL Agent_OnAttach(JavaVM *vm, char *options, void *reserved) {
+  return JNI_ERR;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbAttach.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jdk.test.lib.apps.LingeredApp;
+
+/*
+ * @test
+ * @bug 8191658
+ * @summary Test clhsdb attach, detach, reattach commands
+ * @library /test/lib
+ * @run main/othervm ClhsdbAttach
+ */
+
+public class ClhsdbAttach {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Starting ClhsdbAttach test");
+
+        LingeredApp theApp = null;
+        try {
+            ClhsdbLauncher test = new ClhsdbLauncher();
+            theApp = LingeredApp.startApp();
+            System.out.println("Started LingeredApp with pid " + theApp.getPid());
+            String attach = "attach " + theApp.getPid();
+
+            List<String> cmds = List.of(
+                    "where",
+                    attach,
+                    "flags MaxJavaStackTraceDepth",
+                    "detach",
+                    "universe",
+                    "reattach",
+                    "longConstant markOopDesc::locked_value");
+
+            Map<String, List<String>> expStrMap = new HashMap<>();
+            expStrMap.put("where", List.of(
+                    "Command not valid until attached to a VM"));
+            expStrMap.put("flags MaxJavaStackTraceDepth", List.of(
+                    "MaxJavaStackTraceDepth = "));
+            expStrMap.put("universe", List.of(
+                    "Command not valid until attached to a VM"));
+            expStrMap.put("longConstant markOopDesc::locked_value", List.of(
+                    "longConstant markOopDesc::locked_value"));
+
+            test.run(-1, cmds, expStrMap, null);
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+        System.out.println("Test PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import jdk.test.lib.apps.LingeredApp;
+
+/*
+ * @test
+ * @bug 8191538
+ * @summary Test clhsdb 'field' command
+ * @library /test/lib
+ * @run main/othervm ClhsdbField
+ */
+
+public class ClhsdbField {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Starting ClhsdbField test");
+
+        LingeredApp theApp = null;
+        try {
+            ClhsdbLauncher test = new ClhsdbLauncher();
+            theApp = LingeredApp.startApp();
+            System.out.println("Started LingeredApp with pid " + theApp.getPid());
+
+            List<String> cmds = List.of("field");
+
+            Map<String, List<String>> expStrMap = new HashMap<>();
+            expStrMap.put("field", List.of(
+                "field ConstantPool _pool_holder InstanceKlass*",
+                "field InstanceKlass _methods Array<Method*>*",
+                "field InstanceKlass _constants ConstantPool*",
+                "field Klass _name Symbol*",
+                "field JavaThread _next JavaThread*",
+                "field JavaThread _osthread OSThread*",
+                "field JVMState _bci",
+                "field TenuredGeneration _the_space ContiguousSpace*",
+                "field VirtualSpace _low_boundary char*",
+                "field MethodCounters _backedge_counter InvocationCounter",
+                "field nmethod _entry_bci int",
+                "field Universe _collectedHeap CollectedHeap"));
+            test.run(theApp.getPid(), cmds, expStrMap, null);
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+        System.out.println("Test PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJhisto.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.Utils;
+
+/*
+ * @test
+ * @bug 8191658
+ * @summary Test clhsdb jhisto command
+ * @library /test/lib
+ * @run main/othervm ClhsdbJhisto
+ */
+
+public class ClhsdbJhisto {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Starting ClhsdbJhisto test");
+
+        LingeredAppWithInterface theApp = null;
+        try {
+            ClhsdbLauncher test = new ClhsdbLauncher();
+            List<String> vmArgs = new ArrayList<String>();
+            vmArgs.addAll(Utils.getVmOptions());
+
+            theApp = new LingeredAppWithInterface();
+            LingeredApp.startApp(vmArgs, theApp);
+            System.out.println("Started LingeredApp with pid " + theApp.getPid());
+
+            List<String> cmds = List.of("jhisto");
+
+            Map<String, List<String>> expStrMap = new HashMap<>();
+            expStrMap.put("jhisto", List.of(
+                    "java.lang.String",
+                    "java.util.HashMap",
+                    "java.lang.Class",
+                    "java.nio.HeapByteBuffer",
+                    "java.net.URI",
+                    "LingeredAppWithInterface",
+                    "ParselTongue",
+                    "ImmutableCollections$SetN$1"));
+
+            test.run(theApp.getPid(), cmds, expStrMap, null);
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+        System.out.println("Test PASSED");
+    }
+}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java	Thu Dec 07 11:54:55 2017 +0000
@@ -53,10 +53,12 @@
     private void attach(long lingeredAppPid)
         throws IOException {
 
-        System.out.println("Starting clhsdb against " + lingeredAppPid);
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
         launcher.addToolArg("clhsdb");
-        launcher.addToolArg("--pid=" + Long.toString(lingeredAppPid));
+        if (lingeredAppPid != -1) {
+            launcher.addToolArg("--pid=" + Long.toString(lingeredAppPid));
+            System.out.println("Starting clhsdb against " + lingeredAppPid);
+        }
 
         ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
         processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbSymbolTable.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import jdk.test.lib.apps.LingeredApp;
+
+/*
+ * @test
+ * @bug 8191538
+ * @summary Test the clhsdb 'symboltable' and 'symbol' commands
+ * @library /test/lib
+ * @run main/othervm ClhsdbSymbolTable
+ */
+
+public class ClhsdbSymbolTable {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Starting the ClhsdbSymbolTable test");
+
+        LingeredApp theApp = null;
+        try {
+            ClhsdbLauncher test = new ClhsdbLauncher();
+
+            theApp = LingeredApp.startApp();
+            System.out.println("Started LingeredApp with pid " + theApp.getPid());
+
+            // Test the symboltable command
+            List<String> cmds = List.of(
+                "symboltable main",
+                "symboltable java/lang/Class",
+                "symboltable java/lang/Object",
+                "symboltable java/lang/String",
+                "symboltable java/util/List",
+                "symboltable jdk/test/lib/apps/LingeredApp");
+
+            Map<String, List<String>> expStrMap = new HashMap<>();
+            expStrMap.put("symboltable main", List.of(
+                "sun.jvm.hotspot.oops.Symbol@"));
+            expStrMap.put("symboltable java/lang/Class", List.of(
+                "sun.jvm.hotspot.oops.Symbol@"));
+            expStrMap.put("symboltable java/lang/Object", List.of(
+                "sun.jvm.hotspot.oops.Symbol@"));
+            expStrMap.put("symboltable java/lang/String", List.of(
+                "sun.jvm.hotspot.oops.Symbol@"));
+            expStrMap.put("symboltable java/util/List", List.of(
+                "sun.jvm.hotspot.oops.Symbol@"));
+            expStrMap.put("symboltable jdk/test/lib/apps/LingeredApp", List.of(
+                "sun.jvm.hotspot.oops.Symbol@"));
+            String consolidatedOutput =
+                test.run(theApp.getPid(), cmds, expStrMap, null);
+
+            // Test the 'symbol' command passing in the address obtained from
+            // the 'symboltable' command
+            expStrMap = new HashMap<>();
+            cmds = new ArrayList<String>();
+            int expectedStringsIdx = 0;
+            String expectedStrings[] = {"#main",
+                                        "#java/lang/Class", "#java/lang/Object",
+                                        "#java/lang/String", "#java/util/List",
+                                        "#jdk/test/lib/apps/LingeredApp"};
+            if (consolidatedOutput != null) {
+                // Output could be null due to attach permission issues
+                // and if we are skipping this.
+                String[] singleCommandOutputs = consolidatedOutput.split("hsdb>");
+
+                for (String singleCommandOutput : singleCommandOutputs) {
+                    if (singleCommandOutput.contains("@")) {
+                        String[] tokens = singleCommandOutput.split("@");
+                        String addressString = tokens[1].replace("\n","");
+
+                        // tokens[1] represents the address of the symbol
+                        String cmd = "symbol " + addressString;
+                        cmds.add(cmd);
+                        expStrMap.put(cmd, List.of
+                            (expectedStrings[expectedStringsIdx++]));
+                    }
+                }
+                test.run(theApp.getPid(), cmds, expStrMap, null);
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+        System.out.println("Test PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import jdk.test.lib.apps.LingeredApp;
+
+/*
+ * @test
+ * @bug 8191538
+ * @summary Test clhsdb 'vmstructsdump' command
+ * @library /test/lib
+ * @run main/othervm ClhsdbVmStructsDump
+ */
+
+public class ClhsdbVmStructsDump {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Starting ClhsdbVmStructsDump test");
+
+        LingeredApp theApp = null;
+        try {
+            ClhsdbLauncher test = new ClhsdbLauncher();
+            theApp = LingeredApp.startApp();
+            System.out.println("Started LingeredApp with pid " + theApp.getPid());
+
+            List<String> cmds = List.of("vmstructsdump");
+
+            Map<String, List<String>> expStrMap = new HashMap<>();
+            expStrMap.put("vmstructsdump", List.of(
+                "field ConstantPool _pool_holder InstanceKlass*",
+                "field InstanceKlass _methods Array<Method*>*",
+                "field InstanceKlass _constants ConstantPool*",
+                "field Klass _name Symbol*",
+                "type ClassLoaderData* null",
+                "type DictionaryEntry KlassHashtableEntry",
+                "field JavaThread _next JavaThread*",
+                "field JavaThread _osthread OSThread*",
+                "type TenuredGeneration CardGeneration",
+                "field JVMState _bci",
+                "type Universe null",
+                "type ConstantPoolCache MetaspaceObj"));
+            test.run(theApp.getPid(), cmds, expStrMap, null);
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+        System.out.println("Test PASSED");
+    }
+}
--- a/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -56,9 +56,9 @@
             pb.command(jhsdbLauncher.getCommand());
             Process jhsdb = pb.start();
 
-            jhsdb.waitFor();
+            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
 
-            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
+            jhsdb.waitFor();
 
             System.out.println(out.getStdout());
             System.err.println(out.getStderr());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import jdk.test.lib.apps.LingeredApp;
+
+
+public class LingeredAppWithLock extends LingeredApp {
+
+    public static void lockMethod(Object lock) {
+        synchronized (lock) {
+            try {
+                Thread.sleep(300000);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+        Thread classLock1 = new Thread(() -> lockMethod(LingeredAppWithLock.class));
+        Thread classLock2 = new Thread(() -> lockMethod(LingeredAppWithLock.class));
+        Thread objectLock = new Thread(() -> lockMethod(classLock1));
+        Thread primitiveLock = new Thread(() -> lockMethod(int.class));
+
+        classLock1.start();
+        classLock2.start();
+        objectLock.start();
+        primitiveLock.start();
+
+        LingeredApp.main(args);
+    }
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/TestClassDump.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/*
+ * @test
+ * @bug 8184982
+ * @summary Test ClassDump tool
+ * @library /test/lib
+ * @run main/othervm TestClassDump
+ */
+
+public class TestClassDump {
+
+    private static void dumpClass(long lingeredAppPid)
+        throws IOException {
+
+        ProcessBuilder pb;
+        OutputAnalyzer output;
+
+        pb = ProcessTools.createJavaProcessBuilder(
+                "-Dsun.jvm.hotspot.tools.jcore.outputDir=jtreg_classes",
+                "-m", "jdk.hotspot.agent/sun.jvm.hotspot.tools.jcore.ClassDump", String.valueOf(lingeredAppPid));
+        output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+        if (!Files.isDirectory(Paths.get("jtreg_classes"))) {
+            throw new RuntimeException("jtreg_classes directory not found");
+        }
+        if (Files.notExists(Paths.get("jtreg_classes", "java", "lang", "Integer.class"))) {
+            throw new RuntimeException("jtreg_classes/java/lang/Integer.class not found");
+        }
+        if (Files.notExists(Paths.get("jtreg_classes", "jdk", "test", "lib", "apps", "LingeredApp.class"))) {
+            throw new RuntimeException("jtreg_classes/jdk/test/lib/apps/LingeredApp.class not found");
+        }
+        if (Files.notExists(Paths.get("jtreg_classes", "sun", "net", "util", "URLUtil.class"))) {
+            throw new RuntimeException("jtreg_classes/sun/net/util/URLUtil.class not found");
+        }
+
+        pb = ProcessTools.createJavaProcessBuilder(
+                "-Dsun.jvm.hotspot.tools.jcore.outputDir=jtreg_classes2",
+                "-Dsun.jvm.hotspot.tools.jcore.PackageNameFilter.pkgList=jdk,sun",
+                "-m", "jdk.hotspot.agent/sun.jvm.hotspot.tools.jcore.ClassDump", String.valueOf(lingeredAppPid));
+        output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+        if (Files.exists(Paths.get("jtreg_classes2", "java", "math", "BigInteger.class"))) {
+            throw new RuntimeException("jtreg_classes2/java/math/BigInteger.class not expected");
+        }
+        if (Files.notExists(Paths.get("jtreg_classes2", "sun", "util", "calendar", "BaseCalendar.class"))) {
+            throw new RuntimeException("jtreg_classes2/sun/util/calendar/BaseCalendar.class not found");
+        }
+        if (Files.notExists(Paths.get("jtreg_classes2", "jdk", "internal", "vm", "PostVMInitHook.class"))) {
+            throw new RuntimeException("jtreg_classes2/jdk/internal/vm/PostVMInitHook.class not found");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!Platform.shouldSAAttach()) {
+            // Silently skip the test if we don't have enough permissions to attach
+            System.out.println("SA attach not expected to work - test skipped.");
+            return;
+        }
+
+        LingeredApp theApp = null;
+        try {
+            theApp = LingeredApp.startApp();
+            long pid = theApp.getPid();
+            System.out.println("Started LingeredApp with pid " + pid);
+            dumpClass(pid);
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
+        System.out.println("Test PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/TestClhsdbJstackLock.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.List;
+import java.io.File;
+import java.io.IOException;
+import java.util.stream.Collectors;
+import java.io.OutputStream;
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Utils;
+import jdk.test.lib.Asserts;
+
+/*
+ * @test
+ * @library /test/lib
+ * @run main/othervm TestClhsdbJstackLock
+ */
+
+public class TestClhsdbJstackLock {
+
+    private static final String JSTACK_OUT_FILE = "jstack_out.txt";
+
+    private static void verifyJStackOutput() throws Exception {
+
+        Exception unexpected = null;
+        File jstackFile = new File(JSTACK_OUT_FILE);
+        Asserts.assertTrue(jstackFile.exists() && jstackFile.isFile(),
+                           "File with jstack output not created: " +
+                           jstackFile.getAbsolutePath());
+        try {
+            Scanner scanner = new Scanner(jstackFile);
+
+            boolean classLockOwnerFound = false;
+            boolean classLockWaiterFound = false;
+            boolean objectLockOwnerFound = false;
+            boolean primitiveLockOwnerFound = false;
+
+            while (scanner.hasNextLine()) {
+                String line = scanner.nextLine();
+                System.out.println(line);
+
+                if (line.contains("missing reason for ")) {
+                    unexpected = new RuntimeException("Unexpected msg: missing reason for ");
+                    break;
+                }
+                if (line.matches("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for LingeredAppWithLock\\)$")) {
+                    classLockOwnerFound = true;
+                }
+                if (line.matches("^\\s+- waiting to lock <0x[0-9a-f]+> \\(a java\\.lang\\.Class for LingeredAppWithLock\\)$")) {
+                    classLockWaiterFound = true;
+                }
+                if (line.matches("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Thread\\)$")) {
+                    objectLockOwnerFound = true;
+                }
+                if (line.matches("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for int\\)$")) {
+                    primitiveLockOwnerFound = true;
+                }
+            }
+
+            if (!classLockOwnerFound || !classLockWaiterFound ||
+                !objectLockOwnerFound || !primitiveLockOwnerFound) {
+                unexpected = new RuntimeException(
+                      "classLockOwnerFound = " + classLockOwnerFound +
+                      ", classLockWaiterFound = " + classLockWaiterFound +
+                      ", objectLockOwnerFound = " + objectLockOwnerFound +
+                      ", primitiveLockOwnerFound = " + primitiveLockOwnerFound);
+            }
+            if (unexpected != null) {
+                throw unexpected;
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            jstackFile.delete();
+        }
+    }
+
+    private static void startClhsdbForLock(long lingeredAppPid) throws Exception {
+
+        Process p;
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+        launcher.addToolArg("clhsdb");
+        launcher.addToolArg("--pid");
+        launcher.addToolArg(Long.toString(lingeredAppPid));
+
+        ProcessBuilder pb = new ProcessBuilder();
+        pb.command(launcher.getCommand());
+        System.out.println(pb.command().stream().collect(Collectors.joining(" ")));
+
+        try {
+            p = pb.start();
+        } catch (Exception attachE) {
+            throw new Error("Couldn't start jhsdb or attach to LingeredApp : " + attachE);
+        }
+
+        // Issue the 'jstack' input at the clhsdb prompt.
+        OutputStream input = p.getOutputStream();
+        String str = "jstack > " + JSTACK_OUT_FILE + "\nquit\n";
+        try {
+            input.write(str.getBytes());
+            input.flush();
+        } catch (IOException ioe) {
+            throw new Error("Problem issuing the jstack command: " + str, ioe);
+        }
+
+        OutputAnalyzer output = new OutputAnalyzer(p);
+
+        try {
+            p.waitFor();
+        } catch (InterruptedException ie) {
+            p.destroyForcibly();
+            throw new Error("Problem awaiting the child process: " + ie, ie);
+        }
+
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void main (String... args) throws Exception {
+
+        LingeredApp app = null;
+
+        if (!Platform.shouldSAAttach()) {
+            System.out.println("SA attach not expected to work - test skipped.");
+            return;
+        }
+
+        try {
+            List<String> vmArgs = new ArrayList<String>(Utils.getVmOptions());
+
+            app = new LingeredAppWithLock();
+            LingeredApp.startApp(vmArgs, app);
+            System.out.println ("Started LingeredApp with pid " + app.getPid());
+            startClhsdbForLock(app.getPid());
+            verifyJStackOutput();
+        } finally {
+            LingeredApp.stopApp(app);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.test.lib.apps.LingeredApp;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.Utils;
+
+/*
+ * @test
+ * @library /test/lib
+ * @run main/othervm TestJhsdbJstackLock
+ */
+
+public class TestJhsdbJstackLock {
+
+    public static void main (String... args) throws Exception {
+
+        LingeredApp app = null;
+
+        if (!Platform.shouldSAAttach()) {
+            System.out.println("SA attach not expected to work - test skipped.");
+            return;
+        }
+
+        try {
+            List<String> vmArgs = new ArrayList<String>(Utils.getVmOptions());
+
+            app = new LingeredAppWithLock();
+            LingeredApp.startApp(vmArgs, app);
+            System.out.println ("Started LingeredApp with pid " + app.getPid());
+
+            JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
+            launcher.addToolArg("jstack");
+            launcher.addToolArg("--pid");
+            launcher.addToolArg(Long.toString(app.getPid()));
+
+            ProcessBuilder pb = new ProcessBuilder();
+            pb.command(launcher.getCommand());
+            Process jhsdb = pb.start();
+            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
+
+            jhsdb.waitFor();
+
+            System.out.println(out.getStdout());
+            System.err.println(out.getStderr());
+
+            out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for LingeredAppWithLock\\)$");
+            out.shouldMatch("^\\s+- waiting to lock <0x[0-9a-f]+> \\(a java\\.lang\\.Class for LingeredAppWithLock\\)$");
+            out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Thread\\)$");
+            out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for int\\)$");
+            out.stderrShouldBeEmpty();
+
+            System.out.println("Test Completed");
+        } finally {
+            LingeredApp.stopApp(app);
+        }
+    }
+}
--- a/test/hotspot/jtreg/serviceability/sa/TestPrintMdo.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/TestPrintMdo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -132,22 +132,16 @@
             throw new Error("Problem issuing the printmdo command: " + str, ioe);
         }
 
+        OutputAnalyzer output = new OutputAnalyzer(p);
+
         try {
             p.waitFor();
         } catch (InterruptedException ie) {
+            p.destroyForcibly();
             throw new Error("Problem awaiting the child process: " + ie, ie);
         }
 
-        int exitValue = p.exitValue();
-        if (exitValue != 0) {
-            String output;
-            try {
-                output = new OutputAnalyzer(p).getOutput();
-            } catch (IOException ioe) {
-                throw new Error("Can't get failed clhsdb process output: " + ioe, ioe);
-            }
-            throw new AssertionError("clhsdb wasn't run successfully: " + output);
-        }
+        output.shouldHaveExitValue(0);
     }
 
     public static void main (String... args) throws Exception {
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java	Thu Dec 07 11:54:55 2017 +0000
@@ -123,14 +123,15 @@
                         .collect(Collectors.joining(" "));
                 String phase = phaseName(classStart);
                 Path out = Paths.get(".", phase + ".out");
+                Path err = Paths.get(".", phase + ".err");
                 System.out.printf("%s %dms START : [%s]%n" +
                         "cout/cerr are redirected to %s%n",
                         phase, TimeUnit.NANOSECONDS.toMillis(System.nanoTime()),
-                        commandLine, out);
-                int exitCode = pb.redirectErrorStream(true)
-                        .redirectOutput(out.toFile())
-                        .start()
-                        .waitFor();
+                        commandLine, phase);
+                int exitCode = pb.redirectOutput(out.toFile())
+                                 .redirectError(err.toFile())
+                                 .start()
+                                 .waitFor();
                 System.out.printf("%s %dms END : exit code = %d%n",
                         phase, TimeUnit.NANOSECONDS.toMillis(System.nanoTime()),
                         exitCode);
--- a/test/hotspot/jtreg/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java	Thu Dec 07 11:54:55 2017 +0000
@@ -51,7 +51,7 @@
         VM_TYPE("isClient", "isServer", "isGraal", "isMinimal", "isZero", "isEmbedded"),
         MODE("isInt", "isMixed", "isComp"),
         IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", "isSlowDebugBuild",
-                "shouldSAAttach", "isTieredSupported");
+                "shouldSAAttach", "isTieredSupported", "areCustomLoadersSupportedForCDS");
 
         public final List<String> methodNames;
 
@@ -106,7 +106,7 @@
                     && m.getReturnType() == boolean.class) {
                 Asserts.assertTrue(allMethods.contains(m.getName()),
                         "All Platform's methods with signature '():Z' should "
-                                + "be tested ");
+                                + "be tested. Missing: " + m.getName());
             }
         }
     }
--- a/test/jdk/ProblemList.txt	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/ProblemList.txt	Thu Dec 07 11:54:55 2017 +0000
@@ -124,8 +124,6 @@
 
 java/lang/StringCoding/CheckEncodings.sh                        7008363 generic-all
 
-jdk/internal/misc/JavaLangAccess/NewUnsafeString.java           8176188 generic-all
-
 java/lang/String/nativeEncoding/StringPlatformChars.java        8182569 windows-all,solaris-all
 
 ############################################################################
--- a/test/jdk/TEST.groups	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/TEST.groups	Thu Dec 07 11:54:55 2017 +0000
@@ -89,7 +89,6 @@
 jdk_util_other = \
     java/util \
     sun/util \
-    jdk/internal/util \
     -:jdk_collections \
     -:jdk_concurrent \
     -:jdk_stream
--- a/test/jdk/com/sun/tools/attach/StartManagementAgent.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/com/sun/tools/attach/StartManagementAgent.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -99,7 +99,7 @@
         } catch(AttachOperationFailedException ex) {
             // We expect parsing of "apa" above to fail, but if the file path
             // can't be read we get a different exception message
-            if (!ex.getMessage().contains("Invalid com.sun.management.jmxremote.port number")) {
+            if (!ex.getMessage().contains("NumberFormatException: For input string: \"apa\"")) {
                 throw ex;
             }
             ex.printStackTrace(System.err);
--- a/test/jdk/java/awt/Component/GetScreenLocTest/ComponentGetLocationOnScreenNPETest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/java/awt/Component/GetScreenLocTest/ComponentGetLocationOnScreenNPETest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,7 @@
  * @test
  * @bug 8189204
  * @summary Possible NPE in Component::getLocationOnScreen()
+ * @key headful
  * @run main ComponentGetLocationOnScreenNPETest
  */
 
--- a/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -21,9 +21,11 @@
  * questions.
  */
 
-/* @test
+/**
+ * @test
  * @bug 8190230
  * @summary [macosx] Order of overlapping of modal dialogs is wrong
+ * @key headful
  * @run main SiblingChildOrderTest
  */
 
--- a/test/jdk/java/awt/Focus/FocusTransitionTest/FocusTransitionTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/java/awt/Focus/FocusTransitionTest/FocusTransitionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -21,10 +21,12 @@
  * questions.
  */
 
-/* @test
+/**
+ * @test
  * @bug 8155197
  * @summary Tests whether the value of mostRecentFocusOwner for a window is correct, if
  *          another window is displayed during focus transition
+ * @key headful
  * @library ../../regtesthelpers
  * @build Util
  * @run main FocusTransitionTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/io/Reader/TransferTo.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2017, 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 source 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 source 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 Franklsource 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.
+ */
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.Random;
+
+import jdk.test.lib.RandomFactory;
+
+import static java.lang.String.format;
+
+/*
+ * @test
+ * @bug 8191706
+ * @summary tests whether java.io.Reader.transferTo conforms to its
+ *          contract defined source the javadoc
+ * @library /test/lib
+ * @build jdk.test.lib.RandomFactory
+ * @run main TransferTo
+ * @key randomness
+ * @author Patrick Reinhart
+ */
+public class TransferTo {
+
+    private static Random generator = RandomFactory.getRandom();
+
+    public static void main(String[] args) throws IOException {
+        ifOutIsNullThenNpeIsThrown();
+        ifExceptionInInputNeitherStreamIsClosed();
+        ifExceptionInOutputNeitherStreamIsClosed();
+        onReturnNeitherStreamIsClosed();
+        onReturnInputIsAtEnd();
+        contents();
+    }
+
+    private static void ifOutIsNullThenNpeIsThrown() throws IOException {
+        try (Reader in = input()) {
+            assertThrowsNPE(() -> in.transferTo(null), "out");
+        }
+
+        try (Reader in = input((char) 1)) {
+            assertThrowsNPE(() -> in.transferTo(null), "out");
+        }
+
+        try (Reader in = input((char) 1, (char) 2)) {
+            assertThrowsNPE(() -> in.transferTo(null), "out");
+        }
+
+        Reader in = null;
+        try {
+            Reader fin = in = new ThrowingReader();
+            // null check should precede everything else:
+            // Reader shouldn't be touched if Writer is null
+            assertThrowsNPE(() -> fin.transferTo(null), "out");
+        } finally {
+            if (in != null)
+                try {
+                    in.close();
+                } catch (IOException ignored) { }
+        }
+    }
+
+    private static void ifExceptionInInputNeitherStreamIsClosed()
+            throws IOException {
+        transferToThenCheckIfAnyClosed(input(0, new char[]{1, 2, 3}), output());
+        transferToThenCheckIfAnyClosed(input(1, new char[]{1, 2, 3}), output());
+        transferToThenCheckIfAnyClosed(input(2, new char[]{1, 2, 3}), output());
+    }
+
+    private static void ifExceptionInOutputNeitherStreamIsClosed()
+            throws IOException {
+        transferToThenCheckIfAnyClosed(input(new char[]{1, 2, 3}), output(0));
+        transferToThenCheckIfAnyClosed(input(new char[]{1, 2, 3}), output(1));
+        transferToThenCheckIfAnyClosed(input(new char[]{1, 2, 3}), output(2));
+    }
+
+    private static void transferToThenCheckIfAnyClosed(Reader input,
+                                                       Writer output)
+            throws IOException {
+        try (CloseLoggingReader in = new CloseLoggingReader(input);
+             CloseLoggingWriter out =
+                     new CloseLoggingWriter(output)) {
+            boolean thrown = false;
+            try {
+                in.transferTo(out);
+            } catch (IOException ignored) {
+                thrown = true;
+            }
+            if (!thrown)
+                throw new AssertionError();
+
+            if (in.wasClosed() || out.wasClosed()) {
+                throw new AssertionError();
+            }
+        }
+    }
+
+    private static void onReturnNeitherStreamIsClosed()
+            throws IOException {
+        try (CloseLoggingReader in =
+                     new CloseLoggingReader(input(new char[]{1, 2, 3}));
+             CloseLoggingWriter out =
+                     new CloseLoggingWriter(output())) {
+
+            in.transferTo(out);
+
+            if (in.wasClosed() || out.wasClosed()) {
+                throw new AssertionError();
+            }
+        }
+    }
+
+    private static void onReturnInputIsAtEnd() throws IOException {
+        try (Reader in = input(new char[]{1, 2, 3});
+             Writer out = output()) {
+
+            in.transferTo(out);
+
+            if (in.read() != -1) {
+                throw new AssertionError();
+            }
+        }
+    }
+
+    private static void contents() throws IOException {
+        checkTransferredContents(new char[0]);
+        checkTransferredContents(createRandomChars(1024, 4096));
+        // to span through several batches
+        checkTransferredContents(createRandomChars(16384, 16384));
+    }
+
+    private static void checkTransferredContents(char[] chars)
+            throws IOException {
+        try (Reader in = input(chars);
+             StringWriter out = new StringWriter()) {
+            in.transferTo(out);
+
+            char[] outChars = out.toString().toCharArray();
+            if (!Arrays.equals(chars, outChars)) {
+                throw new AssertionError(
+                        format("chars.length=%s, outChars.length=%s",
+                                chars.length, outChars.length));
+            }
+        }
+    }
+
+    private static char[] createRandomChars(int min, int maxRandomAdditive) {
+        char[] chars = new char[min + generator.nextInt(maxRandomAdditive)];
+        for (int index=0; index<chars.length; index++) {
+            chars[index] = (char)generator.nextInt();
+        }
+        return chars;
+    }
+
+    private static Writer output() {
+        return output(-1);
+    }
+
+    private static Writer output(int exceptionPosition) {
+        return new Writer() {
+
+            int pos;
+
+            @Override
+            public void write(int b) throws IOException {
+                if (pos++ == exceptionPosition)
+                    throw new IOException();
+            }
+
+            @Override
+            public void write(char[] chars, int off, int len) throws IOException {
+                for (int i=0; i<len; i++) {
+                    write(chars[off + i]);
+                }
+            }
+
+            @Override
+            public Writer append(CharSequence csq, int start, int end) throws IOException {
+                for (int i = start; i < end; i++) {
+                    write(csq.charAt(i));
+                }
+                return this;
+            }
+
+            @Override
+            public void flush() throws IOException {
+            }
+
+            @Override
+            public void close() throws IOException {
+            }
+        };
+    }
+
+    private static Reader input(char... chars) {
+        return input(-1, chars);
+    }
+
+    private static Reader input(int exceptionPosition, char... chars) {
+        return new Reader() {
+
+            int pos;
+
+            @Override
+            public int read() throws IOException {
+                if (pos == exceptionPosition) {
+                    throw new IOException();
+                }
+
+                if (pos >= chars.length)
+                    return -1;
+                return chars[pos++];
+            }
+
+            @Override
+            public int read(char[] cbuf, int off, int len) throws IOException {
+                int c = read();
+                if (c == -1) {
+                    return -1;
+                }
+                cbuf[off] = (char)c;
+
+                int i = 1;
+                for (; i < len ; i++) {
+                    c = read();
+                    if (c == -1) {
+                        break;
+                    }
+                    cbuf[off + i] = (char)c;
+                }
+                return i;
+            }
+
+            @Override
+            public void close() throws IOException {
+            }
+        };
+    }
+
+    private static class ThrowingReader extends Reader {
+
+        boolean closed;
+
+        @Override
+        public int read(char[] b, int off, int len) throws IOException {
+            throw new IOException();
+        }
+
+        @Override
+        public void close() throws IOException {
+            if (!closed) {
+                closed = true;
+                throw new IOException();
+            }
+        }
+        @Override
+        public int read() throws IOException {
+            throw new IOException();
+        }
+    }
+
+    private static class CloseLoggingReader extends FilterReader {
+
+        boolean closed;
+
+        CloseLoggingReader(Reader in) {
+            super(in);
+        }
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+            super.close();
+        }
+
+        boolean wasClosed() {
+            return closed;
+        }
+    }
+
+    private static class CloseLoggingWriter extends FilterWriter {
+
+        boolean closed;
+
+        CloseLoggingWriter(Writer out) {
+            super(out);
+        }
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+            super.close();
+        }
+
+        boolean wasClosed() {
+            return closed;
+        }
+    }
+
+    public interface Thrower {
+        public void run() throws Throwable;
+    }
+
+    public static void assertThrowsNPE(Thrower thrower, String message) {
+        assertThrows(thrower, NullPointerException.class, message);
+    }
+
+    public static <T extends Throwable> void assertThrows(Thrower thrower,
+                                                          Class<T> throwable,
+                                                          String message) {
+        Throwable thrown;
+        try {
+            thrower.run();
+            thrown = null;
+        } catch (Throwable caught) {
+            thrown = caught;
+        }
+
+        if (!throwable.isInstance(thrown)) {
+            String caught = thrown == null ?
+                    "nothing" : thrown.getClass().getCanonicalName();
+            throw new AssertionError(
+                    format("Expected to catch %s, but caught %s",
+                            throwable, caught), thrown);
+        }
+
+        if (thrown != null && !message.equals(thrown.getMessage())) {
+            throw new AssertionError(
+                    format("Expected exception message to be '%s', but it's '%s'",
+                            message, thrown.getMessage()));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/ClassLoader/RecursiveSystemLoader.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test
+ * @bug 8187222
+ * @run main/othervm -Djava.system.class.loader=RecursiveSystemLoader RecursiveSystemLoader
+ * @summary Test for IllegalStateException if a custom system loader recursively calls getSystemClassLoader()
+ */
+public class RecursiveSystemLoader extends ClassLoader {
+    public static void main(String[] args) {
+        ClassLoader sys = ClassLoader.getSystemClassLoader();
+        if (!(sys instanceof RecursiveSystemLoader)) {
+            throw new RuntimeException("Unexpected system classloader: " + sys);
+        }
+    }
+    public RecursiveSystemLoader(ClassLoader classLoader) {
+        super("RecursiveSystemLoader", classLoader);
+
+        // Calling ClassLoader.getSystemClassLoader() before the VM is booted
+        // should throw an IllegalStateException.
+        try {
+            ClassLoader.getSystemClassLoader();
+        } catch(IllegalStateException ise) {
+            System.err.println("Caught expected exception:");
+            ise.printStackTrace();
+            return;
+        }
+        throw new RuntimeException("Expected IllegalStateException was not thrown.");
+    }
+
+    @Override
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        return super.loadClass(name);
+    }
+}
--- a/test/jdk/java/lang/ModuleLayer/LayerAndLoadersTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/java/lang/ModuleLayer/LayerAndLoadersTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -52,6 +52,7 @@
 import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.stream.Collectors;
+
 import jdk.test.lib.compiler.CompilerUtils;
 
 import org.testng.annotations.BeforeTest;
@@ -78,7 +79,7 @@
      * Basic test of ModuleLayer.defineModulesWithOneLoader
      *
      * Test scenario:
-     *   m1 requires m2 and m3
+     * m1 requires m2 and m3
      */
     public void testWithOneLoader() throws Exception {
         Configuration cf = resolve("m1");
@@ -105,7 +106,7 @@
      * Basic test of ModuleLayer.defineModulesWithManyLoaders
      *
      * Test scenario:
-     *   m1 requires m2 and m3
+     * m1 requires m2 and m3
      */
     public void testWithManyLoaders() throws Exception {
         Configuration cf = resolve("m1");
@@ -136,9 +137,9 @@
      * modules is a service provider module.
      *
      * Test scenario:
-     *    m1 requires m2 and m3
-     *    m1 uses S
-     *    m4 provides S with ...
+     * m1 requires m2 and m3
+     * m1 uses S
+     * m4 provides S with ...
      */
     public void testServicesWithOneLoader() throws Exception {
         Configuration cf = resolveAndBind("m1");
@@ -175,9 +176,9 @@
      * modules is a service provider module.
      *
      * Test scenario:
-     *    m1 requires m2 and m3
-     *    m1 uses S
-     *    m4 provides S with ...
+     * m1 requires m2 and m3
+     * m1 uses S
+     * m4 provides S with ...
      */
     public void testServicesWithManyLoaders() throws Exception {
         Configuration cf = resolveAndBind("m1");
@@ -234,7 +235,7 @@
         ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent);
         testLoad(layer, cn);
 
-         // one loader with boot loader as parent
+        // one loader with boot loader as parent
         layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, null);
         testLoadFail(layer, cn);
 
@@ -252,21 +253,21 @@
      * Test defineModulesWithXXX when modules that have overlapping packages.
      *
      * Test scenario:
-     *   m1 exports p
-     *   m2 exports p
+     * m1 exports p
+     * m2 exports p
      */
     public void testOverlappingPackages() {
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.newModule("m1").exports("p").build();
+                = ModuleDescriptor.newModule("m1").exports("p").build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.newModule("m2").exports("p").build();
+                = ModuleDescriptor.newModule("m2").exports("p").build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         Configuration cf = ModuleLayer.boot()
-            .configuration()
-            .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
+                .configuration()
+                .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
 
         // cannot define both module m1 and m2 to the same class loader
         try {
@@ -284,35 +285,35 @@
      * Test ModuleLayer.defineModulesWithXXX with split delegation.
      *
      * Test scenario:
-     *   layer1: m1 exports p, m2 exports p
-     *   layer2: m3 reads m1, m4 reads m2
+     * layer1: m1 exports p, m2 exports p
+     * layer2: m3 reads m1, m4 reads m2
      */
     public void testSplitDelegation() {
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.newModule("m1").exports("p").build();
+                = ModuleDescriptor.newModule("m1").exports("p").build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.newModule("m2").exports("p").build();
+                = ModuleDescriptor.newModule("m2").exports("p").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         Configuration cf1 = ModuleLayer.boot()
-            .configuration()
-            .resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
+                .configuration()
+                .resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
 
         ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);
         checkLayer(layer1, "m1", "m2");
 
         ModuleDescriptor descriptor3
-            = ModuleDescriptor.newModule("m3").requires("m1").build();
+                = ModuleDescriptor.newModule("m3").requires("m1").build();
 
         ModuleDescriptor descriptor4
-            = ModuleDescriptor.newModule("m4").requires("m2").build();
+                = ModuleDescriptor.newModule("m4").requires("m2").build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 
         Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(),
-                                                Set.of("m3", "m4"));
+                Set.of("m3", "m4"));
 
         // package p cannot be supplied by two class loaders
         try {
@@ -331,8 +332,8 @@
      * named modules in the parent layer.
      *
      * Test scenario:
-     *   layer1: m1, m2, m3 => same loader
-     *   layer2: m1, m2, m4 => same loader
+     * layer1: m1, m2, m3 => same loader
+     * layer2: m1, m2, m4 => same loader
      */
     public void testOverriding1() throws Exception {
         Configuration cf1 = resolve("m1");
@@ -342,7 +343,7 @@
 
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
-                                                Set.of("m1"));
+                Set.of("m1"));
 
         ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
         checkLayer(layer2, "m1", "m2", "m3");
@@ -378,8 +379,8 @@
      * named modules in the parent layer.
      *
      * Test scenario:
-     *   layer1: m1, m2, m3 => loader pool
-     *   layer2: m1, m2, m3 => loader pool
+     * layer1: m1, m2, m3 => loader pool
+     * layer2: m1, m2, m3 => loader pool
      */
     public void testOverriding2() throws Exception {
         Configuration cf1 = resolve("m1");
@@ -389,7 +390,7 @@
 
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
-                                                Set.of("m1"));
+                Set.of("m1"));
 
         ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
         checkLayer(layer2, "m1", "m2", "m3");
@@ -482,7 +483,7 @@
         ModuleFinder finder = finderFor("m1", "m3");
 
         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
-                                                Set.of("m1"));
+                Set.of("m1"));
 
         ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
         checkLayer(layer2, "m1", "m3");
@@ -517,7 +518,7 @@
         ModuleFinder finder = finderFor("m1", "m3");
 
         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
-                                                Set.of("m1"));
+                Set.of("m1"));
 
         ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
         checkLayer(layer2, "m1", "m3");
@@ -550,18 +551,27 @@
         assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);
     }
 
-
     /**
      * Basic test for locating resources with a class loader created by
      * defineModulesWithOneLoader.
      */
     public void testResourcesWithOneLoader() throws Exception {
+        testResourcesWithOneLoader(ClassLoader.getSystemClassLoader());
+        testResourcesWithOneLoader(null);
+    }
+
+    /**
+     * Test locating resources with the class loader created by
+     * defineModulesWithOneLoader. The class loader has the given class
+     * loader as its parent.
+     */
+    void testResourcesWithOneLoader(ClassLoader parent) throws Exception {
         Configuration cf = resolve("m1");
-        ClassLoader scl = ClassLoader.getSystemClassLoader();
-        ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
+        ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent);
 
         ClassLoader loader = layer.findLoader("m1");
         assertNotNull(loader);
+        assertTrue(loader.getParent() == parent);
 
         // check that getResource and getResources are consistent
         URL url1 = loader.getResource("module-info.class");
@@ -607,14 +617,24 @@
      * defineModulesWithManyLoaders.
      */
     public void testResourcesWithManyLoaders() throws Exception {
+        testResourcesWithManyLoaders(ClassLoader.getSystemClassLoader());
+        testResourcesWithManyLoaders(null);
+    }
+
+    /**
+     * Test locating resources with class loaders created by
+     * defineModulesWithManyLoaders. The class loaders have the given class
+     * loader as their parent.
+     */
+    void testResourcesWithManyLoaders(ClassLoader parent) throws Exception {
         Configuration cf = resolve("m1");
-        ClassLoader scl = ClassLoader.getSystemClassLoader();
-        ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
+        ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, parent);
 
         for (Module m : layer.modules()) {
             String name = m.getName();
             ClassLoader loader = m.getClassLoader();
             assertNotNull(loader);
+            assertTrue(loader.getParent() == parent);
 
             // getResource should find the module-info.class for the module
             URL url = loader.getResource("module-info.class");
--- a/test/jdk/java/text/Format/MessageFormat/MessageRegression.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/java/text/Format/MessageFormat/MessageRegression.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -25,7 +25,7 @@
  * @test
  * @bug 4031438 4058973 4074764 4094906 4104976 4105380 4106659 4106660 4106661
  * 4111739 4112104 4113018 4114739 4114743 4116444 4118592 4118594 4120552
- * 4142938 4169959 4232154 4293229
+ * 4142938 4169959 4232154 4293229 8187551
  * @summary Regression tests for MessageFormat and associated classes
  * @library /java/text/testlib
  * @run main MessageRegression
@@ -642,4 +642,44 @@
                     expected + "\", got \"" + result + "\"");
         }
     }
+
+    /**
+     * @bug 8187551
+     * test MessageFormat.setFormat() method to throw AIOOBE on invalid index.
+     */
+    public void test8187551() {
+        //invalid cases ("pattern", "invalid format element index")
+        String[][] invalidCases = {{"The disk \"{1}\" contains {0}.", "2"},
+                {"The disk \"{1}\" contains {0}.", "9"},
+                {"On {1}, there are {0} and {2} folders", "3"}};
+
+        //invalid cases (must throw exception)
+        Arrays.stream(invalidCases).forEach(entry -> messageSetFormat(entry[0],
+                Integer.valueOf(entry[1])));
+    }
+
+    // test MessageFormat.setFormat() method for the given pattern and
+    // format element index
+    private void messageSetFormat(String pattern, int elemIndex) {
+        MessageFormat form = new MessageFormat(pattern);
+
+        double[] fileLimits = {0, 1, 2};
+        String[] filePart = {"no files", "one file", "{0,number} files"};
+        ChoiceFormat fileForm = new ChoiceFormat(fileLimits, filePart);
+
+        boolean AIOOBEThrown = false;
+        try {
+            form.setFormat(elemIndex, fileForm);
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            AIOOBEThrown = true;
+        }
+
+        if (!AIOOBEThrown) {
+            throw new RuntimeException("[FAILED: Must throw" +
+                    " ArrayIndexOutOfBoundsException for" +
+                    " invalid index " + elemIndex + " used in" +
+                    " MessageFormat.setFormat(index, format)]");
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/security/HashedPasswordFileTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+ /* @test
+ * @bug 5016517
+ * @summary Test Hashed passwords
+ * @library /test/lib
+ * @modules java.management
+ * @build HashedPasswordFileTest
+ * @run testng/othervm  HashedPasswordFileTest
+ *
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.ProcessTools;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import javax.management.MBeanServer;
+import javax.management.remote.*;
+import java.io.*;
+import java.lang.management.ManagementFactory;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.*;
+
+@Test
+public class HashedPasswordFileTest {
+
+    private final String[] randomWords = {"accost", "savoie", "bogart", "merest",
+            "azuela", "hoodie", "bursal", "lingua", "wincey", "trilby", "egesta",
+            "wester", "gilgai", "weinek", "ochone", "sanest", "gainst", "defang",
+            "ranket", "mayhem", "tagger", "timber", "eggcup", "mhren", "colloq",
+            "dreamy", "hattie", "rootle", "bloody", "helyne", "beater", "cosine",
+            "enmity", "outbox", "issuer", "lumina", "dekker", "vetoed", "dennis",
+            "strove", "gurnet", "talkie", "bennie", "behove", "coates", "shiloh",
+            "yemeni", "boleyn", "coaxal", "irne"};
+
+    private final String[] hashAlgs = {
+            "MD2",
+            "MD5",
+            "SHA-1",
+            "SHA-224",
+            "SHA-256",
+            "SHA-384",
+            "SHA-512/224",
+            "SHA-512/256",
+            "SHA3-224",
+            "SHA3-256",
+            "SHA3-384",
+            "SHA3-512"
+    };
+
+    private final Random random = Utils.getRandomInstance();
+
+    private JMXConnectorServer cs;
+
+    private String randomWord() {
+        int idx = random.nextInt(randomWords.length);
+        return randomWords[idx];
+    }
+
+    private String[] getHash(String algorithm, String password) {
+        try {
+            byte[] salt = new byte[64];
+            random.nextBytes(salt);
+
+            MessageDigest digest = MessageDigest.getInstance(algorithm);
+            digest.reset();
+            digest.update(salt);
+            byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
+
+            String saltStr = Base64.getEncoder().encodeToString(salt);
+            String hashStr = Base64.getEncoder().encodeToString(hash);
+
+            return new String[]{saltStr, hashStr};
+        } catch (NoSuchAlgorithmException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private String getPasswordFilePath() {
+        String testDir = System.getProperty("test.src");
+        String testFileName = "jmxremote.password";
+        return testDir + File.separator + testFileName;
+    }
+
+    private File createNewPasswordFile() throws IOException {
+        File file = new File(getPasswordFilePath());
+        if (file.exists()) {
+            file.delete();
+        }
+        file.createNewFile();
+        return file;
+    }
+
+    private Map<String, String> generateClearTextPasswordFile() throws IOException {
+        File file = createNewPasswordFile();
+        Map<String, String> props = new HashMap<>();
+        BufferedWriter br;
+        try (FileWriter fw = new FileWriter(file)) {
+            br = new BufferedWriter(fw);
+            int numentries = random.nextInt(5) + 3;
+            for (int i = 0; i < numentries; i++) {
+                String username;
+                do {
+                    username = randomWord();
+                } while (props.get(username) != null);
+                String password = randomWord();
+                props.put(username, password);
+                br.write(username + " " + password + "\n");
+            }
+            br.flush();
+        }
+        br.close();
+        return props;
+    }
+
+    private boolean isPasswordFileHashed() throws IOException {
+        BufferedReader br;
+        boolean result;
+        try (FileReader fr = new FileReader(getPasswordFilePath())) {
+            br = new BufferedReader(fr);
+            result = br.lines().anyMatch(line -> {
+                if (line.startsWith("#")) {
+                    return false;
+                }
+                String[] tokens = line.split("\\s+");
+                return tokens.length == 3 || tokens.length == 4;
+            });
+        }
+        br.close();
+        return result;
+    }
+
+    private Map<String, String> generateHashedPasswordFile() throws IOException {
+        File file = createNewPasswordFile();
+        Map<String, String> props = new HashMap<>();
+        BufferedWriter br;
+        try (FileWriter fw = new FileWriter(file)) {
+            br = new BufferedWriter(fw);
+            int numentries = random.nextInt(5) + 3;
+            for (int i = 0; i < numentries; i++) {
+                String username;
+                do {
+                    username = randomWord();
+                } while (props.get(username) != null);
+                String password = randomWord();
+                String alg = hashAlgs[random.nextInt(hashAlgs.length)];
+                String[] b64str = getHash(alg, password);
+                br.write(username + " " + b64str[0] + " " + b64str[1] + " " + alg + "\n");
+                props.put(username, password);
+            }
+            br.flush();
+        }
+        br.close();
+        return props;
+    }
+
+    private JMXServiceURL createServerSide(boolean useHash)
+            throws IOException {
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+
+        HashMap<String, Object> env = new HashMap<>();
+        env.put("jmx.remote.x.password.file", getPasswordFilePath());
+        env.put("jmx.remote.x.password.toHashes", useHash ? "true" : "false");
+        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+        cs.start();
+        return cs.getAddress();
+    }
+
+    @Test
+    public void testClearTextPasswordFile() throws IOException {
+        Boolean[] bvals = new Boolean[]{true, false};
+        for (boolean bval : bvals) {
+            try {
+                Map<String, String> credentials = generateClearTextPasswordFile();
+                JMXServiceURL serverUrl = createServerSide(bval);
+                for (Map.Entry<String, String> entry : credentials.entrySet()) {
+                    HashMap<String, Object> env = new HashMap<>();
+                    env.put("jmx.remote.credentials",
+                            new String[]{entry.getKey(), entry.getValue()});
+                    try (JMXConnector cc = JMXConnectorFactory.connect(serverUrl, env)) {
+                        cc.getMBeanServerConnection();
+                    }
+                }
+                Assert.assertEquals(isPasswordFileHashed(), bval);
+            } finally {
+                cs.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testReadOnlyPasswordFile() throws IOException {
+        Boolean[] bvals = new Boolean[]{true, false};
+        for (boolean bval : bvals) {
+            try {
+                Map<String, String> credentials = generateClearTextPasswordFile();
+                File file = new File(getPasswordFilePath());
+                file.setReadOnly();
+                JMXServiceURL serverUrl = createServerSide(bval);
+                for (Map.Entry<String, String> entry : credentials.entrySet()) {
+                    HashMap<String, Object> env = new HashMap<>();
+                    env.put("jmx.remote.credentials",
+                            new String[]{entry.getKey(), entry.getValue()});
+                    try (JMXConnector cc = JMXConnectorFactory.connect(serverUrl, env)) {
+                        cc.getMBeanServerConnection();
+                    }
+                }
+                Assert.assertEquals(isPasswordFileHashed(), false);
+            } finally {
+                cs.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testHashedPasswordFile() throws IOException {
+        Boolean[] bvals = new Boolean[]{true, false};
+        for (boolean bval : bvals) {
+            try {
+                Map<String, String> credentials = generateHashedPasswordFile();
+                JMXServiceURL serverUrl = createServerSide(bval);
+                Assert.assertEquals(isPasswordFileHashed(), true);
+                for (Map.Entry<String, String> entry : credentials.entrySet()) {
+                    HashMap<String, Object> env = new HashMap<>();
+                    env.put("jmx.remote.credentials",
+                            new String[]{entry.getKey(), entry.getValue()});
+                    try (JMXConnector cc = JMXConnectorFactory.connect(serverUrl, env)) {
+                        cc.getMBeanServerConnection();
+                    }
+                }
+            } finally {
+                cs.stop();
+            }
+        }
+    }
+
+    private static class SimpleJMXClient implements Callable {
+        private final JMXServiceURL url;
+        private final Map<String, String> credentials;
+
+        public SimpleJMXClient(JMXServiceURL url, Map<String, String> credentials) {
+            this.url = url;
+            this.credentials = credentials;
+        }
+
+        @Override
+        public Object call() throws Exception {
+            for (Map.Entry<String, String> entry : credentials.entrySet()) {
+                HashMap<String, Object> env = new HashMap<>();
+                env.put("jmx.remote.credentials",
+                        new String[]{entry.getKey(), entry.getValue()});
+                try (JMXConnector cc = JMXConnectorFactory.connect(url, env)) {
+                    cc.getMBeanServerConnection();
+                }
+            }
+            return null;
+        }
+    }
+
+    @Test
+    public void testMultipleClients() throws Throwable {
+        Map<String, String> credentials = generateClearTextPasswordFile();
+        JMXServiceURL serverUrl = createServerSide(true);
+        Assert.assertEquals(isPasswordFileHashed(), false);
+        // create random number of clients
+        int numClients = random.nextInt(20) + 10;
+        List<Future> futures = new ArrayList<>();
+        ExecutorService executor = Executors.newFixedThreadPool(numClients);
+        for (int i = 0; i < numClients; i++) {
+            Future future = executor.submit(new SimpleJMXClient(serverUrl, credentials));
+            futures.add(future);
+        }
+        try {
+            for (Future future : futures) {
+                future.get();
+            }
+        } catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+        } catch (ExecutionException ex) {
+            throw ex.getCause();
+        } finally {
+            executor.shutdown();
+        }
+
+        Assert.assertEquals(isPasswordFileHashed(), true);
+    }
+
+    @Test
+    public void testPasswordChange() throws IOException {
+        try {
+            Map<String, String> credentials = generateClearTextPasswordFile();
+            JMXServiceURL serverUrl = createServerSide(true);
+            Assert.assertEquals(isPasswordFileHashed(), false);
+
+            for (Map.Entry<String, String> entry : credentials.entrySet()) {
+                HashMap<String, Object> env = new HashMap<>();
+                env.put("jmx.remote.credentials",
+                        new String[]{entry.getKey(), entry.getValue()});
+                try (JMXConnector cc = JMXConnectorFactory.connect(serverUrl, env)) {
+                    cc.getMBeanServerConnection();
+                }
+            }
+            Assert.assertEquals(isPasswordFileHashed(), true);
+
+            // Read the file back. Add new entries. Change passwords for few
+            BufferedReader br = new BufferedReader(new FileReader(getPasswordFilePath()));
+            String line;
+            StringBuilder sbuild = new StringBuilder();
+            while ((line = br.readLine()) != null) {
+                if (line.trim().startsWith("#")) {
+                    sbuild.append(line).append("\n");
+                    continue;
+                }
+
+                // Change password for random entries
+                if (random.nextBoolean()) {
+                    String[] tokens = line.split("\\s+");
+                    if ((tokens.length == 4 || tokens.length == 3)) {
+                        String password = randomWord();
+                        credentials.put(tokens[0], password);
+                        sbuild.append(tokens[0]).append(" ").append(password).append("\n");
+                    }
+                } else {
+                    sbuild.append(line).append("\n");
+                }
+            }
+
+            // Add new entries in clear
+            int newentries = random.nextInt(2) + 3;
+            for (int i = 0; i < newentries; i++) {
+                String username;
+                do {
+                    username = randomWord();
+                } while (credentials.get(username) != null);
+                String password = randomWord();
+                credentials.put(username, password);
+                sbuild.append(username).append(" ").append(password).append("\n");
+            }
+
+            // Add new entries as a hash
+            int numentries = random.nextInt(2) + 3;
+            for (int i = 0; i < numentries; i++) {
+                String username;
+                do {
+                    username = randomWord();
+                } while (credentials.get(username) != null);
+                String password = randomWord();
+                String alg = hashAlgs[random.nextInt(hashAlgs.length)];
+                String[] b64str = getHash(alg, password);
+                credentials.put(username, password);
+                sbuild.append(username).append(" ").append(b64str[0])
+                        .append(" ").append(b64str[1]).append(" ")
+                        .append(alg).append("\n");
+            }
+
+            try (BufferedWriter bw = new BufferedWriter(new FileWriter(getPasswordFilePath()))) {
+                bw.write(sbuild.toString());
+            }
+
+            for (Map.Entry<String, String> entry : credentials.entrySet()) {
+                HashMap<String, Object> env = new HashMap<>();
+                env.put("jmx.remote.credentials",
+                        new String[]{entry.getKey(), entry.getValue()});
+                try (JMXConnector cc = JMXConnectorFactory.connect(serverUrl, env)) {
+                    cc.getMBeanServerConnection();
+                }
+            }
+        } finally {
+            cs.stop();
+        }
+    }
+
+    @Test
+    public void testDefaultAgent() throws Exception {
+        List<String> pbArgs = new ArrayList<>();
+        int port = Utils.getFreePort();
+        generateClearTextPasswordFile();
+
+        // This will run only on a POSIX compliant system
+        if (!FileSystems.getDefault().supportedFileAttributeViews().contains("posix")) {
+            return;
+        }
+
+        // Make sure only owner is able to read/write the file or else
+        // default agent will fail to start
+        File file = new File(getPasswordFilePath());
+        Set<PosixFilePermission> perms = new HashSet<>();
+        perms.add(PosixFilePermission.OWNER_READ);
+        perms.add(PosixFilePermission.OWNER_WRITE);
+        Files.setPosixFilePermissions(file.toPath(), perms);
+
+        pbArgs.add("-cp");
+        pbArgs.add(System.getProperty("test.class.path"));
+
+        pbArgs.add("-Dcom.sun.management.jmxremote.port=" + port);
+        pbArgs.add("-Dcom.sun.management.jmxremote.authenticate=true");
+        pbArgs.add("-Dcom.sun.management.jmxremote.password.file=" + file.getAbsolutePath());
+        pbArgs.add("-Dcom.sun.management.jmxremote.ssl=false");
+        pbArgs.add(TestApp.class.getSimpleName());
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                pbArgs.toArray(new String[0]));
+        Process process = ProcessTools.startProcess(
+                TestApp.class.getSimpleName(),
+                pb);
+
+        if (process.waitFor() != 0) {
+            throw new RuntimeException("Test Failed : Error starting default agent");
+        }
+        Assert.assertEquals(isPasswordFileHashed(), true);
+    }
+
+    @Test
+    public void testDefaultAgentNoHash() throws Exception {
+        List<String> pbArgs = new ArrayList<>();
+        int port = Utils.getFreePort();
+        generateClearTextPasswordFile();
+
+        // This will run only on a POSIX compliant system
+        if (!FileSystems.getDefault().supportedFileAttributeViews().contains("posix")) {
+            return;
+        }
+
+        // Make sure only owner is able to read/write the file or else
+        // default agent will fail to start
+        File file = new File(getPasswordFilePath());
+        Set<PosixFilePermission> perms = new HashSet<>();
+        perms.add(PosixFilePermission.OWNER_READ);
+        perms.add(PosixFilePermission.OWNER_WRITE);
+        Files.setPosixFilePermissions(file.toPath(), perms);
+
+        pbArgs.add("-cp");
+        pbArgs.add(System.getProperty("test.class.path"));
+
+        pbArgs.add("-Dcom.sun.management.jmxremote.port=" + port);
+        pbArgs.add("-Dcom.sun.management.jmxremote.authenticate=true");
+        pbArgs.add("-Dcom.sun.management.jmxremote.password.file=" + file.getAbsolutePath());
+        pbArgs.add("-Dcom.sun.management.jmxremote.password.toHashes=false");
+        pbArgs.add("-Dcom.sun.management.jmxremote.ssl=false");
+        pbArgs.add(TestApp.class.getSimpleName());
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                pbArgs.toArray(new String[0]));
+        Process process = ProcessTools.startProcess(
+                TestApp.class.getSimpleName(),
+                pb);
+
+        if (process.waitFor() != 0) {
+            throw new RuntimeException("Test Failed : Error starting default agent");
+        }
+        Assert.assertEquals(isPasswordFileHashed(), false);
+    }
+
+    @AfterClass
+    public void cleanUp() {
+        File file = new File(getPasswordFilePath());
+        if (file.exists()) {
+            file.delete();
+        }
+    }
+}
+
+class TestApp {
+
+    public static void main(String[] args) throws IOException {
+        try {
+            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:"
+                    + System.getProperty("com.sun.management.jmxremote.port") + "/jmxrmi");
+            Map<String, Object> env = new HashMap<>(1);
+            // any dummy credentials will do. We just have to trigger password hashing
+            env.put("jmx.remote.credentials", new String[]{"a", "a"});
+            try (JMXConnector cc = JMXConnectorFactory.connect(url, env)) {
+                cc.getMBeanServerConnection();
+            }
+        } catch (SecurityException ex) {
+            // Catch authentication failure here
+        }
+    }
+}
--- a/test/jdk/javax/swing/DefaultButtonModel/DefaultButtonModelCrashTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/DefaultButtonModel/DefaultButtonModelCrashTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,12 +20,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8182577
  * @summary  Verifies if moving focus via custom ButtonModel causes crash
+ * @key headful
  * @run main DefaultButtonModelCrashTest
  */
+
 import java.awt.BorderLayout;
 import java.awt.Container;
 import java.awt.Point;
@@ -61,7 +64,7 @@
             robot.keyPress(KeyEvent.VK_TAB);
             robot.keyRelease(KeyEvent.VK_TAB);
         } finally {
-            SwingUtilities.invokeAndWait(()->frame  .dispose());
+            if (frame != null) { SwingUtilities.invokeAndWait(()->frame.dispose()); }
         }
     }
 
--- a/test/jdk/javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,12 +20,14 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8178025
  * @summary  Verifies if graphicsConfiguration property notification is sent
  *           when frame is moved from one screen to another in multiscreen
  *           environment.
+ * @key headful
  * @run main TestMultiScreenGConfigNotify
  */
 
--- a/test/jdk/javax/swing/JButton/TestGlyphBreak.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/JButton/TestGlyphBreak.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,10 +20,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8191428
  * @summary  Verifies if text view is not borken into multiple lines
+ * @key headful
  * @run main/othervm -Dsun.java2d.uiScale=1.2 TestGlyphBreak
  */
 
--- a/test/jdk/javax/swing/JComboBox/8182031/ComboPopupTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/JComboBox/8182031/ComboPopupTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,12 +20,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8182031
  * @summary  Verifies if ComboBox Popup opens and closes immediately
+ * @key headful
  * @run main ComboPopupTest
  */
+
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
@@ -80,7 +83,7 @@
                 throw new RuntimeException("combobox popup is not visible");
             }
         } finally {
-            SwingUtilities.invokeAndWait(()->frame.dispose());
+            if (frame != null) { SwingUtilities.invokeAndWait(()->frame.dispose()); }
         }
     }
 
--- a/test/jdk/javax/swing/JMenu/8178430/LabelDotTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/JMenu/8178430/LabelDotTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,13 +20,16 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8178430
  * @summary JMenu in GridBagLayout flickers when label text shows "..." and
  * is updated
+ * @key headful
  * @run main LabelDotTest
  */
+
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
@@ -112,7 +115,9 @@
             SwingUtilities.invokeAndWait(() -> createUI());
             runTest(50);
         } finally {
-            SwingUtilities.invokeAndWait(() -> frame.dispose());
+            if (frame != null) {
+                SwingUtilities.invokeAndWait(() -> frame.dispose());
+            }
             if (isException)
                 throw new RuntimeException("Size of Menu bar is not correct.");
         }
--- a/test/jdk/javax/swing/JTextArea/TestTabSize.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/JTextArea/TestTabSize.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,10 +20,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8187957
  * @summary  Verifies Tab Size works correctly in JTextArea
+ * @key headful
  * @run main TestTabSize
  */
 
@@ -96,7 +98,9 @@
             } catch (BadLocationException ex) {
                 excpnthrown = true;
             } finally {
-                f.dispose();
+                if (f != null) {
+                    f.dispose();
+                }
             }
         });
         if (excpnthrown) {
--- a/test/jdk/javax/swing/dnd/8139050/NativeErrorsInTableDnD.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/dnd/8139050/NativeErrorsInTableDnD.java	Thu Dec 07 11:54:55 2017 +0000
@@ -40,10 +40,12 @@
 /**
  * @test
  * @bug 8139050 8153871
+ * @key headful
  * @library ../../../../lib/testlibrary
  * @build ExtendedRobot
  * @run main/othervm/timeout=360 -Xcheck:jni NativeErrorsInTableDnD
  */
+
 public final class NativeErrorsInTableDnD {
 
     private static JFrame frame;
--- a/test/jdk/javax/swing/plaf/nimbus/TestNimbusOverride.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/plaf/nimbus/TestNimbusOverride.java	Thu Dec 07 11:54:55 2017 +0000
@@ -20,13 +20,16 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/*
+
+/**
  * @test
  * @bug 8043315
  * @summary  Verifies if setting Nimbus.Overrides property affects
  *           keymap installation
+ * @key headful
  * @run main TestNimbusOverride
  */
+
 import java.awt.BorderLayout;
 import java.awt.Component;
 import java.awt.Dimension;
--- a/test/jdk/javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -30,6 +30,7 @@
  * @test
  * @bug 8188081
  * @summary  Text selection does not clear after focus is lost
+ * @key headful
  * @run main HidingSelectionTest
  */
 
--- a/test/jdk/jdk/internal/misc/JavaLangAccess/NewUnsafeString.java	Wed Dec 06 19:07:16 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2012, 2017, 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.
- */
-
-import java.util.Objects;
-import java.util.Comparator;
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
-
-/*
- * @test
- * @bug 8013528
- * @summary Test JavaLangAccess.newUnsafeString
- * @modules java.base/jdk.internal.misc
- * @compile -XDignore.symbol.file NewUnsafeString.java
- * @run main NewUnsafeString
- */
-public class NewUnsafeString {
-
-    static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-
-    public static void testNewUnsafeString() {
-        String benchmark = "exemplar";
-        String constructorCopy = new String(benchmark);
-        char[] jlaChars = benchmark.toCharArray();
-        String jlaCopy = jla.newStringUnsafe(jlaChars);
-
-        if (benchmark == constructorCopy) {
-            throw new Error("should be different instances");
-        }
-        if (!benchmark.equals(constructorCopy)) {
-            throw new Error("Copy not equal");
-        }
-        if (0 != Objects.compare(benchmark, constructorCopy, Comparator.naturalOrder())) {
-            throw new Error("Copy not equal");
-        }
-
-        if (benchmark == jlaCopy) {
-            throw new Error("should be different instances");
-        }
-        if (!benchmark.equals(jlaCopy)) {
-            throw new Error("Copy not equal");
-        }
-        if (0 != Objects.compare(benchmark, jlaCopy, Comparator.naturalOrder())) {
-            throw new Error("Copy not equal");
-        }
-
-        if (constructorCopy == jlaCopy) {
-            throw new Error("should be different instances");
-        }
-        if (!constructorCopy.equals(jlaCopy)) {
-            throw new Error("Copy not equal");
-        }
-        if (0 != Objects.compare(constructorCopy, jlaCopy, Comparator.naturalOrder())) {
-            throw new Error("Copy not equal");
-        }
-
-        // The following is extremely "evil". Never ever do this in non-test code.
-        jlaChars[0] = 'X';
-        if (!"Xxemplar".equals(jlaCopy)) {
-            throw new Error("jla.newStringUnsafe did not use provided string");
-        }
-
-    }
-
-    public static void main(String[] args) {
-        testNewUnsafeString();
-    }
-}
--- a/test/jdk/tools/jlink/multireleasejar/JLinkMRJavaBaseVersionTest.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jdk/tools/jlink/multireleasejar/JLinkMRJavaBaseVersionTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -25,6 +25,8 @@
  * @test
  * @bug 8177471
  * @summary  jlink should use the version from java.base.jmod to find modules
+ * @bug 8185130
+ * @summary jlink should throw error if target image and current JDK versions don't match
  * @modules java.base/jdk.internal.module
  * @library /test/lib
  * @build jdk.test.lib.process.* CheckRuntimeVersion
@@ -122,7 +124,9 @@
         System.out.println("Testing jlink with " + getJmods() + " of target version " + version);
 
         // use jlink to build image from multi-release jar
-        jlink("m1.jar", "myimage");
+        if (jlink("m1.jar", "myimage")) {
+            return;
+        }
 
         // validate runtime image
         Path java = Paths.get("myimage", "bin", "java");
@@ -130,12 +134,7 @@
 
         // validate the image linked with the proper MR version
 
-        if (version.equalsIgnoreOptional(Runtime.version())) {
-            ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
-                                        "CheckRuntimeVersion", String.valueOf(version.major()),
-                                        "java.base", "java.logging", "m1")
-                .shouldHaveExitValue(0);
-        } else {
+        if (!version.equalsIgnoreOptional(Runtime.version())) {
             ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
                                         "CheckRuntimeVersion", String.valueOf(version.major()),
                                         "java.base", "m1")
@@ -151,13 +150,19 @@
         return Runtime.Version.parse(mref.descriptor().version().get().toString());
     }
 
-    private void jlink(String jar, String image) {
+    private boolean jlink(String jar, String image) {
         List<String> args = List.of("--output", image,
                                     "--add-modules", "m1",
                                     "--module-path",
                                     getJmods().toString() + File.pathSeparator + jar);
         System.out.println("jlink " + args.stream().collect(Collectors.joining(" ")));
         int exitCode = JLINK_TOOL.run(System.out, System.err, args.toArray(new String[0]));
-        Assert.assertEquals(exitCode, 0);
+        boolean isJDK9 = System.getProperty("java9.home") != null;
+        if (isJDK9) {
+            Assert.assertNotEquals(exitCode, 0);
+        } else {
+            Assert.assertEquals(exitCode, 0);
+        }
+        return isJDK9;
     }
 }
--- a/test/jtreg-ext/requires/VMProps.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/jtreg-ext/requires/VMProps.java	Thu Dec 07 11:54:55 2017 +0000
@@ -74,6 +74,7 @@
         map.put("vm.aot", vmAOT());
         // vm.cds is true if the VM is compiled with cds support.
         map.put("vm.cds", vmCDS());
+        map.put("vm.cds.custom.loaders", vmCDSForCustomLoaders());
         // vm.graal.enabled is true if Graal is used as JIT
         map.put("vm.graal.enabled", isGraalEnabled());
         map.put("docker.support", dockerSupport());
@@ -297,6 +298,19 @@
     }
 
     /**
+     * Check for CDS support for custom loaders.
+     *
+     * @return true if CDS is supported for customer loader by the VM to be tested.
+     */
+    protected String vmCDSForCustomLoaders() {
+        if (vmCDS().equals("true") && Platform.areCustomLoadersSupportedForCDS()) {
+            return "true";
+        } else {
+            return "false";
+        }
+    }
+
+    /**
      * Check if Graal is used as JIT compiler.
      *
      * @return true if Graal is used as JIT compiler.
--- a/test/langtools/jdk/javadoc/doclet/testSerializedForm/TestSerializedForm.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testSerializedForm/TestSerializedForm.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4341304 4485668 4966728 8032066 8071982
+ * @bug 4341304 4485668 4966728 8032066 8071982 8192933
  * @summary Test that methods readResolve and writeReplace show
  * up in serialized-form.html the same way that readObject and writeObject do.
  * If the doclet includes readResolve and writeReplace in the serialized-form
@@ -114,4 +114,21 @@
                 + "title=\"class in pkg1\">pkg1.PublicExcludeInnerClass.PubInnerClass</a> "
                 + "extends java.lang.Object implements Serializable</h3>");
     }
+
+    @Test
+    void test2() {
+        javadoc("-private",
+                "-d", "out-2",
+                "-sourcepath", testSrc,
+                "pkg2");
+        checkExit(Exit.OK);
+
+        checkOrder("serialized-form.html",
+                "int[] a1",
+                "int[][] a2",
+                "<a href=\"pkg2/Fields.html\" title=\"class in pkg2\">Fields</a>[][] doubleArray",
+                "<a href=\"pkg2/Fields.html\" title=\"class in pkg2\">Fields</a>[] singleArray",
+                "java.lang.Class&lt;<a href=\"pkg2/Fields.html\" "
+                + "title=\"type parameter in Fields\">E</a>&gt; someClass");
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testSerializedForm/pkg2/Fields.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, 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 pkg2;
+
+public class Fields<E> implements java.io.Serializable {
+    /** Some doc. */
+    public Class<E> someClass;
+
+    /** a primitive array */
+    private int[] a1;
+
+    /** a two dimensional primitive array */
+    private int[][] a2;
+
+    /** a single object array */
+    private Fields[] singleArray;
+
+    /** a double object array */
+    private Fields[][] doubleArray;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/tool/testPackages/TestPackages.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test
+ * @bug 8191078
+ * @summary ensure that javadoc considers packages correctly
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ *          jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.javadoc/jdk.javadoc.internal.api
+ *          jdk.javadoc/jdk.javadoc.internal.tool
+ * @library /tools/lib
+ * @build toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
+ * @run main TestPackages
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import toolbox.*;
+import toolbox.Task.Expect;
+import toolbox.Task.OutputKind;
+import toolbox.Task.Result;
+
+public class TestPackages extends TestRunner {
+
+    final ToolBox tb = new ToolBox();
+
+    public TestPackages() {
+        super(System.err);
+    }
+
+    public static void main(String[] args) throws Exception {
+        TestPackages t = new TestPackages();
+        t.runTests(m -> new Object[] { Paths.get(m.getName()) });
+    }
+
+    @Test
+    public void testEmptyPackage(Path base) throws Exception {
+        Files.createDirectories(base);
+        tb.writeFile(base.resolve("p1/package-info.java"), "package p1;\n");
+        tb.writeFile(base.resolve("p2/A.java"), "package p2;\npublic class A {}\n");
+
+        Path outDir = base.resolve("out");
+        Files.createDirectory(outDir);
+        JavadocTask task = new JavadocTask(tb);
+        task = task.outdir(outDir).sourcepath(base).options("p1", "p2");
+        Result r = task.run(Expect.SUCCESS);
+        List<String> list = tb.grep(".*warning.*not found.*", r.getOutputLines(OutputKind.DIRECT));
+        if (!list.isEmpty()) {
+            throw new Exception("Found warning: " + list.get(0));
+        }
+    }
+}
--- a/test/langtools/tools/javac/6330997/T6330997.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/langtools/tools/javac/6330997/T6330997.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug     6330997 7025789 8000961
+ * @bug     6330997 7025789 8000961 8188870
  * @summary javac should accept class files with major version of the next release
  * @author  Wei Tao
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -32,8 +32,8 @@
  *          jdk.compiler/com.sun.tools.javac.main
  *          jdk.compiler/com.sun.tools.javac.util
  * @clean T1 T2
- * @compile -source 9 -target 9 T1.java
- * @compile -source 9 -target 9 T2.java
+ * @compile -source 10 -target 10 T1.java
+ * @compile -source 10 -target 10 T2.java
  * @run main/othervm T6330997
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8192885/AddGotoAfterForLoopToLNTTest.java	Thu Dec 07 11:54:55 2017 +0000
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test
+ * @bug 8192885
+ * @summary Compiler in JDK 10-ea+33 misses to include entry in LineNumberTable for goto instruction of foreach loop
+ * @library /tools/lib
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ *          jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.javac.util
+ *          jdk.jdeps/com.sun.tools.javap
+ * @build toolbox.ToolBox toolbox.JavacTask
+ * @run main AddGotoAfterForLoopToLNTTest
+ */
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.util.Assert;
+
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+public class AddGotoAfterForLoopToLNTTest {
+
+    static final String testSource =
+    /* 01 */        "class GotoAtEnhancedForTest {\n" +
+    /* 02 */        "    void lookForThisMethod() {\n" +
+    /* 03 */        "        for (Object o : java.util.Collections.emptyList()) {\n" +
+    /* 04 */        "        }\n" +
+    /* 05 */        "    }\n" +
+    /* 06 */        "}";
+
+    static final int[][] expectedLNT = {
+    //  {line-number, start-pc},
+        {3,           0},
+        {4,           25},
+        {3,           28},
+        {5,           30},
+    };
+
+    static final String methodToLookFor = "lookForThisMethod";
+
+    public static void main(String[] args) throws Exception {
+        new AddGotoAfterForLoopToLNTTest().run();
+    }
+
+    ToolBox tb = new ToolBox();
+
+    void run() throws Exception {
+        compileTestClass();
+        checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+                "GotoAtEnhancedForTest.class").toUri()), methodToLookFor);
+    }
+
+    void compileTestClass() throws Exception {
+        new JavacTask(tb)
+                .sources(testSource)
+                .run();
+    }
+
+    void checkClassFile(final File cfile, String methodToFind) throws Exception {
+        ClassFile classFile = ClassFile.read(cfile);
+        boolean methodFound = false;
+        for (Method method : classFile.methods) {
+            if (method.getName(classFile.constant_pool).equals(methodToFind)) {
+                methodFound = true;
+                Code_attribute code = (Code_attribute) method.attributes.get("Code");
+                LineNumberTable_attribute lnt =
+                        (LineNumberTable_attribute) code.attributes.get("LineNumberTable");
+                Assert.check(lnt.line_number_table_length == expectedLNT.length,
+                        "The LineNumberTable found has a length different to the expected one");
+                int i = 0;
+                for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) {
+                    Assert.check(entry.line_number == expectedLNT[i][0] &&
+                            entry.start_pc == expectedLNT[i][1],
+                            "LNT entry at pos " + i + " differ from expected." +
+                            "Found " + entry.line_number + ":" + entry.start_pc +
+                            ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
+                    i++;
+                }
+            }
+        }
+        Assert.check(methodFound, "The seek method was not found");
+    }
+
+    void error(String msg) {
+        throw new AssertionError(msg);
+    }
+}
--- a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7157626 8001112
+ * @bug 7157626 8001112 8188870
  * @summary Test major version for all legal combinations for -source and -target
  * @author sgoel
  *
@@ -38,7 +38,7 @@
 public class ClassVersionChecker {
 
     int errors;
-    String[] jdk = {"", "1.6", "1.7", "1.8", "1.9"};
+    String[] jdk = {"", "1.6", "1.7", "1.8", "1.9", "1.10"};
     File javaFile = null;
 
     public static void main(String[] args) throws Throwable {
@@ -58,10 +58,11 @@
          * -1 => invalid combinations
          */
         int[][] ver =
-                {{53, -1, -1, -1, -1},
-                 {53, 50, 51, 52, 53},
-                 {53, -1, 51, 52, 53},
-                 {53, -1, -1, 52, 53}};
+                {{54, -1, -1, -1, -1, -1},
+                 {54, 50, 51, 52, 53, 54},
+                 {54, -1, 51, 52, 53, 54},
+                 {54, -1, -1, 52, 53, 54},
+                 {54, -1, -1, -1, 53, 54}};
 
         // Loop to run all possible combinations of source/target values
         for (int i = 0; i< ver.length; i++) {
--- a/test/langtools/tools/javac/flow/tests/TestCaseForEach.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/langtools/tools/javac/flow/tests/TestCaseForEach.java	Thu Dec 07 11:54:55 2017 +0000
@@ -3,7 +3,7 @@
 public class TestCaseForEach {
 
     @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=11)
-    @AliveRange(varName="o", bytecodeStart=44, bytecodeLength=1)
+    @AliveRange(varName="o", bytecodeStart=41, bytecodeLength=1)
     void m(String[] args) {
         Object o;
         for (String s : args) {
--- a/test/langtools/tools/javac/versions/Versions.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/langtools/tools/javac/versions/Versions.java	Thu Dec 07 11:54:55 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 8000961 8030610 8028546
+ * @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 8000961 8030610 8028546 8188870
  * @summary Check interpretation of -target and -source options
  * @modules java.compiler
  *          jdk.compiler
@@ -64,12 +64,12 @@
         String TC = "";
         System.out.println("Version.java: Starting");
 
-        check("53.0");
-        check("53.0", "-source 1.6");
-        check("53.0", "-source 1.7");
-        check("53.0", "-source 1.8");
-        check("53.0", "-source 1.9");
-        check("53.0", "-source 1.10");
+        check("54.0");
+        check("54.0", "-source 1.6");
+        check("54.0", "-source 1.7");
+        check("54.0", "-source 1.8");
+        check("54.0", "-source 1.9");
+        check("54.0", "-source 1.10");
 
         check_source_target("50.0", "6", "6");
         check_source_target("51.0", "6", "7");
@@ -81,7 +81,11 @@
         check_source_target("53.0", "7", "9");
         check_source_target("53.0", "8", "9");
         check_source_target("53.0", "9", "9");
-        check_source_target("53.0", "10", "10");
+        check_source_target("54.0", "6", "10");
+        check_source_target("54.0", "7", "10");
+        check_source_target("54.0", "8", "10");
+        check_source_target("54.0", "9", "10");
+        check_source_target("54.0", "10", "10");
 
         checksrc16("-source 1.6");
         checksrc16("-source 6");
@@ -99,7 +103,6 @@
         checksrc19("-source 9");
         checksrc19("-source 1.9", "-target 1.9");
         checksrc19("-source 9", "-target 9");
-
         checksrc110();
         checksrc110("-source 1.10");
         checksrc110("-source 10");
--- a/test/lib/jdk/test/lib/Platform.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/lib/jdk/test/lib/Platform.java	Thu Dec 07 11:54:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -288,4 +288,16 @@
             return "so";
         }
     }
+
+    /*
+     * This should match the #if condition in ClassListParser::load_class_from_source().
+     */
+    public static boolean areCustomLoadersSupportedForCDS() {
+        boolean isLinux = Platform.isLinux();
+        boolean is64 = Platform.is64bit();
+        boolean isSolaris = Platform.isSolaris();
+        boolean isAix = Platform.isAix();
+
+        return (is64 && (isLinux || isSolaris || isAix));
+    }
 }
--- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java	Wed Dec 06 19:07:16 2017 +0000
+++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java	Thu Dec 07 11:54:55 2017 +0000
@@ -166,9 +166,9 @@
             outStr.contains("Unable to map ReadWrite shared space at required address") ||
             outStr.contains("Unable to map MiscData shared space at required address") ||
             outStr.contains("Unable to map MiscCode shared space at required address") ||
-            outStr.contains("Unable to map shared string space at required address") ||
+            outStr.contains("Unable to map OptionalData shared space at required address") ||
             outStr.contains("Could not allocate metaspace at a compatible address") ||
-            outStr.contains("Unable to allocate shared string space: range is not within java heap") ))
+            outStr.contains("UseSharedSpaces: Unable to allocate region, range is not within java heap") ))
         {
             return true;
         }