changeset 14371:b77d076941f2

Merge
author lana
date Thu, 05 May 2016 19:11:09 +0000
parents f38c0650a60f ee18c1df243b
children ed8ca9167d66
files src/java.base/share/classes/jdk/internal/module/Hasher.java test/javax/transaction/testng/TEST.properties test/tools/jlink/hashes/HashesTest.java test/tools/jlink/hashes/newsrc/m2/module-info.java test/tools/jlink/hashes/newsrc/m2/org/m2/Util.java test/tools/jlink/hashes/newsrc/not_matched/module-info.java test/tools/jlink/hashes/newsrc/not_matched/org/not_matched/Name.java test/tools/jlink/hashes/src/m1/module-info.java test/tools/jlink/hashes/src/m1/org/m1/Main.java test/tools/jlink/hashes/src/m2/module-info.java test/tools/jlink/hashes/src/m2/org/m2/Util.java test/tools/jlink/hashes/src/not_matched/module-info.java test/tools/jlink/hashes/src/not_matched/org/not_matched/Name.java test/tools/launcher/modules/addmods/src/app/Main.java test/tools/launcher/modules/addmods/src/lib/jdk/lib/Util.java test/tools/launcher/modules/addmods/src/lib/module-info.java
diffstat 322 files changed, 5430 insertions(+), 3569 deletions(-) [+]
line wrap: on
line diff
--- a/make/Tools.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/Tools.gmk	Thu May 05 19:11:09 2016 +0000
@@ -96,7 +96,13 @@
 TOOL_SPP = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes build.tools.spp.Spp
 
 # Nimbus is used somewhere in the swing build.
+
+ifeq ($(BOOT_JDK_MODULAR), true)
+  COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind
+endif
+
 TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
+    $(COMPILENIMBUS_ADD_MODS) \
     build.tools.generatenimbus.Generator
 
 TOOL_WRAPPERGENERATOR = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
--- a/make/gendata/GendataBreakIterator.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/gendata/GendataBreakIterator.gmk	Thu May 05 19:11:09 2016 +0000
@@ -62,10 +62,13 @@
     BIN := $(BREAK_ITERATOR_CLASSES)/jdk.localedata))
 
 ifeq ($(BOOT_JDK_MODULAR), true)
-  BREAK_ITERATOR_BOOTCLASSPATH := -Xpatch:$(BREAK_ITERATOR_CLASSES) \
-        -XaddExports:java.base/sun.text=ALL-UNNAMED \
-        -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
-        -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED
+  BREAK_ITERATOR_BOOTCLASSPATH := \
+      -Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
+      -Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
+      -XaddExports:java.base/sun.text=ALL-UNNAMED \
+      -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
+      -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
+      #
 else
   BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \
       $(BREAK_ITERATOR_CLASSES)/java.base \
--- a/make/launcher/Launcher-java.desktop.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/launcher/Launcher-java.desktop.gmk	Thu May 05 19:11:09 2016 +0000
@@ -31,7 +31,7 @@
 ifndef BUILD_HEADLESS_ONLY
   $(eval $(call SetupBuildLauncher, appletviewer, \
       MAIN_CLASS := sun.applet.Main, \
-      JAVA_ARGS := -addmods ALL-SYSTEM, \
+      JAVA_ARGS := -addmods ALL-DEFAULT, \
       LIBS_unix := $(X_LIBS), \
   ))
 endif
--- a/make/launcher/Launcher-java.scripting.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/launcher/Launcher-java.scripting.gmk	Thu May 05 19:11:09 2016 +0000
@@ -27,4 +27,5 @@
 
 $(eval $(call SetupBuildLauncher, jrunscript, \
     MAIN_CLASS := com.sun.tools.script.shell.Main, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
 ))
--- a/make/launcher/Launcher-jdk.compiler.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/launcher/Launcher-jdk.compiler.gmk	Thu May 05 19:11:09 2016 +0000
@@ -27,7 +27,8 @@
 
 $(eval $(call SetupBuildLauncher, javac, \
    MAIN_CLASS := com.sun.tools.javac.Main, \
-    CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
+   JAVA_ARGS := -addmods ALL-DEFAULT, \
+   CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
 
--- a/make/launcher/Launcher-jdk.javadoc.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/launcher/Launcher-jdk.javadoc.gmk	Thu May 05 19:11:09 2016 +0000
@@ -27,6 +27,7 @@
 
 $(eval $(call SetupBuildLauncher, javadoc, \
     MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
     CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
--- a/make/launcher/Launcher-jdk.jlink.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/launcher/Launcher-jdk.jlink.gmk	Thu May 05 19:11:09 2016 +0000
@@ -32,6 +32,7 @@
 
 $(eval $(call SetupBuildLauncher, jlink,\
     MAIN_CLASS := jdk.tools.jlink.internal.Main, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
     CFLAGS := -DENABLE_ARG_FILES \
         -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
--- a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk	Thu May 05 17:35:48 2016 +0000
+++ b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk	Thu May 05 19:11:09 2016 +0000
@@ -27,6 +27,6 @@
 
 $(eval $(call SetupBuildLauncher, jjs, \
     MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
-    JAVA_ARGS := -addmods ALL-SYSTEM, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
     CFLAGS := -DENABLE_ARG_FILES, \
 ))
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -102,7 +102,7 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        String userHome = GetPropertyAction.getProperty("user.home");
+        String userHome = GetPropertyAction.privilegedGetProperty("user.home");
         Path userMimeTypes = Paths.get(userHome, ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
--- a/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -53,7 +53,7 @@
     start = t.tv_sec * 1000 + t.tv_usec / 1000;
 
     for (;;) {
-        int res = epoll_wait(epfd, events, numfds, timeout);
+        int res = epoll_wait(epfd, events, numfds, remaining);
         if (res < 0 && errno == EINTR) {
             if (remaining >= 0) {
                 gettimeofday(&t, NULL);
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu May 05 19:11:09 2016 +0000
@@ -84,7 +84,8 @@
     static {
         IOUtil.load();
         initStructSizes();
-        String datamodel = GetPropertyAction.getProperty("sun.arch.data.model");
+        String datamodel =
+                GetPropertyAction.privilegedGetProperty("sun.arch.data.model");
         is64bit = "64".equals(datamodel);
     }
 
--- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java	Thu May 05 19:11:09 2016 +0000
@@ -29,8 +29,6 @@
 import java.io.IOException;
 import java.util.*;
 import java.util.regex.Pattern;
-import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
 
 import static sun.nio.fs.MacOSXNativeDispatcher.*;
 
--- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -46,8 +46,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(
-            GetPropertyAction.getProperty("user.home"), ".mime.types");
+        Path userMimeTypes = Paths.get(GetPropertyAction
+                .privilegedGetProperty("user.home"), ".mime.types");
 
         return chain(new MimeTypesFileTypeDetector(userMimeTypes),
                      new UTIFileTypeDetector());
--- a/src/java.base/share/classes/java/io/File.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/io/File.java	Thu May 05 19:11:09 2016 +0000
@@ -1896,7 +1896,7 @@
 
         // temporary directory location
         private static final File tmpdir = new File(
-                GetPropertyAction.getProperty("java.io.tmpdir"));
+                GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));
         static File location() {
             return tmpdir;
         }
--- a/src/java.base/share/classes/java/lang/Class.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/Class.java	Thu May 05 19:11:09 2016 +0000
@@ -470,7 +470,7 @@
      * expression with an empty argument list.  The class is initialized if it
      * has not already been initialized.
      *
-     * <p>Note that this method propagates any exception thrown by the
+     * @deprecated This method propagates any exception thrown by the
      * nullary constructor, including a checked exception.  Use of
      * this method effectively bypasses the compile-time exception
      * checking that would otherwise be performed by the compiler.
@@ -500,6 +500,7 @@
      *          of this class.
      */
     @CallerSensitive
+    @Deprecated(since="9")
     public T newInstance()
         throws InstantiationException, IllegalAccessException
     {
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Thu May 05 19:11:09 2016 +0000
@@ -2615,7 +2615,7 @@
     ServicesCatalog createOrGetServicesCatalog() {
         ServicesCatalog catalog = servicesCatalog;
         if (catalog == null) {
-            catalog = new ServicesCatalog();
+            catalog = ServicesCatalog.create();
             boolean set = trySetObjectField("servicesCatalog", catalog);
             if (!set) {
                 // beaten by someone else
--- a/src/java.base/share/classes/java/lang/ProcessBuilder.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java	Thu May 05 19:11:09 2016 +0000
@@ -468,7 +468,7 @@
      */
     public abstract static class Redirect {
         private static final File NULL_FILE = new File(
-                (GetPropertyAction.getProperty("os.name")
+                (GetPropertyAction.privilegedGetProperty("os.name")
                         .startsWith("Windows") ? "NUL" : "/dev/null")
         );
 
--- a/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -78,7 +78,8 @@
      * Performance work and extensive testing is needed to replace the
      * VM built-in backtrace filled in Throwable with the StackWalker.
      */
-    final static boolean isDebug = getProperty("stackwalk.debug", false);
+    final static boolean isDebug =
+            "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug"));
 
     static <T> StackFrameTraverser<T>
         makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
@@ -988,11 +989,4 @@
                 c.getName().startsWith("java.lang.invoke.LambdaForm");
     }
 
-    private static boolean getProperty(String key, boolean value) {
-        String s = GetPropertyAction.getProperty(key);
-        if (s != null) {
-            return Boolean.parseBoolean(s);
-        }
-        return value;
-    }
 }
--- a/src/java.base/share/classes/java/lang/System.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/System.java	Thu May 05 19:11:09 2016 +0000
@@ -69,7 +69,6 @@
 import jdk.internal.logger.LocalizedLoggerWrapper;
 
 import jdk.internal.module.ModuleBootstrap;
-import jdk.internal.module.Modules;
 import jdk.internal.module.ServicesCatalog;
 
 /**
@@ -1924,10 +1923,6 @@
         // initialize the module system
         System.bootLayer = ModuleBootstrap.boot();
 
-        // base module needs to be loose (CODETOOLS-7901619)
-        Module base = Object.class.getModule();
-        Modules.addReads(base, null);
-
         // module system initialized
         VM.initLevel(2);
     }
--- a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu May 05 19:11:09 2016 +0000
@@ -33,8 +33,6 @@
 import sun.invoke.util.Wrapper;
 
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Objects;
 
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu May 05 19:11:09 2016 +0000
@@ -88,7 +88,7 @@
 
     static {
         final String key = "jdk.internal.lambda.dumpProxyClasses";
-        String path = GetPropertyAction.getProperty(key);
+        String path = GetPropertyAction.privilegedGetProperty(key);
         dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/Invokers.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java	Thu May 05 19:11:09 2016 +0000
@@ -396,7 +396,7 @@
         LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)),
                                           ARG_LIMIT + 1, names);
 
-        lform.prepare();
+        lform.compileToBytecode();
         return lform;
     }
 
@@ -448,7 +448,7 @@
         LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)),
                                           ARG_LIMIT, names);
 
-        lform.prepare();
+        lform.compileToBytecode();
         return lform;
     }
 
@@ -497,44 +497,33 @@
 
     /*non-public*/ static
     @ForceInline
-    MethodHandle checkVarHandleGenericType(VarHandle vh, VarHandle.AccessDescriptor vad) {
-        MethodType expected = vad.symbolicMethodType;
-        MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
-
-        MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
-        if (mn == null)
-            throw vh.unsupported();
-        // TODO the following MH is not constant, cache in stable field array
-        // on VarForm?
-        MethodHandle mh = DirectMethodHandle.make(mn);
-        if (actual == expected) {
+    MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        // Test for exact match on invoker types
+        // TODO match with erased types and add cast of return value to lambda form
+        MethodHandle mh = handle.getMethodHandle(ad.mode);
+        if (mh.type() == ad.symbolicMethodTypeInvoker) {
             return mh;
         }
         else {
-            // Adapt to the actual (which should never fail since mh's method
-            // type is in the basic form), then to the expected (which my fail
-            // if the symbolic type descriptor does not match)
-            // TODO optimize for the case of actual.erased() == expected.erased()
-            return mh.asType(actual.insertParameterTypes(0, VarHandle.class)).
-                    asType(expected.insertParameterTypes(0, VarHandle.class));
+            return mh.asType(ad.symbolicMethodTypeInvoker);
         }
     }
 
     /*non-public*/ static
     @ForceInline
-    void checkVarHandleExactType(VarHandle vh, VarHandle.AccessDescriptor vad) {
-        MethodType expected = vad.symbolicMethodType;
-        MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
-        if (actual != expected)
-            throw newWrongMethodTypeException(expected, actual);
+    void checkVarHandleExactType(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        MethodType erasedTarget = handle.vform.methodType_table[ad.type];
+        MethodType erasedSymbolic = ad.symbolicMethodTypeErased;
+        if (erasedTarget != erasedSymbolic)
+            throw newWrongMethodTypeException(erasedTarget, erasedSymbolic);
     }
 
     /*non-public*/ static
     @ForceInline
-    MemberName getVarHandleMemberName(VarHandle vh, VarHandle.AccessDescriptor vad) {
-        MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
+    MemberName getVarHandleMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        MemberName mn = handle.vform.memberName_table[ad.mode];
         if (mn == null) {
-            throw vh.unsupported();
+            throw handle.unsupported();
         }
         return mn;
     }
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu May 05 19:11:09 2016 +0000
@@ -430,14 +430,14 @@
 
         // If not polymorphic in the return type, such as the compareAndSet
         // methods that return boolean
-        if (ak.isPolyMorphicInReturnType) {
-            if (ak.returnType != mtype.returnType()) {
+        if (ak.at.isMonomorphicInReturnType) {
+            if (ak.at.returnType != mtype.returnType()) {
                 // The caller contains a different return type than that
                 // defined by the method
                 throw newNoSuchMethodErrorOnVarHandle(name, mtype);
             }
             // Adjust the return type of the signature method type
-            sigType = sigType.changeReturnType(ak.returnType);
+            sigType = sigType.changeReturnType(ak.at.returnType);
         }
 
         // Get the guard method type for linking
@@ -455,26 +455,25 @@
             MemberName linker = new MemberName(
                     VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType),
                     guardType, REF_invokeStatic);
-            try {
-                return MemberName.getFactory().resolveOrFail(
-                        REF_invokeStatic, linker, VarHandleGuards.class, ReflectiveOperationException.class);
-            } catch (ReflectiveOperationException ex) {
-                // Fall back to lambda form linkage if guard method is not available
-                // TODO Optionally log fallback ?
+
+            linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
+                                                           VarHandleGuards.class);
+            if (linker != null) {
+                return linker;
             }
+            // Fall back to lambda form linkage if guard method is not available
+            // TODO Optionally log fallback ?
         }
         return Invokers.varHandleInvokeLinkerMethod(name, mtype);
     }
     static String getVarHandleMethodSignature(MethodType mt) {
-        StringBuilder sb = new StringBuilder(mt.parameterCount() + 1);
+        StringBuilder sb = new StringBuilder(mt.parameterCount() + 2);
 
         for (int i = 0; i < mt.parameterCount(); i++) {
             Class<?> pt = mt.parameterType(i);
             sb.append(getCharType(pt));
         }
-
         sb.append('_').append(getCharType(mt.returnType()));
-
         return sb.toString();
     }
     static char getCharType(Class<?> pt) {
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Thu May 05 19:11:09 2016 +0000
@@ -53,7 +53,7 @@
     static final boolean VAR_HANDLE_GUARDS;
 
     static {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
                 props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));
         DUMP_CLASS_FILES = Boolean.parseBoolean(
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -197,7 +197,7 @@
         // DEBUG = false;        // implied
         // DUMPER = null;        // implied
 
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         final String strategy =
                 props.getProperty("java.lang.invoke.stringConcat");
         CACHE_ENABLE = Boolean.parseBoolean(
--- a/src/java.base/share/classes/java/lang/invoke/VarForm.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/VarForm.java	Thu May 05 19:11:09 2016 +0000
@@ -24,42 +24,102 @@
  */
 package java.lang.invoke;
 
+import jdk.internal.vm.annotation.ForceInline;
 import jdk.internal.vm.annotation.Stable;
 
 import java.lang.invoke.VarHandle.AccessMode;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * A var handle form containing a set of member name, one for each operation.
  * Each member characterizes a static method.
  */
-class VarForm {
+final class VarForm {
 
-    // Holds VarForm for VarHandle implementation classes
-    private static final ClassValue<VarForm> VFORMS
-            = new ClassValue<>() {
-        @Override
-        protected VarForm computeValue(Class<?> impl) {
-            return new VarForm(linkFromStatic(impl));
-        }
-    };
+    final @Stable MethodType[] methodType_table;
 
-    final @Stable MemberName[] table;
+    final @Stable MemberName[] memberName_table;
 
-    VarForm(MemberName[] table) {
-        this.table = table;
+    VarForm(Class<?> implClass, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
+        this.methodType_table = new MethodType[VarHandle.AccessType.values().length];
+
+        // TODO lazily calculate
+        this.memberName_table = linkFromStatic(implClass);
+
+        // (Receiver, <Intermediates>)
+        List<Class<?>> l = new ArrayList<>();
+        if (receiver != null)
+            l.add(receiver);
+        l.addAll(Arrays.asList(intermediate));
+
+        // (Receiver, <Intermediates>)Value
+        methodType_table[VarHandle.AccessType.GET.ordinal()] =
+                MethodType.methodType(value, l).erase();
+
+        // (Receiver, <Intermediates>, Value)void
+        l.add(value);
+        methodType_table[VarHandle.AccessType.SET.ordinal()] =
+                MethodType.methodType(void.class, l).erase();
+
+        // (Receiver, <Intermediates>, Value)Value
+        methodType_table[VarHandle.AccessType.GET_AND_UPDATE.ordinal()] =
+                MethodType.methodType(value, l).erase();
+
+        // (Receiver, <Intermediates>, Value, Value)boolean
+        l.add(value);
+        methodType_table[VarHandle.AccessType.COMPARE_AND_SWAP.ordinal()] =
+                MethodType.methodType(boolean.class, l).erase();
+
+        // (Receiver, <Intermediates>, Value, Value)Value
+        methodType_table[VarHandle.AccessType.COMPARE_AND_EXCHANGE.ordinal()] =
+                MethodType.methodType(value, l).erase();
     }
 
-    /**
-     * Creates a var form given an VarHandle implementation class.
-     * Each signature polymorphic method is linked to a static method of the
-     * same name on the implementation class or a super class.
-     */
-    static VarForm createFromStatic(Class<? extends VarHandle> impl) {
-        return VFORMS.get(impl);
+    @ForceInline
+    final MethodType getMethodType(int type) {
+        return methodType_table[type];
     }
 
+    @ForceInline
+    final MemberName getMemberName(int mode) {
+        // TODO calculate lazily
+        MemberName mn = memberName_table[mode];
+        if (mn == null) {
+            throw new UnsupportedOperationException();
+        }
+        return mn;
+    }
+
+
+    @Stable
+    MethodType[] methodType_V_table;
+
+    @ForceInline
+    final MethodType[] getMethodType_V_init() {
+        MethodType[] table = new MethodType[VarHandle.AccessType.values().length];
+        for (int i = 0; i < methodType_table.length; i++) {
+            MethodType mt = methodType_table[i];
+            // TODO only adjust for sig-poly methods returning Object
+            table[i] = mt.changeReturnType(void.class);
+        }
+        methodType_V_table = table;
+        return table;
+    }
+
+    @ForceInline
+    final MethodType getMethodType_V(int type) {
+        MethodType[] table = methodType_V_table;
+        if (table == null) {
+            table = getMethodType_V_init();
+        }
+        return table[type];
+    }
+
+
     /**
      * Link all signature polymorphic methods.
      */
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu May 05 19:11:09 2016 +0000
@@ -27,10 +27,9 @@
 
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.vm.annotation.ForceInline;
+import jdk.internal.vm.annotation.Stable;
 
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -406,42 +405,10 @@
  * @since 9
  */
 public abstract class VarHandle {
-    // Use explicit final fields rather than an @Stable array as
-    // this can reduce the memory per handle
-    // e.g. by 24 bytes on 64 bit architectures
-    final MethodType typeGet;
-    final MethodType typeSet;
-    final MethodType typeCompareSwap;
-    final MethodType typeCompareExchange;
-    final MethodType typeGetAndUpdate;
-
     final VarForm vform;
 
-    VarHandle(VarForm vform, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
+    VarHandle(VarForm vform) {
         this.vform = vform;
-
-        // (Receiver, <Intermediates>)
-        List<Class<?>> l = new ArrayList<>();
-        if (receiver != null)
-            l.add(receiver);
-        l.addAll(Arrays.asList(intermediate));
-
-        // (Receiver, <Intermediates>)Value
-        this.typeGet = MethodType.methodType(value, l);
-
-        // (Receiver, <Intermediates>, Value)void
-        l.add(value);
-        this.typeSet = MethodType.methodType(void.class, l);
-
-        // (Receiver, <Intermediates>, Value)Value
-        this.typeGetAndUpdate = MethodType.methodType(value, l);
-
-        // (Receiver, <Intermediates>, Value, Value)boolean
-        l.add(value);
-        this.typeCompareSwap = MethodType.methodType(boolean.class, l);
-
-        // (Receiver, <Intermediates>, Value, Value)Value
-        this.typeCompareExchange = MethodType.methodType(value, l);
     }
 
     RuntimeException unsupported() {
@@ -1090,36 +1057,83 @@
     Object addAndGet(Object... args);
 
     enum AccessType {
-        GET,                    // 0
-        SET,                    // 1
-        COMPARE_AND_SWAP,       // 2
-        COMPARE_AND_EXCHANGE,   // 3
-        GET_AND_UPDATE;         // 4
+        GET(Object.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(0, receiver, intermediate);
+                fillParameters(ps, receiver, intermediate);
+                return MethodType.methodType(value, ps);
+            }
+        },
+        SET(void.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i] = value;
+                return MethodType.methodType(void.class, ps);
+            }
+        },
+        COMPARE_AND_SWAP(boolean.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i++] = value;
+                ps[i] = value;
+                return MethodType.methodType(boolean.class, ps);
+            }
+        },
+        COMPARE_AND_EXCHANGE(Object.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i++] = value;
+                ps[i] = value;
+                return MethodType.methodType(value, ps);
+            }
+        },
+        GET_AND_UPDATE(Object.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i] = value;
+                return MethodType.methodType(value, ps);
+            }
+        };
 
-        MethodType getMethodType(VarHandle vh) {
-            return getMethodType(this.ordinal(), vh);
+        final Class<?> returnType;
+        final boolean isMonomorphicInReturnType;
+
+        AccessType(Class<?> returnType) {
+            this.returnType = returnType;
+            isMonomorphicInReturnType = returnType != Object.class;
         }
 
-        @ForceInline
-        static MethodType getMethodType(int ordinal, VarHandle vh) {
-            if (ordinal == 0) {
-                return vh.typeGet;
-            }
-            else if (ordinal == 1) {
-                return vh.typeSet;
-            }
-            else if (ordinal == 2) {
-                return vh.typeCompareSwap;
-            }
-            else if (ordinal == 3) {
-                return vh.typeCompareExchange;
-            }
-            else if (ordinal == 4) {
-                return vh.typeGetAndUpdate;
-            }
-            else {
-                throw new IllegalStateException("Illegal access type: " + ordinal);
-            }
+        abstract MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                           Class<?>... intermediate);
+
+        private static Class<?>[] allocateParameters(int values,
+                                                     Class<?> receiver, Class<?>... intermediate) {
+            int size = ((receiver != null) ? 1 : 0) + intermediate.length + values;
+            return new Class<?>[size];
+        }
+
+        private static int fillParameters(Class<?>[] ps,
+                                          Class<?> receiver, Class<?>... intermediate) {
+            int i = 0;
+            if (receiver != null)
+                ps[i++] = receiver;
+            for (int j = 0; j < intermediate.length; j++)
+                ps[i++] = intermediate[j];
+            return i;
         }
     }
 
@@ -1133,115 +1147,115 @@
          * method
          * {@link VarHandle#get VarHandle.get}
          */
-        GET("get", AccessType.GET, Object.class),
+        GET("get", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#set VarHandle.set}
          */
-        SET("set", AccessType.SET, void.class),
+        SET("set", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getVolatile VarHandle.getVolatile}
          */
-        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
+        GET_VOLATILE("getVolatile", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setVolatile VarHandle.setVolatile}
          */
-        SET_VOLATILE("setVolatile", AccessType.SET, void.class),
+        SET_VOLATILE("setVolatile", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAcquire VarHandle.getAcquire}
          */
-        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
+        GET_ACQUIRE("getAcquire", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setRelease VarHandle.setRelease}
          */
-        SET_RELEASE("setRelease", AccessType.SET, void.class),
+        SET_RELEASE("setRelease", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getOpaque VarHandle.getOpaque}
          */
-        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
+        GET_OPAQUE("getOpaque", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setOpaque VarHandle.setOpaque}
          */
-        SET_OPAQUE("setOpaque", AccessType.SET, void.class),
+        SET_OPAQUE("setOpaque", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
          */
-        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
          */
-        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
+        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
          */
-        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
          */
-        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
          */
-        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
          */
-        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
          */
-        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
          */
-        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndSet VarHandle.getAndSet}
          */
-        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
          */
-        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#addAndGet VarHandle.addAndGet}
          */
-        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
+        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE),
         ;
 
         static final Map<String, AccessMode> methodNameToAccessMode;
@@ -1256,10 +1270,8 @@
 
         final String methodName;
         final AccessType at;
-        final boolean isPolyMorphicInReturnType;
-        final Class<?> returnType;
 
-        AccessMode(final String methodName, AccessType at, Class<?> returnType) {
+        AccessMode(final String methodName, AccessType at) {
             this.methodName = methodName;
             this.at = at;
 
@@ -1267,10 +1279,7 @@
             assert methodName.equals(toMethodName(name()));
             // Assert that return type is correct
             // Otherwise, when disabled avoid using reflection
-            assert returnType == getReturnType(methodName);
-
-            this.returnType = returnType;
-            isPolyMorphicInReturnType = returnType != Object.class;
+            assert at.returnType == getReturnType(methodName);
         }
 
         /**
@@ -1324,17 +1333,21 @@
 
         @ForceInline
         static MemberName getMemberName(int ordinal, VarForm vform) {
-            return vform.table[ordinal];
+            return vform.memberName_table[ordinal];
         }
     }
 
     static final class AccessDescriptor {
-        final MethodType symbolicMethodType;
+        final MethodType symbolicMethodTypeErased;
+        final MethodType symbolicMethodTypeInvoker;
+        final Class<?> returnType;
         final int type;
         final int mode;
 
         public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
-            this.symbolicMethodType = symbolicMethodType;
+            this.symbolicMethodTypeErased = symbolicMethodType.erase();
+            this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class);
+            this.returnType = symbolicMethodType.returnType();
             this.type = type;
             this.mode = mode;
         }
@@ -1346,6 +1359,7 @@
      * @return the variable type of variables referenced by this VarHandle
      */
     public final Class<?> varType() {
+        MethodType typeSet = accessModeType(AccessMode.SET);
         return typeSet.parameterType(typeSet.parameterCount() - 1);
     }
 
@@ -1356,6 +1370,7 @@
      * list is unmodifiable
      */
     public final List<Class<?>> coordinateTypes() {
+        MethodType typeGet = accessModeType(AccessMode.GET);
         return typeGet.parameterList();
     }
 
@@ -1374,9 +1389,15 @@
      * @return the access mode type for the given access mode
      */
     public final MethodType accessModeType(AccessMode accessMode) {
-        return accessMode.at.getMethodType(this);
+        TypesAndInvokers tis = getTypesAndInvokers();
+        MethodType mt = tis.methodType_table[accessMode.at.ordinal()];
+        if (mt == null) {
+            mt = tis.methodType_table[accessMode.at.ordinal()] =
+                    accessModeTypeUncached(accessMode);
+        }
+        return mt;
     }
-
+    abstract MethodType accessModeTypeUncached(AccessMode accessMode);
 
     /**
      * Returns {@code true} if the given access mode is supported, otherwise
@@ -1417,9 +1438,8 @@
     public final MethodHandle toMethodHandle(AccessMode accessMode) {
         MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
         if (mn != null) {
-            return DirectMethodHandle.make(mn).
-                    bindTo(this).
-                    asType(accessMode.at.getMethodType(this));
+            MethodHandle mh = getMethodHandle(accessMode.ordinal());
+            return mh.bindTo(this);
         }
         else {
             // Ensure an UnsupportedOperationException is thrown
@@ -1428,6 +1448,51 @@
         }
     }
 
+    @Stable
+    TypesAndInvokers typesAndInvokers;
+
+    static class TypesAndInvokers {
+        final @Stable
+        MethodType[] methodType_table =
+                new MethodType[VarHandle.AccessType.values().length];
+
+        final @Stable
+        MethodHandle[] methodHandle_table =
+                new MethodHandle[AccessMode.values().length];
+    }
+
+    @ForceInline
+    private final TypesAndInvokers getTypesAndInvokers() {
+        TypesAndInvokers tis = typesAndInvokers;
+        if (tis == null) {
+            tis = typesAndInvokers = new TypesAndInvokers();
+        }
+        return tis;
+    }
+
+    @ForceInline
+    final MethodHandle getMethodHandle(int mode) {
+        TypesAndInvokers tis = getTypesAndInvokers();
+        MethodHandle mh = tis.methodHandle_table[mode];
+        if (mh == null) {
+            mh = tis.methodHandle_table[mode] = getMethodHandleUncached(tis, mode);
+        }
+        return mh;
+    }
+    private final MethodHandle getMethodHandleUncached(TypesAndInvokers tis, int mode) {
+        MethodType mt = accessModeType(AccessMode.values()[mode]).
+                insertParameterTypes(0, VarHandle.class);
+        MemberName mn = vform.getMemberName(mode);
+        DirectMethodHandle dmh = DirectMethodHandle.make(mn);
+        // Such a method handle must not be publically exposed directly
+        // otherwise it can be cracked, it must be transformed or rebound
+        // before exposure
+        MethodHandle mh = dmh.copyWith(mt, dmh.form);
+        assert mh.type().erase() == mn.getMethodType().erase();
+        return mh;
+    }
+
+
     /*non-public*/
     final void updateVarForm(VarForm newVForm) {
         if (vform == newVForm) return;
@@ -1453,6 +1518,10 @@
         catch (ReflectiveOperationException e) {
             throw newInternalError(e);
         }
+
+        // The VarHandleGuards must be initialized to ensure correct
+        // compilation of the guard methods
+        UNSAFE.ensureClassInitialized(VarHandleGuards.class);
     }
 
 
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java	Thu May 05 19:11:09 2016 +0000
@@ -30,1361 +30,1008 @@
 final class VarHandleGuards {
 
     @ForceInline
-    final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
-        MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);
-        if (mn == null) {
-            throw handle.unsupported();
-        }
-        return mn;
-    }
-
-    @ForceInline
     @LambdaForm.Compiled
     final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu May 05 19:11:09 2016 +0000
@@ -280,28 +280,29 @@
 //                "@ForceInline\n" +
 //                "@LambdaForm.Compiled\n" +
 //                "final static <METHOD> throws Throwable {\n" +
-//                "    MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);\n" +
-//                "    MethodType symbolic = ad.symbolicMethodType;\n" +
-//                "    if (target == symbolic) {\n" +
-//                "        <RETURN>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
-//                "    }\n" +
-//                "    else if (target.erase() == symbolic.erase()) {\n" +
+//                "    if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodType) {\n" +
 //                "        <RESULT_ERASED>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);<RETURN_ERASED>\n" +
 //                "    }\n" +
 //                "    else {\n" +
-//                "        MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);\n" +
-//                "        <RETURN>vh_invoker.invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
+//                "        MethodHandle mh = handle.getMethodHandle(ad.mode);\n" +
+//                "        <RETURN>mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
 //                "    }\n" +
 //                "}";
 //
-//        static final String GET_MEMBER_NAME_METHOD =
+//        static final String GUARD_METHOD_TEMPLATE_V =
 //                "@ForceInline\n" +
-//                "final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {\n" +
-//                "    MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);\n" +
-//                "    if (mn == null) {\n" +
-//                "        throw handle.unsupported();\n" +
+//                "@LambdaForm.Compiled\n" +
+//                "final static <METHOD> throws Throwable {\n" +
+//                "    if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodType) {\n" +
+//                "        MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
 //                "    }\n" +
-//                "    return mn;\n" +
+//                "    else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodType) {\n" +
+//                "        MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
+//                "    }\n" +
+//                "    else {\n" +
+//                "        MethodHandle mh = handle.getMethodHandle(ad.mode);\n" +
+//                "        mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
+//                "    }\n" +
 //                "}";
 //
 //        // A template for deriving the operations
@@ -345,8 +346,6 @@
 //            System.out.println("final class VarHandleGuards {");
 //
 //            System.out.println();
-//            System.out.println(GET_MEMBER_NAME_METHOD);
-//            System.out.println();
 //
 //            // Declare the stream of shapes
 //            Stream<HandleType> hts = Stream.of(
@@ -445,7 +444,10 @@
 //
 //            List<String> LINK_TO_STATIC_ARGS = params.keySet().stream().
 //                    collect(toList());
-//            LINK_TO_STATIC_ARGS.add("getMemberName(handle, ad)");
+//            LINK_TO_STATIC_ARGS.add("handle.vform.getMemberName(ad.mode)");
+//            List<String> LINK_TO_STATIC_ARGS_V = params.keySet().stream().
+//                    collect(toList());
+//            LINK_TO_STATIC_ARGS_V.add("handle.vform.getMemberName_V(ad.mode)");
 //
 //            List<String> LINK_TO_INVOKER_ARGS = params.keySet().stream().
 //                    collect(toList());
@@ -464,9 +466,12 @@
 //
 //            String RETURN_ERASED = returnType != Object.class
 //                                   ? ""
-//                                   : " return symbolic.returnType().cast(r);";
+//                                   : " return ad.returnType.cast(r);";
 //
-//            return GUARD_METHOD_TEMPLATE.
+//            String template = returnType == void.class
+//                              ? GUARD_METHOD_TEMPLATE_V
+//                              : GUARD_METHOD_TEMPLATE;
+//            return template.
 //                    replace("<METHOD>", METHOD).
 //                    replace("<NAME>", NAME).
 //                    replaceAll("<RETURN>", RETURN).
@@ -474,6 +479,8 @@
 //                    replace("<RETURN_ERASED>", RETURN_ERASED).
 //                    replaceAll("<LINK_TO_STATIC_ARGS>", LINK_TO_STATIC_ARGS.stream().
 //                            collect(joining(", "))).
+//                    replaceAll("<LINK_TO_STATIC_ARGS_V>", LINK_TO_STATIC_ARGS_V.stream().
+//                            collect(joining(", "))).
 //                    replace("<LINK_TO_INVOKER_ARGS>", LINK_TO_INVOKER_ARGS.stream().
 //                            collect(joining(", ")))
 //                    ;
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu May 05 19:11:09 2016 +0000
@@ -41,12 +41,12 @@
 #end[Object]
 
         FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.class);
+            this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.FORM);
         }
 
         protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
-                                        Class<? extends FieldInstanceReadOnly> handle) {
-            super(VarForm.createFromStatic(handle), receiverType, {#if[Object]?fieldType:$type$.class});
+                                        VarForm form) {
+            super(form);
             this.fieldOffset = fieldOffset;
             this.receiverType = receiverType;
 #if[Object]
@@ -54,6 +54,11 @@
 #end[Object]
         }
 
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class});
+        }
+
         @ForceInline
         static $type$ get(FieldInstanceReadOnly handle, Object holder) {
             return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
@@ -77,12 +82,14 @@
             return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
                                  handle.fieldOffset);
         }
+
+        static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, $type$.class);
     }
 
-    static class FieldInstanceReadWrite extends FieldInstanceReadOnly {
+    static final class FieldInstanceReadWrite extends FieldInstanceReadOnly {
 
         FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.class);
+            super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.FORM);
         }
 
         @ForceInline
@@ -202,6 +209,8 @@
                                        value) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(FieldInstanceReadWrite.class, Object.class, $type$.class);
     }
 
 
@@ -213,12 +222,12 @@
 #end[Object]
 
         FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.class);
+            this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM);
         }
 
         protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
-                                      Class<? extends FieldStaticReadOnly> handle) {
-            super(VarForm.createFromStatic(handle), null, {#if[Object]?fieldType:$type$.class});
+                                      VarForm form) {
+            super(form);
             this.base = base;
             this.fieldOffset = fieldOffset;
 #if[Object]
@@ -226,6 +235,11 @@
 #end[Object]
         }
 
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(null, {#if[Object]?fieldType:$type$.class});
+        }
+
         @ForceInline
         static $type$ get(FieldStaticReadOnly handle) {
             return UNSAFE.get$Type$(handle.base,
@@ -249,12 +263,14 @@
             return UNSAFE.get$Type$Acquire(handle.base,
                                  handle.fieldOffset);
         }
+
+        static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, $type$.class);
     }
 
-    static class FieldStaticReadWrite extends FieldStaticReadOnly {
+    static final class FieldStaticReadWrite extends FieldStaticReadOnly {
 
         FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.class);
+            super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM);
         }
 
         @ForceInline
@@ -375,6 +391,8 @@
                                        value) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, $type$.class);
     }
 
 
@@ -387,8 +405,7 @@
 #end[Object]
 
         Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}) {
-            super(VarForm.createFromStatic(Array.class),
-                  {#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+            super(Array.FORM);
             this.abase = abase;
             this.ashift = ashift;
 #if[Object]
@@ -397,6 +414,11 @@
 #end[Object]
         }
 
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+        }
+
         @ForceInline
         static $type$ get(Array handle, Object oarray, int index) {
 #if[Object]
@@ -630,5 +652,7 @@
                     value) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(Array.class, {#if[Object]?Object[].class:$type$[].class}, {#if[Object]?Object.class:$type$.class}, int.class);
     }
 }
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Thu May 05 19:11:09 2016 +0000
@@ -59,13 +59,11 @@
 #end[floatingPoint]
 
 
-    private static class ByteArrayViewVarHandle extends VarHandle {
+    private static abstract class ByteArrayViewVarHandle extends VarHandle {
         final boolean be;
 
-        ByteArrayViewVarHandle(Class<? extends ByteArrayViewVarHandle> implSubType,
-                               Class<?> arrayType, Class<?> component, boolean be) {
-            super(VarForm.createFromStatic(implSubType),
-                  arrayType, component, int.class);
+        ByteArrayViewVarHandle(VarForm form, boolean be) {
+            super(form);
             this.be = be;
         }
     }
@@ -73,7 +71,12 @@
     static final class ArrayHandle extends ByteArrayViewVarHandle {
 
         ArrayHandle(boolean be) {
-            super(ArrayHandle.class, byte[].class, $type$.class, be);
+            super(ArrayHandle.FORM, be);
+        }
+
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(byte[].class, $type$.class, int.class);
         }
 
         @ForceInline
@@ -286,13 +289,20 @@
                     convEndian(handle.be, value))) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(ArrayHandle.class, byte[].class, $type$.class, int.class);
     }
 
 
     static final class ByteBufferHandle extends ByteArrayViewVarHandle {
 
         ByteBufferHandle(boolean be) {
-            super(ByteBufferHandle.class, ByteBuffer.class, $type$.class, be);
+            super(ByteBufferHandle.FORM, be);
+        }
+
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(ByteBuffer.class, $type$.class, int.class);
         }
 
         @ForceInline
@@ -513,5 +523,7 @@
                                       convEndian(handle.be, value))) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(ByteBufferHandle.class, ByteBuffer.class, $type$.class, int.class);
     }
 }
--- a/src/java.base/share/classes/java/lang/module/Configuration.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/Configuration.java	Thu May 05 19:11:09 2016 +0000
@@ -25,6 +25,7 @@
 
 package java.lang.module;
 
+import java.io.PrintStream;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -183,17 +184,20 @@
         this.nameToModule = Collections.emptyMap();
     }
 
-    private Configuration(Configuration parent, Resolver resolver) {
-        Map<ResolvedModule, Set<ResolvedModule>> graph = resolver.finish(this);
+    private Configuration(Configuration parent,
+                          Resolver resolver,
+                          boolean check)
+    {
+        Map<ResolvedModule, Set<ResolvedModule>> g = resolver.finish(this, check);
 
         Map<String, ResolvedModule> nameToModule = new HashMap<>();
-        for (ResolvedModule resolvedModule : graph.keySet()) {
+        for (ResolvedModule resolvedModule : g.keySet()) {
             nameToModule.put(resolvedModule.name(), resolvedModule);
         }
 
         this.parent = parent;
-        this.graph = graph;
-        this.modules = Collections.unmodifiableSet(graph.keySet());
+        this.graph = g;
+        this.modules = Collections.unmodifiableSet(g.keySet());
         this.nameToModule = Collections.unmodifiableMap(nameToModule);
     }
 
@@ -283,10 +287,10 @@
         Objects.requireNonNull(after);
         Objects.requireNonNull(roots);
 
-        Resolver resolver = new Resolver(before, this, after);
+        Resolver resolver = new Resolver(before, this, after, null);
         resolver.resolveRequires(roots);
 
-        return new Configuration(this, resolver);
+        return new Configuration(this, resolver, true);
     }
 
 
@@ -340,10 +344,32 @@
         Objects.requireNonNull(after);
         Objects.requireNonNull(roots);
 
-        Resolver resolver = new Resolver(before, this, after);
+        Resolver resolver = new Resolver(before, this, after, null);
         resolver.resolveRequires(roots).resolveUses();
 
-        return new Configuration(this, resolver);
+        return new Configuration(this, resolver, true);
+    }
+
+
+    /**
+     * Resolves a collection of root modules, with service binding, and with
+     * the empty configuration as its parent. The post resolution checks
+     * are optionally run.
+     *
+     * This method is used to create the configuration for the boot layer.
+     */
+    static Configuration resolveRequiresAndUses(ModuleFinder finder,
+                                                Collection<String> roots,
+                                                boolean check,
+                                                PrintStream traceOutput)
+    {
+        Configuration parent = empty();
+
+        Resolver resolver
+            = new Resolver(finder, parent, ModuleFinder.empty(), traceOutput);
+        resolver.resolveRequires(roots).resolveUses();
+
+        return new Configuration(parent, resolver, check);
     }
 
 
--- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Thu May 05 19:11:09 2016 +0000
@@ -27,13 +27,17 @@
 
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.io.UncheckedIOException;
+import java.net.URI;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -45,7 +49,7 @@
 import static java.util.Objects.*;
 
 import jdk.internal.module.Checks;
-import jdk.internal.module.Hasher.DependencyHashes;
+import jdk.internal.module.ModuleHashes;
 
 
 /**
@@ -372,8 +376,9 @@
 
         private Provides(String service, Set<String> providers, boolean check) {
             this.service = check ? requireServiceTypeName(service) : service;
-            providers = check ? Collections.unmodifiableSet(new HashSet<>(providers))
-                              : Collections.unmodifiableSet(providers);
+            providers = check
+                ? Collections.unmodifiableSet(new LinkedHashSet<>(providers))
+                : Collections.unmodifiableSet(providers);
             if (providers.isEmpty())
                 throw new IllegalArgumentException("Empty providers set");
             if (check)
@@ -787,7 +792,7 @@
     private final String osVersion;
     private final Set<String> conceals;
     private final Set<String> packages;
-    private final DependencyHashes hashes;
+    private final ModuleHashes hashes;
 
     private ModuleDescriptor(String name,
                              boolean automatic,
@@ -802,7 +807,7 @@
                              String osArch,
                              String osVersion,
                              Set<String> conceals,
-                             DependencyHashes hashes)
+                             ModuleHashes hashes)
     {
 
         this.name = name;
@@ -878,7 +883,8 @@
                      String osArch,
                      String osVersion,
                      Set<String> conceals,
-                     Set<String> packages) {
+                     Set<String> packages,
+                     ModuleHashes hashes) {
         this.name = name;
         this.automatic = automatic;
         this.synthetic = synthetic;
@@ -894,7 +900,7 @@
         this.osName = osName;
         this.osArch = osArch;
         this.osVersion = osVersion;
-        this.hashes = null;
+        this.hashes = hashes;
     }
 
     /**
@@ -1063,9 +1069,9 @@
     }
 
     /**
-     * Returns the object with the hashes of the dependences.
+     * Returns the object with the hashes of other modules
      */
-    Optional<DependencyHashes> hashes() {
+    Optional<ModuleHashes> hashes() {
         return Optional.ofNullable(hashes);
     }
 
@@ -1103,7 +1109,7 @@
         String osArch;
         String osVersion;
         String mainClass;
-        DependencyHashes hashes;
+        ModuleHashes hashes;
 
         /**
          * Initializes a new builder with the given module name.
@@ -1580,7 +1586,7 @@
             return this;
         }
 
-        /* package */ Builder hashes(DependencyHashes hashes) {
+        /* package */ Builder hashes(ModuleHashes hashes) {
             this.hashes = hashes;
             return this;
         }
@@ -1719,7 +1725,9 @@
             hc = hc * 43 + Objects.hashCode(osVersion);
             hc = hc * 43 + Objects.hashCode(conceals);
             hc = hc * 43 + Objects.hashCode(hashes);
-            if (hc != 0) hash = hc;
+            if (hc == 0)
+                hc = -1;
+            hash = hc;
         }
         return hc;
     }
@@ -1925,11 +1933,12 @@
 
     static {
         /**
-         * Setup the shared secret to allow code in other packages create
-         * ModuleDescriptor and associated objects directly.
+         * Setup the shared secret to allow code in other packages access
+         * private package methods in java.lang.module.
          */
         jdk.internal.misc.SharedSecrets
             .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
+
                 @Override
                 public Requires newRequires(Set<Requires.Modifier> ms, String mn) {
                     return new Requires(ms, mn, false);
@@ -1974,7 +1983,8 @@
                                                             String osArch,
                                                             String osVersion,
                                                             Set<String> conceals,
-                                                            Set<String> packages) {
+                                                            Set<String> packages,
+                                                            ModuleHashes hashes) {
                     return new ModuleDescriptor(name,
                                                 automatic,
                                                 synthetic,
@@ -1988,7 +1998,29 @@
                                                 osArch,
                                                 osVersion,
                                                 conceals,
-                                                packages);
+                                                packages,
+                                                hashes);
+                }
+
+                @Override
+                public Configuration resolveRequiresAndUses(ModuleFinder finder,
+                                                            Collection<String> roots,
+                                                            boolean check,
+                                                            PrintStream traceOutput)
+                {
+                    return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
+                }
+
+                @Override
+                public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
+                                                        URI location,
+                                                        Supplier<ModuleReader> s) {
+                    return new ModuleReference(descriptor, location, s, true, null);
+                }
+
+                @Override
+                public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
+                    return descriptor.hashes();
                 }
             });
     }
--- a/src/java.base/share/classes/java/lang/module/ModuleInfo.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModuleInfo.java	Thu May 05 19:11:09 2016 +0000
@@ -37,11 +37,12 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Supplier;
 
-import jdk.internal.module.Hasher.DependencyHashes;
+import jdk.internal.module.ModuleHashes;
 
 import static jdk.internal.module.ClassFileConstants.*;
 
@@ -337,7 +338,7 @@
                 // computeIfAbsent
                 Set<String> providers = pm.get(sn);
                 if (providers == null) {
-                    providers = new HashSet<>();
+                    providers = new LinkedHashSet<>(); // preserve order
                     pm.put(sn, providers);
                 }
                 providers.add(cn);
@@ -425,7 +426,7 @@
             map.put(dn, hash);
         }
 
-        builder.hashes(new DependencyHashes(algorithm, map));
+        builder.hashes(new ModuleHashes(algorithm, map));
     }
 
 
--- a/src/java.base/share/classes/java/lang/module/ModulePath.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModulePath.java	Thu May 05 19:11:09 2016 +0000
@@ -40,7 +40,7 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
@@ -52,7 +52,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
@@ -190,18 +189,16 @@
                 }
             }
 
-            if (attrs.isRegularFile() || attrs.isDirectory()) {
-                // packaged or exploded module
-                ModuleReference mref = readModule(entry, attrs);
-                if (mref != null) {
-                    String name = mref.descriptor().name();
-                    return Collections.singletonMap(name, mref);
-                }
+            // packaged or exploded module
+            ModuleReference mref = readModule(entry, attrs);
+            if (mref != null) {
+                String name = mref.descriptor().name();
+                return Collections.singletonMap(name, mref);
+            } else {
+                // skipped
+                return Collections.emptyMap();
             }
 
-            // not recognized
-            throw new FindException("Unrecognized module: " + entry);
-
         } catch (IOException ioe) {
             throw new FindException(ioe);
         }
@@ -238,16 +235,13 @@
 
                 // module found
                 if (mref != null) {
-
                     // can have at most one version of a module in the directory
                     String name = mref.descriptor().name();
                     if (nameToReference.put(name, mref) != null) {
                         throw new FindException("Two versions of module "
-                                + name + " found in " + dir);
+                                                  + name + " found in " + dir);
                     }
-
                 }
-
             }
         }
 
@@ -257,28 +251,40 @@
 
     /**
      * Locates a packaged or exploded module, returning a {@code ModuleReference}
-     * to the module. Returns {@code null} if the module is not recognized
-     * as a packaged or exploded module.
+     * to the module. Returns {@code null} if the entry is skipped because it is
+     * to a directory that does not contain a module-info.class or it's a hidden
+     * file.
      *
      * @throws IOException if an I/O error occurs
-     * @throws FindException if an error occurs parsing the module descriptor
+     * @throws FindException if the file is not recognized as a module or an
+     *         error occurs parsing its module descriptor
      */
     private ModuleReference readModule(Path entry, BasicFileAttributes attrs)
         throws IOException
     {
         try {
 
-            ModuleReference mref = null;
             if (attrs.isDirectory()) {
-                mref = readExplodedModule(entry);
-            } if (attrs.isRegularFile()) {
-                if (entry.toString().endsWith(".jar")) {
-                    mref = readJar(entry);
-                } else if (isLinkPhase && entry.toString().endsWith(".jmod")) {
-                    mref = readJMod(entry);
+                return readExplodedModule(entry); // may return null
+            }
+
+            String fn = entry.getFileName().toString();
+            if (attrs.isRegularFile()) {
+                if (fn.endsWith(".jar")) {
+                    return readJar(entry);
+                } else if (fn.endsWith(".jmod")) {
+                    if (isLinkPhase)
+                        return readJMod(entry);
+                    throw new FindException("JMOD files not supported: " + entry);
                 }
             }
-            return mref;
+
+            // skip hidden files
+            if (fn.startsWith(".") || Files.isHidden(entry)) {
+                return null;
+            } else {
+                throw new FindException("Unrecognized module: " + entry);
+            }
 
         } catch (InvalidModuleDescriptorException e) {
             throw new FindException("Error reading module: " + entry, e);
@@ -292,15 +298,17 @@
         return zf.stream()
             .filter(e -> e.getName().startsWith("classes/") &&
                     e.getName().endsWith(".class"))
-            .map(e -> toPackageName(e))
+            .map(e -> toPackageName(e.getName().substring(8)))
             .filter(pkg -> pkg.length() > 0) // module-info
-            .distinct()
             .collect(Collectors.toSet());
     }
 
     /**
      * Returns a {@code ModuleReference} to a module in jmod file on the
      * file system.
+     *
+     * @throws IOException
+     * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readJMod(Path file) throws IOException {
         try (ZipFile zf = new ZipFile(file.toString())) {
@@ -419,13 +427,12 @@
 
         // scan the entries in the JAR file to locate the .class and service
         // configuration file
-        Stream<String> stream = jf.stream()
-            .map(e -> e.getName())
-            .filter(e -> (e.endsWith(".class") || e.startsWith(SERVICES_PREFIX)))
-            .distinct();
-        Map<Boolean, Set<String>> map
-            = stream.collect(Collectors.partitioningBy(s -> s.endsWith(".class"),
-                             Collectors.toSet()));
+        Map<Boolean, Set<String>> map =
+            jf.stream()
+              .map(JarEntry::getName)
+              .filter(s -> (s.endsWith(".class") ^ s.startsWith(SERVICES_PREFIX)))
+              .collect(Collectors.partitioningBy(s -> s.endsWith(".class"),
+                                                 Collectors.toSet()));
         Set<String> classFiles = map.get(Boolean.TRUE);
         Set<String> configFiles = map.get(Boolean.FALSE);
 
@@ -433,19 +440,18 @@
         classFiles.stream()
             .map(c -> toPackageName(c))
             .distinct()
-            .forEach(p -> builder.exports(p));
+            .forEach(builder::exports);
 
         // map names of service configuration files to service names
         Set<String> serviceNames = configFiles.stream()
             .map(this::toServiceName)
-            .filter(Optional::isPresent)
-            .map(Optional::get)
+            .flatMap(Optional::stream)
             .collect(Collectors.toSet());
 
         // parse each service configuration file
         for (String sn : serviceNames) {
             JarEntry entry = jf.getJarEntry(SERVICES_PREFIX + sn);
-            Set<String> providerClasses = new HashSet<>();
+            Set<String> providerClasses = new LinkedHashSet<>();
             try (InputStream in = jf.getInputStream(entry)) {
                 BufferedReader reader
                     = new BufferedReader(new InputStreamReader(in, "UTF-8"));
@@ -475,19 +481,25 @@
     private Set<String> jarPackages(JarFile jf) {
         return jf.stream()
             .filter(e -> e.getName().endsWith(".class"))
-            .map(e -> toPackageName(e))
+            .map(e -> toPackageName(e.getName()))
             .filter(pkg -> pkg.length() > 0)   // module-info
-            .distinct()
             .collect(Collectors.toSet());
     }
 
     /**
      * Returns a {@code ModuleReference} to a module in modular JAR file on
      * the file system.
+     *
+     * @throws IOException
+     * @throws FindException
+     * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readJar(Path file) throws IOException {
-        try (JarFile jf = new JarFile(file.toString())) {
-
+        try (JarFile jf = new JarFile(file.toFile(),
+                                      true,               // verify
+                                      ZipFile.OPEN_READ,
+                                      JarFile.Release.RUNTIME))
+        {
             ModuleDescriptor md;
             JarEntry entry = jf.getJarEntry(MODULE_INFO);
             if (entry == null) {
@@ -520,7 +532,6 @@
                                path.toString().endsWith(".class")))
                 .map(path -> toPackageName(dir.relativize(path)))
                 .filter(pkg -> pkg.length() > 0)   // module-info
-                .distinct()
                 .collect(Collectors.toSet());
         } catch (IOException x) {
             throw new UncheckedIOException(x);
@@ -530,6 +541,9 @@
     /**
      * Returns a {@code ModuleReference} to an exploded module on the file
      * system or {@code null} if {@code module-info.class} not found.
+     *
+     * @throws IOException
+     * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readExplodedModule(Path dir) throws IOException {
         Path mi = dir.resolve(MODULE_INFO);
@@ -559,19 +573,6 @@
         }
     }
 
-    private String toPackageName(ZipEntry entry) {
-        String name = entry.getName();
-        assert name.endsWith(".class");
-        // jmod classes in classes/, jar in /
-        int start = name.startsWith("classes/") ? 8 : 0;
-        int index = name.lastIndexOf("/");
-        if (index > start) {
-            return name.substring(start, index).replace('/', '.');
-        } else {
-            return "";
-        }
-    }
-
     private String toPackageName(Path path) {
         String name = path.toString();
         assert name.endsWith(".class");
--- a/src/java.base/share/classes/java/lang/module/ModuleReader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModuleReader.java	Thu May 05 19:11:09 2016 +0000
@@ -142,10 +142,11 @@
      * @see ClassLoader#defineClass(String, ByteBuffer, java.security.ProtectionDomain)
      */
     default Optional<ByteBuffer> read(String name) throws IOException {
-        Optional<InputStream> in = open(name);
-        if (in.isPresent()) {
-            byte[] bytes = in.get().readAllBytes();
-            return Optional.of(ByteBuffer.wrap(bytes));
+        Optional<InputStream> oin = open(name);
+        if (oin.isPresent()) {
+            try (InputStream in = oin.get()) {
+                return Optional.of(ByteBuffer.wrap(in.readAllBytes()));
+            }
         } else {
             return Optional.empty();
         }
--- a/src/java.base/share/classes/java/lang/module/ModuleReference.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModuleReference.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -32,7 +32,7 @@
 import java.util.Optional;
 import java.util.function.Supplier;
 
-import jdk.internal.module.Hasher.HashSupplier;
+import jdk.internal.module.ModuleHashes.HashSupplier;
 
 
 /**
@@ -54,12 +54,33 @@
     private final URI location;
     private final Supplier<ModuleReader> readerSupplier;
 
+    // true if this is a reference to a patched module
+    private boolean patched;
+
     // the function that computes the hash of this module reference
     private final HashSupplier hasher;
 
     // cached hash string to avoid needing to compute it many times
     private String cachedHash;
 
+
+    /**
+     * Constructs a new instance of this class.
+     */
+    ModuleReference(ModuleDescriptor descriptor,
+                    URI location,
+                    Supplier<ModuleReader> readerSupplier,
+                    boolean patched,
+                    HashSupplier hasher)
+
+    {
+        this.descriptor = Objects.requireNonNull(descriptor);
+        this.location = location;
+        this.readerSupplier = Objects.requireNonNull(readerSupplier);
+        this.patched = patched;
+        this.hasher = hasher;
+    }
+
     /**
      * Constructs a new instance of this class.
      */
@@ -67,11 +88,9 @@
                     URI location,
                     Supplier<ModuleReader> readerSupplier,
                     HashSupplier hasher)
+
     {
-        this.descriptor = Objects.requireNonNull(descriptor);
-        this.location = location;
-        this.readerSupplier = Objects.requireNonNull(readerSupplier);
-        this.hasher = hasher;
+        this(descriptor, location, readerSupplier, false, hasher);
     }
 
 
@@ -96,10 +115,9 @@
                            URI location,
                            Supplier<ModuleReader> readerSupplier)
     {
-        this(descriptor, location, readerSupplier, null);
+        this(descriptor, location, readerSupplier, false, null);
     }
 
-
     /**
      * Returns the module descriptor.
      *
@@ -151,6 +169,20 @@
 
 
     /**
+     * Returns {@code true} if this module has been patched via -Xpatch.
+     */
+    boolean isPatched() {
+        return patched;
+    }
+
+    /**
+     * Returns the hash supplier for this module.
+     */
+    HashSupplier hasher() {
+        return hasher;
+    }
+
+    /**
      * Computes the hash of this module, returning it as a hex string.
      * Returns {@code null} if the hash cannot be computed.
      *
@@ -166,8 +198,6 @@
         return result;
     }
 
-    private int hash;
-
     /**
      * Computes a hash code for this module reference.
      *
@@ -181,12 +211,17 @@
     public int hashCode() {
         int hc = hash;
         if (hc == 0) {
-            hc = Objects.hash(descriptor, location, readerSupplier, hasher);
-            if (hc != 0) hash = hc;
+            hc = Objects.hash(descriptor, location, readerSupplier, hasher,
+                    Boolean.valueOf(patched));
+            if (hc == 0)
+                hc = -1;
+            hash = hc;
         }
         return hc;
     }
 
+    private int hash;
+
     /**
      * Tests this module reference for equality with the given object.
      *
@@ -214,7 +249,8 @@
         return Objects.equals(this.descriptor, that.descriptor)
                 && Objects.equals(this.location, that.location)
                 && Objects.equals(this.readerSupplier, that.readerSupplier)
-                && Objects.equals(this.hasher, that.hasher);
+                && Objects.equals(this.hasher, that.hasher)
+                && this.patched == that.patched;
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/module/ModuleReferences.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/ModuleReferences.java	Thu May 05 19:11:09 2016 +0000
@@ -48,8 +48,8 @@
 
 import jdk.internal.misc.JavaLangAccess;
 import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.Hasher;
-import jdk.internal.module.Hasher.HashSupplier;
+import jdk.internal.module.ModuleHashes;
+import jdk.internal.module.ModuleHashes.HashSupplier;
 import jdk.internal.module.ModulePatcher;
 import sun.net.www.ParseUtil;
 
@@ -89,7 +89,7 @@
     static ModuleReference newJarModule(ModuleDescriptor md, Path file) {
         URI uri = file.toUri();
         Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
-        HashSupplier hasher = (algorithm) -> Hasher.generate(file, algorithm);
+        HashSupplier hasher = (a) -> ModuleHashes.computeHashAsString(file, a);
         return newModule(md, uri, supplier, hasher);
     }
 
@@ -99,7 +99,7 @@
     static ModuleReference newJModModule(ModuleDescriptor md, Path file) {
         URI uri = file.toUri();
         Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
-        HashSupplier hasher = (algorithm) -> Hasher.generate(file, algorithm);
+        HashSupplier hasher = (a) -> ModuleHashes.computeHashAsString(file, a);
         return newModule(md, file.toUri(), supplier, hasher);
     }
 
@@ -122,7 +122,7 @@
         private final ReadWriteLock lock = new ReentrantReadWriteLock();
         private final Lock readLock = lock.readLock();
         private final Lock writeLock = lock.writeLock();
-        private volatile boolean closed;
+        private boolean closed;
 
         SafeCloseModuleReader() { }
 
@@ -198,7 +198,10 @@
 
         static JarFile newJarFile(Path path) {
             try {
-                return new JarFile(path.toFile());
+                return new JarFile(path.toFile(),
+                                   true,               // verify
+                                   ZipFile.OPEN_READ,
+                                   JarFile.Release.RUNTIME);
             } catch (IOException ioe) {
                 throw new UncheckedIOException(ioe);
             }
@@ -219,6 +222,8 @@
             if (je != null) {
                 String encodedPath = ParseUtil.encodePath(name, false);
                 String uris = "jar:" + uri + "!/" + encodedPath;
+                if (jf.isMultiRelease())
+                    uris += "#runtime";
                 return Optional.of(URI.create(uris));
             } else {
                 return Optional.empty();
--- a/src/java.base/share/classes/java/lang/module/Resolver.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/Resolver.java	Thu May 05 19:11:09 2016 +0000
@@ -25,8 +25,8 @@
 
 package java.lang.module;
 
+import java.io.PrintStream;
 import java.lang.module.ModuleDescriptor.Requires.Modifier;
-import java.lang.reflect.Layer;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -43,7 +43,7 @@
 import java.util.StringJoiner;
 import java.util.stream.Collectors;
 
-import jdk.internal.module.Hasher;
+import jdk.internal.module.ModuleHashes;
 
 /**
  * The resolver used by {@link Configuration#resolveRequires} and
@@ -55,6 +55,7 @@
     private final ModuleFinder beforeFinder;
     private final Configuration parent;
     private final ModuleFinder afterFinder;
+    private final PrintStream traceOutput;
 
     // maps module name to module reference
     private final Map<String, ModuleReference> nameToReference = new HashMap<>();
@@ -62,10 +63,12 @@
 
     Resolver(ModuleFinder beforeFinder,
              Configuration parent,
-             ModuleFinder afterFinder) {
+             ModuleFinder afterFinder,
+             PrintStream traceOutput) {
         this.beforeFinder = beforeFinder;
         this.parent = parent;
         this.afterFinder = afterFinder;
+        this.traceOutput = traceOutput;
     }
 
 
@@ -76,8 +79,6 @@
      */
     Resolver resolveRequires(Collection<String> roots) {
 
-        long start = trace_start("Resolve");
-
         // create the visit stack to get us started
         Deque<ModuleDescriptor> q = new ArrayDeque<>();
         for (String root : roots) {
@@ -95,10 +96,9 @@
                 }
             }
 
-            if (TRACE) {
+            if (isTracing()) {
                 trace("Root module %s located", root);
-                if (mref.location().isPresent())
-                    trace("  (%s)", mref.location().get());
+                mref.location().ifPresent(uri -> trace("  (%s)", uri));
             }
 
             assert mref.descriptor().name().equals(root);
@@ -108,13 +108,6 @@
 
         resolve(q);
 
-        if (TRACE) {
-            long duration = System.currentTimeMillis() - start;
-            Set<String> names = nameToReference.keySet();
-            trace("Resolver completed in %s ms", duration);
-            names.stream().sorted().forEach(name -> trace("  %s", name));
-        }
-
         return this;
     }
 
@@ -153,11 +146,10 @@
                     q.offer(mref.descriptor());
                     resolved.add(mref.descriptor());
 
-                    if (TRACE) {
+                    if (isTracing()) {
                         trace("Module %s located, required by %s",
                                 dn, descriptor.name());
-                        if (mref.location().isPresent())
-                            trace("  (%s)", mref.location().get());
+                        mref.location().ifPresent(uri -> trace("  (%s)", uri));
                     }
                 }
 
@@ -175,8 +167,6 @@
      */
     Resolver resolveUses() {
 
-        long start = trace_start("Bind");
-
         // Scan the finders for all available service provider modules. As
         // java.base uses services then then module finders will be scanned
         // anyway.
@@ -230,10 +220,10 @@
 
                                     String pn = provider.name();
                                     if (!nameToReference.containsKey(pn)) {
-
-                                        if (TRACE && mref.location().isPresent())
-                                            trace("  (%s)", mref.location().get());
-
+                                        if (isTracing()) {
+                                            mref.location()
+                                                .ifPresent(uri -> trace("  (%s)", uri));
+                                        }
                                         nameToReference.put(pn, mref);
                                         q.push(provider);
                                     }
@@ -248,14 +238,6 @@
 
         } while (!candidateConsumers.isEmpty());
 
-
-        if (TRACE) {
-            long duration = System.currentTimeMillis() - start;
-            Set<String> names = nameToReference.keySet();
-            trace("Bind completed in %s ms", duration);
-            names.stream().sorted().forEach(name -> trace("  %s", name));
-        }
-
         return this;
     }
 
@@ -264,23 +246,33 @@
      * Execute post-resolution checks and returns the module graph of resolved
      * modules as {@code Map}. The resolved modules will be in the given
      * configuration.
+     *
+     * @param check {@true} to execute the post resolution checks
      */
-    Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf) {
+    Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf,
+                                                    boolean check)
+    {
+        if (isTracing()) {
+            trace("Result:");
+            Set<String> names = nameToReference.keySet();
+            names.stream().sorted().forEach(name -> trace("  %s", name));
+        }
 
-        detectCycles();
-
-        checkPlatformConstraints();
-
-        checkHashes();
+        if (check) {
+            detectCycles();
+            checkPlatformConstraints();
+            checkHashes();
+        }
 
         Map<ResolvedModule, Set<ResolvedModule>> graph = makeGraph(cf);
 
-        checkExportSuppliers(graph);
+        if (check) {
+            checkExportSuppliers(graph);
+        }
 
         return graph;
     }
 
-
     /**
      * Checks the given module graph for cycles.
      *
@@ -420,52 +412,44 @@
 
     }
 
-
     /**
      * Checks the hashes in the module descriptor to ensure that they match
-     * the hash of the dependency's module reference.
+     * any recorded hashes.
      */
     private void checkHashes() {
-
         for (ModuleReference mref : nameToReference.values()) {
             ModuleDescriptor descriptor = mref.descriptor();
 
-            // get map of module names to hash
-            Optional<Hasher.DependencyHashes> ohashes = descriptor.hashes();
+            // get map of module hashes
+            Optional<ModuleHashes> ohashes = descriptor.hashes();
             if (!ohashes.isPresent())
                 continue;
-            Hasher.DependencyHashes hashes = ohashes.get();
+            ModuleHashes hashes = ohashes.get();
 
-            // check dependences
-            for (ModuleDescriptor.Requires d : descriptor.requires()) {
-                String dn = d.name();
-                String recordedHash = hashes.hashFor(dn);
+            String algorithm = hashes.algorithm();
+            for (String dn : hashes.names()) {
+                ModuleReference other = nameToReference.get(dn);
+                if (other == null) {
+                    other = parent.findModule(dn)
+                            .map(ResolvedModule::reference)
+                            .orElse(null);
+                }
 
-                if (recordedHash != null) {
-
-                    ModuleReference other = nameToReference.get(dn);
-                    if (other == null) {
-                        other = parent.findModule(dn)
-                                .map(ResolvedModule::reference)
-                                .orElse(null);
-                    }
-                    if (other == null)
-                        throw new InternalError(dn + " not found");
-
-                    String actualHash = other.computeHash(hashes.algorithm());
+                // skip checking the hash if the module has been patched
+                if (other != null && !other.isPatched()) {
+                    String recordedHash = hashes.hashFor(dn);
+                    String actualHash = other.computeHash(algorithm);
                     if (actualHash == null)
                         fail("Unable to compute the hash of module %s", dn);
+                    if (!recordedHash.equals(actualHash)) {
+                        fail("Hash of %s (%s) differs to expected hash (%s)" +
+                             " recorded in %s", dn, actualHash, recordedHash,
+                             descriptor.name());
+                    }
+                }
+            }
 
-                    if (!recordedHash.equals(actualHash)) {
-                        fail("Hash of %s (%s) differs to expected hash (%s)",
-                                dn, actualHash, recordedHash);
-                    }
-
-                }
-
-            }
         }
-
     }
 
 
@@ -666,7 +650,7 @@
                     // source is exported to descriptor2
                     String source = export.source();
                     ModuleDescriptor other
-                            = packageToExporter.put(source, descriptor2);
+                        = packageToExporter.put(source, descriptor2);
 
                     if (other != null && other != descriptor2) {
                         // package might be local to descriptor1
@@ -690,33 +674,38 @@
                 }
             }
 
-            // uses S
-            for (String service : descriptor1.uses()) {
-                String pn = packageName(service);
-                if (!packageToExporter.containsKey(pn)) {
-                    fail("Module %s does not read a module that exports %s",
-                            descriptor1.name(), pn);
-                }
-            }
+            // uses/provides checks not applicable to automatic modules
+            if (!descriptor1.isAutomatic()) {
 
-            // provides S
-            for (Map.Entry<String, ModuleDescriptor.Provides> entry :
-                    descriptor1.provides().entrySet()) {
-                String service = entry.getKey();
-                ModuleDescriptor.Provides provides = entry.getValue();
-
-                String pn = packageName(service);
-                if (!packageToExporter.containsKey(pn)) {
-                    fail("Module %s does not read a module that exports %s",
-                            descriptor1.name(), pn);
+                // uses S
+                for (String service : descriptor1.uses()) {
+                    String pn = packageName(service);
+                    if (!packageToExporter.containsKey(pn)) {
+                        fail("Module %s does not read a module that exports %s",
+                             descriptor1.name(), pn);
+                    }
                 }
 
-                for (String provider : provides.providers()) {
-                    if (!packages.contains(packageName(provider))) {
-                        fail("Provider %s not in module %s",
-                                provider, descriptor1.name());
+                // provides S
+                for (Map.Entry<String, ModuleDescriptor.Provides> entry :
+                        descriptor1.provides().entrySet()) {
+                    String service = entry.getKey();
+                    ModuleDescriptor.Provides provides = entry.getValue();
+
+                    String pn = packageName(service);
+                    if (!packageToExporter.containsKey(pn)) {
+                        fail("Module %s does not read a module that exports %s",
+                             descriptor1.name(), pn);
+                    }
+
+                    for (String provider : provides.providers()) {
+                        if (!packages.contains(packageName(provider))) {
+                            fail("Provider %s not in module %s",
+                                 provider, descriptor1.name());
+                        }
                     }
                 }
+
             }
 
         }
@@ -796,27 +785,18 @@
         throw new ResolutionException(msg);
     }
 
-
     /**
-     * Tracing support, limited to boot layer for now.
+     * Tracing support
      */
 
-    private final static boolean TRACE
-        = Boolean.getBoolean("jdk.launcher.traceResolver")
-            && (Layer.boot() == null);
-
-    private String op;
-
-    private long trace_start(String op) {
-        this.op = op;
-        return System.currentTimeMillis();
+    private boolean isTracing() {
+        return traceOutput != null;
     }
 
     private void trace(String fmt, Object ... args) {
-        if (TRACE) {
-            System.out.print("[" + op + "] ");
-            System.out.format(fmt, args);
-            System.out.println();
+        if (traceOutput != null) {
+            traceOutput.format("[Resolver] " + fmt, args);
+            traceOutput.println();
         }
     }
 
--- a/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Thu May 05 19:11:09 2016 +0000
@@ -44,6 +44,7 @@
 import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
 import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.module.ModuleHashes;
 import jdk.internal.module.SystemModules;
 import jdk.internal.module.ModulePatcher;
 import jdk.internal.perf.PerfCounter;
@@ -101,13 +102,16 @@
         for (int i = 0; i < n; i++) {
             String mn = moduleNames[i];
             ModuleDescriptor md;
+            String hash;
             if (fastLoad) {
                 md = descriptors[i];
+                hash = SystemModules.MODULES_TO_HASH[i];
             } else {
                 // fallback to read module-info.class
                 // if fast loading of ModuleDescriptors is disabled
                 ImageLocation location = imageReader.findLocation(mn, "module-info.class");
                 md = ModuleDescriptor.read(imageReader.getResourceBuffer(location));
+                hash = null;
             }
             if (!md.name().equals(mn))
                 throw new InternalError();
@@ -123,7 +127,8 @@
                 }
             };
 
-            ModuleReference mref = new ModuleReference(md, uri, readerSupplier);
+            ModuleReference mref =
+                new ModuleReference(md, uri, readerSupplier, hashSupplier(hash));
 
             // may need a reference to a patched module if -Xpatch specified
             mref = ModulePatcher.interposeIfNeeded(mref);
@@ -142,6 +147,18 @@
         initTime.addElapsedTimeFrom(t0);
     }
 
+    private static ModuleHashes.HashSupplier hashSupplier(String hash) {
+        if (hash == null)
+            return null;
+
+        return new ModuleHashes.HashSupplier() {
+            @Override
+            public String generate(String algorithm) {
+                return hash;
+            }
+        };
+    }
+
     SystemModuleFinder() { }
 
     @Override
--- a/src/java.base/share/classes/java/lang/reflect/Layer.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/reflect/Layer.java	Thu May 05 19:11:09 2016 +0000
@@ -27,6 +27,7 @@
 
 import java.lang.module.Configuration;
 import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.module.ResolvedModule;
 import java.util.Collections;
 import java.util.HashMap;
@@ -41,6 +42,8 @@
 import jdk.internal.loader.Loader;
 import jdk.internal.loader.LoaderPool;
 import jdk.internal.misc.SharedSecrets;
+import jdk.internal.module.ServicesCatalog;
+import jdk.internal.module.ServicesCatalog.ServiceProvider;
 import sun.security.util.SecurityConstants;
 
 
@@ -549,4 +552,55 @@
     public static Layer boot() {
         return SharedSecrets.getJavaLangAccess().getBootLayer();
     }
+
+
+    /**
+     * Returns the ServicesCatalog for this Layer, creating it if not
+     * already created.
+     */
+    ServicesCatalog getServicesCatalog() {
+        ServicesCatalog servicesCatalog = this.servicesCatalog;
+        if (servicesCatalog != null)
+            return servicesCatalog;
+
+        Map<String, Set<ServiceProvider>> map = new HashMap<>();
+        for (Module m : nameToModule.values()) {
+            ModuleDescriptor descriptor = m.getDescriptor();
+            for (Provides provides : descriptor.provides().values()) {
+                String service = provides.service();
+                Set<ServiceProvider> providers
+                    = map.computeIfAbsent(service, k -> new HashSet<>());
+                for (String pn : provides.providers()) {
+                    providers.add(new ServiceProvider(m, pn));
+                }
+            }
+        }
+
+        ServicesCatalog catalog = new ServicesCatalog() {
+            @Override
+            public void register(Module module) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public Set<ServiceProvider> findServices(String service) {
+                Set<ServiceProvider> providers = map.get(service);
+                if (providers == null) {
+                    return Collections.emptySet();
+                } else {
+                    return Collections.unmodifiableSet(providers);
+                }
+            }
+        };
+
+        synchronized (this) {
+            servicesCatalog = this.servicesCatalog;
+            if (servicesCatalog == null) {
+                this.servicesCatalog = servicesCatalog = catalog;
+            }
+        }
+
+        return servicesCatalog;
+    }
+
+    private volatile ServicesCatalog servicesCatalog;
 }
--- a/src/java.base/share/classes/java/lang/reflect/Module.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/reflect/Module.java	Thu May 05 19:11:09 2016 +0000
@@ -43,11 +43,7 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.function.Function;
 import java.util.stream.Stream;
 
@@ -142,9 +138,6 @@
         this.name = null;
         this.loader = loader;
         this.descriptor = null;
-
-        // unnamed modules are loose
-        this.loose = true;
     }
 
 
@@ -245,17 +238,27 @@
     }
 
 
+    // --
+
+    // the special Module to mean reads or exported to "all unnamed modules"
+    private static final Module ALL_UNNAMED_MODULE = new Module(null);
+
+    // special Module to mean exported to "everyone"
+    private static final Module EVERYONE_MODULE = new Module(null);
+
+    // exported to all modules
+    private static final Set<Module> EVERYONE = Collections.singleton(EVERYONE_MODULE);
+
+
     // -- readability --
 
-    // true if this module reads all unnamed modules (a.k.a. loose module)
-    private volatile boolean loose;
-
     // the modules that this module permanently reads
     // (will be final when the modules are defined in reverse topology order)
     private volatile Set<Module> reads;
 
-    // created lazily, additional modules that this module reflectively reads
-    private volatile WeakSet<Module> transientReads;
+    // additional module (2nd key) that some module (1st key) reflectively reads
+    private static final WeakPairMap<Module, Module, Boolean> transientReads
+        = new WeakPairMap<>();
 
 
     /**
@@ -284,22 +287,19 @@
 
         // check if this module reads other
         if (other.isNamed()) {
-
             Set<Module> reads = this.reads; // volatile read
             if (reads != null && reads.contains(other))
                 return true;
-
-        } else {
-
-            // loose modules read all unnamed modules
-            if (this.loose)
-                return true;
-
         }
 
         // check if this module reads the other module reflectively
-        WeakSet<Module> tr = this.transientReads; // volatile read
-        if (tr != null && tr.contains(other))
+        if (transientReads.containsKeyPair(this, other))
+            return true;
+
+        // if other is an unnamed module then check if this module reads
+        // all unnamed modules
+        if (!other.isNamed()
+            && transientReads.containsKeyPair(this, ALL_UNNAMED_MODULE))
             return true;
 
         return false;
@@ -346,8 +346,7 @@
     }
 
     /**
-     * Makes the given {@code Module} readable to this module without
-     * notifying the VM.
+     * Updates this module to read another module without notifying the VM.
      *
      * @apiNote This method is for VM white-box testing.
      */
@@ -361,40 +360,28 @@
      * If {@code syncVM} is {@code true} then the VM is notified.
      */
     private void implAddReads(Module other, boolean syncVM) {
+        Objects.requireNonNull(other);
 
         // nothing to do
         if (other == this || !this.isNamed())
             return;
 
-        // if the other is null then change this module to be loose.
-        if (other == null) {
-            if (syncVM)
-                addReads0(this, null);
-            this.loose = true;
-            return;
-        }
-
         // check if we already read this module
         Set<Module> reads = this.reads;
         if (reads != null && reads.contains(other))
             return;
 
         // update VM first, just in case it fails
-        if (syncVM)
-            addReads0(this, other);
+        if (syncVM) {
+            if (other == ALL_UNNAMED_MODULE) {
+                addReads0(this, null);
+            } else {
+                addReads0(this, other);
+            }
+        }
 
         // add reflective read
-        WeakSet<Module> tr = this.transientReads;
-        if (tr == null) {
-            synchronized (this) {
-                tr = this.transientReads;
-                if (tr == null) {
-                    tr = new WeakSet<>();
-                    this.transientReads = tr;
-                }
-            }
-        }
-        tr.add(other);
+        transientReads.putIfAbsent(this, other, Boolean.TRUE);
     }
 
 
@@ -404,15 +391,10 @@
     // (will be final when the modules are defined in reverse topology order)
     private volatile Map<String, Set<Module>> exports;
 
-    // created lazily, additional exports added at run-time
-    private volatile Map<String, WeakSet<Module>> transientExports;
-
-    // the special Module to mean exported to all modules
-    private static final Module EVERYONE_MODULE = new Module(null);
-    private static final Set<Module> EVERYONE = Collections.singleton(EVERYONE_MODULE);
-
-    // the special Module to mean exported to all unnamed modules
-    private static final Module ALL_UNNAMED_MODULE = new Module(null);
+    // additional exports added at run-time
+    // this module (1st key), other module (2nd key), exported packages (value)
+    private static final WeakPairMap<Module, Module, Map<String, Boolean>>
+        transientExports = new WeakPairMap<>();
 
 
     /**
@@ -489,23 +471,9 @@
         if (exports != null) {
             Set<Module> targets = exports.get(pn);
 
-            if (targets != null) {
-
-                // exported to all modules
-                if (targets.contains(EVERYONE_MODULE))
-                    return true;
-
-                if (other != EVERYONE_MODULE) {
-                    // exported to other
-                    if (targets.contains(other))
-                        return true;
-
-                    // other is an unnamed module && exported to all unnamed
-                    if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
-                        return true;
-                }
-
-            }
+            if ((targets != null)
+                && (targets.contains(other) || targets.contains(EVERYONE_MODULE)))
+                return true;
         }
         return false;
     }
@@ -515,29 +483,27 @@
      * package package to the given module.
      */
     private boolean isExportedReflectively(String pn, Module other) {
-        Map<String, WeakSet<Module>> te = this.transientExports;
-        if (te != null) {
-            WeakSet<Module> targets = te.get(pn);
+        // exported to all modules
+        Map<String, ?> exports = transientExports.get(this, EVERYONE_MODULE);
+        if (exports != null && exports.containsKey(pn))
+            return true;
 
-            if (targets != null) {
+        if (other != EVERYONE_MODULE) {
 
-                // exported to all modules
-                if (targets.contains(EVERYONE_MODULE))
+            // exported to other
+            exports = transientExports.get(this, other);
+            if (exports != null && exports.containsKey(pn))
+                return true;
+
+            // other is an unnamed module && exported to all unnamed
+            if (!other.isNamed()) {
+                exports = transientExports.get(this, ALL_UNNAMED_MODULE);
+                if (exports != null && exports.containsKey(pn))
                     return true;
-
-                if (other != EVERYONE_MODULE) {
-
-                    // exported to other
-                    if (targets.contains(other))
-                        return true;
-
-                    // other is an unnamed module && exported to all unnamed
-                    if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
-                        return true;
-                }
             }
 
         }
+
         return false;
     }
 
@@ -638,34 +604,19 @@
             }
         }
 
-        // create transientExports if needed
-        Map<String, WeakSet<Module>> te = this.transientExports; // read
-        if (te == null) {
-            synchronized (this) {
-                te = this.transientExports;
-                if (te == null) {
-                    te = new ConcurrentHashMap<>();
-                    this.transientExports = te;  // volatile write
-                }
-            }
-        }
-
         // add package name to transientExports if absent
-        WeakSet<Module> s = te.get(pn);
-        if (s == null) {
-            s = new WeakSet<>();
-            WeakSet<Module> prev = te.putIfAbsent(pn, s);
-            if (prev != null)
-                s = prev;
-        }
-        s.add(other);
+        transientExports
+            .computeIfAbsent(this, other,
+                             (_this, _other) -> new ConcurrentHashMap<>())
+            .putIfAbsent(pn, Boolean.TRUE);
     }
 
 
     // -- services --
 
-    // created lazily, additional service types that this module uses
-    private volatile WeakSet<Class<?>> transientUses;
+    // additional service type (2nd key) that some module (1st key) uses
+    private static final WeakPairMap<Module, Class<?>, Boolean> transientUses
+        = new WeakPairMap<>();
 
     /**
      * If the caller's module is this module then update this module to add a
@@ -702,17 +653,7 @@
             }
 
             if (!canUse(st)) {
-                WeakSet<Class<?>> uses = this.transientUses;
-                if (uses == null) {
-                    synchronized (this) {
-                        uses = this.transientUses;
-                        if (uses == null) {
-                            uses = new WeakSet<>();
-                            this.transientUses = uses;
-                        }
-                    }
-                }
-                uses.add(st);
+                transientUses.putIfAbsent(this, st, Boolean.TRUE);
             }
 
         }
@@ -746,11 +687,7 @@
             return true;
 
         // uses added via addUses
-        WeakSet<Class<?>> uses = this.transientUses;
-        if (uses != null && uses.contains(st))
-            return true;
-
-        return false;
+        return transientUses.containsKeyPair(this, st);
     }
 
 
@@ -885,7 +822,7 @@
     // -- creating Module objects --
 
     /**
-     * Find the runtime Module corresponding to the given ReadDependence
+     * Find the runtime Module corresponding to the given ResolvedModule
      * in the given parent Layer (or its parents).
      */
     private static Module find(ResolvedModule resolvedModule, Layer layer) {
@@ -969,7 +906,7 @@
 
             // automatic modules reads all unnamed modules
             if (descriptor.isAutomatic()) {
-                m.implAddReads(null, true);
+                m.implAddReads(ALL_UNNAMED_MODULE, true);
             }
 
             // exports
@@ -1097,7 +1034,7 @@
      * the representation is the string {@code "module"}, followed by a space,
      * and then the module name. For an unnamed module, the representation is
      * the string {@code "unnamed module"}, followed by a space, and then an
-     * implementation specific identifier for the unnamed module.
+     * implementation specific string that identifies the unnamed module.
      *
      * @return The string representation of this module
      */
@@ -1112,46 +1049,6 @@
     }
 
 
-    // -- supporting classes --
-
-
-    /**
-     * A "not-a-Set" set of weakly referenced objects that supports concurrent
-     * access.
-     */
-    private static class WeakSet<E> {
-        private final ReadWriteLock lock = new ReentrantReadWriteLock();
-        private final Lock readLock = lock.readLock();
-        private final Lock writeLock = lock.writeLock();
-
-        private final WeakHashMap<E, Boolean> map = new WeakHashMap<>();
-
-        /**
-         * Adds the specified element to the set.
-         */
-        void add(E e) {
-            writeLock.lock();
-            try {
-                map.put(e, Boolean.TRUE);
-            } finally {
-                writeLock.unlock();
-            }
-        }
-
-        /**
-         * Returns {@code true} if this set contains the specified element.
-         */
-        boolean contains(E e) {
-            readLock.lock();
-            try {
-                return map.containsKey(e);
-            } finally {
-                readLock.unlock();
-            }
-        }
-    }
-
-
     // -- native methods --
 
     // JVM_DefineModule
@@ -1196,8 +1093,12 @@
                     m1.implAddReads(m2, true);
                 }
                 @Override
+                public void addReadsAllUnnamed(Module m) {
+                    m.implAddReads(Module.ALL_UNNAMED_MODULE);
+                }
+                @Override
                 public void addExports(Module m, String pn, Module other) {
-                    m.implAddExports(pn, Objects.requireNonNull(other), true);
+                    m.implAddExports(pn, other, true);
                 }
                 @Override
                 public void addExportsToAll(Module m, String pn) {
@@ -1211,6 +1112,10 @@
                 public void addPackage(Module m, String pn) {
                     m.implAddPackage(pn, true);
                 }
+                @Override
+                public ServicesCatalog getServicesCatalog(Layer layer) {
+                    return layer.getServicesCatalog();
+                }
             });
     }
 }
--- a/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu May 05 19:11:09 2016 +0000
@@ -582,7 +582,7 @@
         }
 
         private static final String DEBUG =
-                GetPropertyAction.getProperty("jdk.proxy.debug", "");
+                GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
 
         private static boolean isDebug() {
             return !DEBUG.isEmpty();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/reflect/WeakPairMap.java	Thu May 05 19:11:09 2016 +0000
@@ -0,0 +1,354 @@
+/*
+ * 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.  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 java.lang.reflect;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiFunction;
+
+/**
+ * A WeakHashMap-like data structure that uses a pair of weakly-referenced keys
+ * with identity equality semantics to associate a strongly-referenced value.
+ * Unlike WeakHashMap, this data structure is thread-safe.
+ *
+ * @param <K1> the type of 1st key in key pair
+ * @param <K2> the type of 2nd key in key pair
+ * @param <V>  the type of value
+ * @author Peter Levart
+ */
+final class WeakPairMap<K1, K2, V> {
+
+    private final ConcurrentHashMap<Pair<K1, K2>, V> map = new ConcurrentHashMap<>();
+    private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
+
+    /**
+     * Tests if the specified pair of keys are associated with a value
+     * in the WeakPairMap.
+     *
+     * @param k1 the 1st of the pair of keys
+     * @param k2 the 2nd of the pair of keys
+     * @return true if and only if the specified key pair is in this WeakPairMap,
+     * as determined by the identity comparison; false otherwise
+     * @throws NullPointerException if any of the specified keys is null
+     */
+    public boolean containsKeyPair(K1 k1, K2 k2) {
+        expungeStaleAssociations();
+        return map.containsKey(Pair.lookup(k1, k2));
+    }
+
+    /**
+     * Returns the value to which the specified pair of keys is mapped, or null
+     * if this WeakPairMap contains no mapping for the key pair.
+     * <p>More formally, if this WeakPairMap contains a mapping from a key pair
+     * {@code (_k1, _k2)} to a value {@code v} such that
+     * {@code k1 == _k1 && k2 == _k2}, then this method returns {@code v};
+     * otherwise it returns {@code null}.
+     * (There can be at most one such mapping.)
+     *
+     * @param k1 the 1st of the pair of keys for which the mapped value is to
+     *           be returned
+     * @param k2 the 2nd of the pair of keys for which the mapped value is to
+     *           be returned
+     * @return the value to which the specified key pair is mapped, or null if
+     * this map contains no mapping for the key pair
+     * @throws NullPointerException if any of the specified keys is null
+     */
+    public V get(K1 k1, K2 k2) {
+        expungeStaleAssociations();
+        return map.get(Pair.lookup(k1, k2));
+    }
+
+    /**
+     * Maps the specified key pair to the specified value in this WeakPairMap.
+     * Neither the keys nor the value can be null.
+     * <p>The value can be retrieved by calling the {@link #get} method
+     * with the the same keys (compared by identity).
+     *
+     * @param k1 the 1st of the pair of keys with which the specified value is to
+     *           be associated
+     * @param k2 the 2nd of the pair of keys with which the specified value is to
+     *           be associated
+     * @param v  value to be associated with the specified key pair
+     * @return the previous value associated with key pair, or {@code null} if
+     * there was no mapping for key pair
+     * @throws NullPointerException if any of the specified keys or value is null
+     */
+    public V put(K1 k1, K2 k2, V v) {
+        expungeStaleAssociations();
+        return map.put(Pair.weak(k1, k2, queue), v);
+    }
+
+    /**
+     * If the specified key pair is not already associated with a value,
+     * associates it with the given value and returns {@code null}, else does
+     * nothing and returns the currently associated value.
+     *
+     * @param k1 the 1st of the pair of keys with which the specified value is to
+     *           be associated
+     * @param k2 the 2nd of the pair of keys with which the specified value is to
+     *           be associated
+     * @param v  value to be associated with the specified key pair
+     * @return the previous value associated with key pair, or {@code null} if
+     * there was no mapping for key pair
+     * @throws NullPointerException if any of the specified keys or value is null
+     */
+    public V putIfAbsent(K1 k1, K2 k2, V v) {
+        expungeStaleAssociations();
+        return map.putIfAbsent(Pair.weak(k1, k2, queue), v);
+    }
+
+    /**
+     * If the specified key pair is not already associated with a value,
+     * attempts to compute its value using the given mapping function
+     * and enters it into this WeakPairMap unless {@code null}. The entire
+     * method invocation is performed atomically, so the function is
+     * applied at most once per key pair. Some attempted update operations
+     * on this WeakPairMap by other threads may be blocked while computation
+     * is in progress, so the computation should be short and simple,
+     * and must not attempt to update any other mappings of this WeakPairMap.
+     *
+     * @param k1              the 1st of the pair of keys with which the
+     *                        computed value is to be associated
+     * @param k2              the 2nd of the pair of keys with which the
+     *                        computed value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     * the specified key pair, or null if the computed value is null
+     * @throws NullPointerException  if any of the specified keys or
+     *                               mappingFunction is null
+     * @throws IllegalStateException if the computation detectably
+     *                               attempts a recursive update to this map
+     *                               that would otherwise never complete
+     * @throws RuntimeException      or Error if the mappingFunction does so, in
+     *                               which case the mapping is left unestablished
+     */
+    public V computeIfAbsent(K1 k1, K2 k2,
+                             BiFunction<? super K1, ? super K2, ? extends V>
+                                 mappingFunction) {
+        expungeStaleAssociations();
+        try {
+            return map.computeIfAbsent(
+                Pair.weak(k1, k2, queue),
+                pair -> mappingFunction.apply(pair.first(), pair.second()));
+        } finally {
+            Reference.reachabilityFence(k1);
+            Reference.reachabilityFence(k2);
+        }
+    }
+
+    /**
+     * Returns a {@link Collection} view of the values contained in this
+     * WeakPairMap. The collection is backed by the WeakPairMap, so changes to
+     * the map are reflected in the collection, and vice-versa.  The collection
+     * supports element removal, which removes the corresponding
+     * mapping from this map, via the {@code Iterator.remove},
+     * {@code Collection.remove}, {@code removeAll},
+     * {@code retainAll}, and {@code clear} operations.  It does not
+     * support the {@code add} or {@code addAll} operations.
+     *
+     * @return the collection view
+     */
+    public Collection<V> values() {
+        expungeStaleAssociations();
+        return map.values();
+    }
+
+    /**
+     * Removes associations from this WeakPairMap for which at least one of the
+     * keys in key pair has been found weakly-reachable and corresponding
+     * WeakRefPeer(s) enqueued. Called as part of each public operation.
+     */
+    private void expungeStaleAssociations() {
+        WeakRefPeer<?> peer;
+        while ((peer = (WeakRefPeer<?>) queue.poll()) != null) {
+            map.remove(peer.weakPair());
+        }
+    }
+
+    /**
+     * Common interface of both {@link Weak} and {@link Lookup} key pairs.
+     */
+    private interface Pair<K1, K2> {
+
+        static <K1, K2> Pair<K1, K2> weak(K1 k1, K2 k2,
+                                          ReferenceQueue<Object> queue) {
+            return new Weak<>(k1, k2, queue);
+        }
+
+        static <K1, K2> Pair<K1, K2> lookup(K1 k1, K2 k2) {
+            return new Lookup<>(k1, k2);
+        }
+
+        /**
+         * @return The 1st of the pair of keys (may be null for {@link Weak}
+         * when it gets cleared)
+         */
+        K1 first();
+
+        /**
+         * @return The 2nd of the pair of keys (may be null for {@link Weak}
+         * when it gets cleared)
+         */
+        K2 second();
+
+        static int hashCode(Object first, Object second) {
+            // assert first != null && second != null;
+            return System.identityHashCode(first) ^
+                   System.identityHashCode(second);
+        }
+
+        static boolean equals(Object first, Object second, Pair<?, ?> p) {
+            return first != null && second != null &&
+                   first == p.first() && second == p.second();
+        }
+
+        /**
+         * A Pair where both keys are weakly-referenced.
+         * It is composed of two instances of {@link WeakRefPeer}s:
+         * <pre>{@code
+         *
+         *     +-referent-> [K1]                +-referent-> [K2]
+         *     |                                |
+         *   +----------------+               +----------------+
+         *   | Pair.Weak <:   |-----peer----->| (anonymous) <: |
+         *   | WeakRefPeer,   |               | WeakRefPeer    |
+         *   | Pair           |<--weakPair()--|                |
+         *   +----------------+               +----------------+
+         *     |            ^
+         *     |            |
+         *     +-weakPair()-+
+         *
+         * }</pre>
+         * <p>
+         * Pair.Weak is used for CHM keys. Both peers are associated with the
+         * same {@link ReferenceQueue} so when either of their referents
+         * becomes weakly-reachable, the corresponding entries can be
+         * {@link #expungeStaleAssociations() expunged} from the map.
+         */
+        final class Weak<K1, K2> extends WeakRefPeer<K1> implements Pair<K1, K2> {
+
+            // saved hash so it can be retrieved after the reference is cleared
+            private final int hash;
+            // link to <K2> peer
+            private final WeakRefPeer<K2> peer;
+
+            Weak(K1 k1, K2 k2, ReferenceQueue<Object> queue) {
+                super(k1, queue);
+                hash = Pair.hashCode(k1, k2);
+                peer = new WeakRefPeer<>(k2, queue) {
+                    // link back to <K1> peer
+                    @Override
+                    Weak<?, ?> weakPair() { return Weak.this; }
+                };
+            }
+
+            @Override
+            Weak<?, ?> weakPair() {
+                return this;
+            }
+
+            @Override
+            public K1 first() {
+                return get();
+            }
+
+            @Override
+            public K2 second() {
+                return peer.get();
+            }
+
+            @Override
+            public int hashCode() {
+                return hash;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return this == obj ||
+                       (obj instanceof Pair &&
+                        Pair.equals(first(), second(), (Pair<?, ?>) obj));
+            }
+        }
+
+        /**
+         * Optimized lookup Pair, used as lookup key in methods like
+         * {@link java.util.Map#get(Object)} or
+         * {@link java.util.Map#containsKey(Object)}) where
+         * there is a great chance its allocation is eliminated
+         * by escape analysis when such lookups are inlined by JIT.
+         * All its methods are purposely designed so that 'this' is never
+         * passed to any other method or used as identity.
+         */
+        final class Lookup<K1, K2> implements Pair<K1, K2> {
+            private final K1 k1;
+            private final K2 k2;
+
+            Lookup(K1 k1, K2 k2) {
+                this.k1 = Objects.requireNonNull(k1);
+                this.k2 = Objects.requireNonNull(k2);
+            }
+
+            @Override
+            public K1 first() {
+                return k1;
+            }
+
+            @Override
+            public K2 second() {
+                return k2;
+            }
+
+            @Override
+            public int hashCode() {
+                return Pair.hashCode(k1, k2);
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return obj instanceof Pair &&
+                       Pair.equals(k1, k2, (Pair<?, ?>) obj);
+            }
+        }
+    }
+
+    /**
+     * Common abstract supertype of a pair of WeakReference peers.
+     */
+    private static abstract class WeakRefPeer<K> extends WeakReference<K> {
+
+        WeakRefPeer(K k, ReferenceQueue<Object> queue) {
+            super(Objects.requireNonNull(k), queue);
+        }
+
+        /**
+         * @return the {@link Pair.Weak} side of the pair of peers.
+         */
+        abstract Pair.Weak<?, ?> weakPair();
+    }
+}
--- a/src/java.base/share/classes/java/math/BigDecimal.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/math/BigDecimal.java	Thu May 05 19:11:09 2016 +0000
@@ -1536,7 +1536,7 @@
      * be performed to generate a result with the specified scale, the
      * specified rounding mode is applied.
      *
-     * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method
+     * @deprecated The method {@link #divide(BigDecimal, int, RoundingMode)}
      * should be used in preference to this legacy method.
      *
      * @param  divisor value by which this {@code BigDecimal} is to be divided.
@@ -1558,6 +1558,7 @@
      * @see    #ROUND_HALF_EVEN
      * @see    #ROUND_UNNECESSARY
      */
+    @Deprecated(since="9")
     public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
         if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
             throw new IllegalArgumentException("Invalid rounding mode");
@@ -1602,7 +1603,7 @@
      * rounding must be performed to generate a result with the given
      * scale, the specified rounding mode is applied.
      *
-     * <p>The new {@link #divide(BigDecimal, RoundingMode)} method
+     * @deprecated The method {@link #divide(BigDecimal, RoundingMode)}
      * should be used in preference to this legacy method.
      *
      * @param  divisor value by which this {@code BigDecimal} is to be divided.
@@ -1623,6 +1624,7 @@
      * @see    #ROUND_HALF_EVEN
      * @see    #ROUND_UNNECESSARY
      */
+    @Deprecated(since="9")
     public BigDecimal divide(BigDecimal divisor, int roundingMode) {
         return this.divide(divisor, scale, roundingMode);
     }
@@ -2267,14 +2269,20 @@
      * Rounding mode to round away from zero.  Always increments the
      * digit prior to a nonzero discarded fraction.  Note that this rounding
      * mode never decreases the magnitude of the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#UP} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_UP =           0;
 
     /**
      * Rounding mode to round towards zero.  Never increments the digit
      * prior to a discarded fraction (i.e., truncates).  Note that this
      * rounding mode never increases the magnitude of the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#DOWN} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_DOWN =         1;
 
     /**
@@ -2283,7 +2291,10 @@
      * {@code ROUND_UP}; if negative, behaves as for
      * {@code ROUND_DOWN}.  Note that this rounding mode never
      * decreases the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#CEILING} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_CEILING =      2;
 
     /**
@@ -2292,7 +2303,10 @@
      * {@code ROUND_DOWN}; if negative, behave as for
      * {@code ROUND_UP}.  Note that this rounding mode never
      * increases the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#FLOOR} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_FLOOR =        3;
 
     /**
@@ -2302,7 +2316,10 @@
      * &ge; 0.5; otherwise, behaves as for {@code ROUND_DOWN}.  Note
      * that this is the rounding mode that most of us were taught in
      * grade school.
+     *
+     * @deprecated Use {@link RoundingMode#HALF_UP} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_HALF_UP =      4;
 
     /**
@@ -2311,7 +2328,10 @@
      * down.  Behaves as for {@code ROUND_UP} if the discarded
      * fraction is {@literal >} 0.5; otherwise, behaves as for
      * {@code ROUND_DOWN}.
+     *
+     * @deprecated Use {@link RoundingMode#HALF_DOWN} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_HALF_DOWN =    5;
 
     /**
@@ -2323,7 +2343,10 @@
      * {@code ROUND_HALF_DOWN} if it's even.  Note that this is the
      * rounding mode that minimizes cumulative error when applied
      * repeatedly over a sequence of calculations.
+     *
+     * @deprecated Use {@link RoundingMode#HALF_EVEN} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_HALF_EVEN =    6;
 
     /**
@@ -2331,7 +2354,10 @@
      * result, hence no rounding is necessary.  If this rounding mode is
      * specified on an operation that yields an inexact result, an
      * {@code ArithmeticException} is thrown.
+     *
+     * @deprecated Use {@link RoundingMode#UNNECESSARY} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_UNNECESSARY =  7;
 
 
@@ -2408,7 +2434,7 @@
      * Instead, {@code setScale} returns an object with the proper
      * scale; the returned object may or may not be newly allocated.
      *
-     * <p>The new {@link #setScale(int, RoundingMode)} method should
+     * @deprecated The method {@link #setScale(int, RoundingMode)} should
      * be used in preference to this legacy method.
      *
      * @param  newScale scale of the {@code BigDecimal} value to be returned.
@@ -2431,6 +2457,7 @@
      * @see    #ROUND_HALF_EVEN
      * @see    #ROUND_UNNECESSARY
      */
+    @Deprecated(since="9")
     public BigDecimal setScale(int newScale, int roundingMode) {
         if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
             throw new IllegalArgumentException("Invalid rounding mode");
--- a/src/java.base/share/classes/java/math/RoundingMode.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/math/RoundingMode.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -90,6 +90,7 @@
  * @author  Joseph D. Darcy
  * @since 1.5
  */
+@SuppressWarnings("deprecation") // Legacy rounding mode constants in BigDecimal
 public enum RoundingMode {
 
         /**
--- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -52,7 +52,8 @@
     protected InetAddress connectedAddress = null;
     private int connectedPort = -1;
 
-    private static final String os = GetPropertyAction.getProperty("os.name");
+    private static final String os =
+            GetPropertyAction.privilegedGetProperty("os.name");
 
     /**
      * flag set if the native connect() call not to be used
--- a/src/java.base/share/classes/java/net/InetAddress.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/InetAddress.java	Thu May 05 19:11:09 2016 +0000
@@ -1124,7 +1124,7 @@
     private static NameService createNameService() {
 
         String hostsFileName =
-                GetPropertyAction.getProperty("jdk.net.hosts.file");
+                GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");
         NameService theNameService;
         if (hostsFileName != null) {
             theNameService = new HostsFileNameService(hostsFileName);
@@ -1643,9 +1643,11 @@
          * property can vary across implementations of the java.
          * classes.  The default is an empty String "".
          */
-        String prefix = GetPropertyAction.getProperty("impl.prefix", "");
+        String prefix = GetPropertyAction.privilegedGetProperty("impl.prefix", "");
         try {
-            impl = Class.forName("java.net." + prefix + implName).newInstance();
+            @SuppressWarnings("deprecation")
+            Object tmp = Class.forName("java.net." + prefix + implName).newInstance();
+            impl = tmp;
         } catch (ClassNotFoundException e) {
             System.err.println("Class not found: java.net." + prefix +
                                implName + ":\ncheck impl.prefix property " +
@@ -1662,7 +1664,9 @@
 
         if (impl == null) {
             try {
-                impl = Class.forName(implName).newInstance();
+                @SuppressWarnings("deprecation")
+                Object tmp = Class.forName(implName).newInstance();
+                impl = tmp;
             } catch (Exception e) {
                 throw new Error("System property impl.prefix incorrect");
             }
--- a/src/java.base/share/classes/java/net/ProxySelector.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/ProxySelector.java	Thu May 05 19:11:09 2016 +0000
@@ -71,7 +71,9 @@
         try {
             Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector");
             if (c != null && ProxySelector.class.isAssignableFrom(c)) {
-                theProxySelector = (ProxySelector) c.newInstance();
+                @SuppressWarnings("deprecation")
+                ProxySelector tmp = (ProxySelector) c.newInstance();
+                theProxySelector = tmp;
             }
         } catch (Exception e) {
             theProxySelector = null;
--- a/src/java.base/share/classes/java/net/SocksSocketImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -178,7 +178,7 @@
                 userName = pw.getUserName();
                 password = new String(pw.getPassword());
             } else {
-                userName = GetPropertyAction.getProperty("user.name");
+                userName = GetPropertyAction.privilegedGetProperty("user.name");
             }
             if (userName == null)
                 return false;
@@ -1088,7 +1088,7 @@
                 userName = System.getProperty("user.name");
             } catch (SecurityException se) { /* swallow Exception */ }
         } else {
-            userName = GetPropertyAction.getProperty("user.name");
+            userName = GetPropertyAction.privilegedGetProperty("user.name");
         }
         return userName;
     }
--- a/src/java.base/share/classes/java/net/URL.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/URL.java	Thu May 05 19:11:09 2016 +0000
@@ -1198,8 +1198,9 @@
         public URLStreamHandler createURLStreamHandler(String protocol) {
             String name = PREFIX + "." + protocol + ".Handler";
             try {
-                Class<?> c = Class.forName(name);
-                return (URLStreamHandler)c.newInstance();
+                @SuppressWarnings("deprecation")
+                Object o = Class.forName(name).newInstance();
+                return (URLStreamHandler)o;
             } catch (ClassNotFoundException x) {
                 // ignore
             } catch (Exception e) {
@@ -1212,7 +1213,7 @@
 
     private static URLStreamHandler lookupViaProperty(String protocol) {
         String packagePrefixList =
-                GetPropertyAction.getProperty(protocolPathProp);
+                GetPropertyAction.privilegedGetProperty(protocolPathProp);
         if (packagePrefixList == null) {
             // not set
             return null;
@@ -1234,7 +1235,9 @@
                     }
                 }
                 if (cls != null) {
-                    handler = (URLStreamHandler)cls.newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object tmp = cls.newInstance();
+                    handler = (URLStreamHandler)tmp;
                 }
             } catch (Exception e) {
                 // any number of exceptions can get thrown here
--- a/src/java.base/share/classes/java/net/URLConnection.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/URLConnection.java	Thu May 05 19:11:09 2016 +0000
@@ -1323,7 +1323,9 @@
                     }
                 }
                 if (cls != null) {
-                    return (ContentHandler) cls.newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object tmp = cls.newInstance();
+                    return (ContentHandler) tmp;
                 }
             } catch(Exception ignored) { }
         }
@@ -1397,7 +1399,7 @@
      */
     private String getContentHandlerPkgPrefixes() {
         String packagePrefixList =
-                GetPropertyAction.getProperty(contentPathProp, "");
+                GetPropertyAction.privilegedGetProperty(contentPathProp, "");
 
         if (packagePrefixList != "") {
             packagePrefixList += "|";
--- a/src/java.base/share/classes/java/net/URLEncoder.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/net/URLEncoder.java	Thu May 05 19:11:09 2016 +0000
@@ -133,7 +133,7 @@
         dontNeedEncoding.set('.');
         dontNeedEncoding.set('*');
 
-        dfltEncName = GetPropertyAction.getProperty("file.encoding");
+        dfltEncName = GetPropertyAction.privilegedGetProperty("file.encoding");
     }
 
     /**
--- a/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -94,9 +94,10 @@
             if (cn == null)
                 return null;
             try {
-                Class<?> c = Class.forName(cn, true,
-                                           ClassLoader.getSystemClassLoader());
-                return (AsynchronousChannelProvider)c.newInstance();
+                @SuppressWarnings("deprecation")
+                Object tmp = Class.forName(cn, true,
+                                           ClassLoader.getSystemClassLoader()).newInstance();
+                return (AsynchronousChannelProvider)tmp;
             } catch (ClassNotFoundException x) {
                 throw new ServiceConfigurationError(null, x);
             } catch (IllegalAccessException x) {
--- a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -95,9 +95,10 @@
         if (cn == null)
             return false;
         try {
-            Class<?> c = Class.forName(cn, true,
-                                       ClassLoader.getSystemClassLoader());
-            provider = (SelectorProvider)c.newInstance();
+            @SuppressWarnings("deprecation")
+            Object tmp = Class.forName(cn, true,
+                                       ClassLoader.getSystemClassLoader()).newInstance();
+            provider = (SelectorProvider)tmp;
             return true;
         } catch (ClassNotFoundException x) {
             throw new ServiceConfigurationError(null, x);
--- a/src/java.base/share/classes/java/nio/charset/Charset.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/nio/charset/Charset.java	Thu May 05 19:11:09 2016 +0000
@@ -283,8 +283,8 @@
         if (level == null) {
             if (!VM.isBooted())
                 return false;
-            bugLevel = level =
-                    GetPropertyAction.getProperty("sun.nio.cs.bugLevel", "");
+            bugLevel = level = GetPropertyAction
+                    .privilegedGetProperty("sun.nio.cs.bugLevel", "");
         }
         return level.equals(bl);
     }
@@ -609,7 +609,8 @@
     public static Charset defaultCharset() {
         if (defaultCharset == null) {
             synchronized (Charset.class) {
-                String csn = GetPropertyAction.getProperty("file.encoding");
+                String csn = GetPropertyAction
+                        .privilegedGetProperty("file.encoding");
                 Charset cs = lookup(csn);
                 if (cs != null)
                     defaultCharset = cs;
--- a/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Thu May 05 19:11:09 2016 +0000
@@ -46,7 +46,7 @@
 
     // temporary directory location
     private static final Path tmpdir =
-        Paths.get(GetPropertyAction.getProperty("java.io.tmpdir"));
+        Paths.get(GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));
 
     private static final boolean isPosix =
         FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
--- a/src/java.base/share/classes/java/security/Policy.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/security/Policy.java	Thu May 05 19:11:09 2016 +0000
@@ -222,8 +222,9 @@
             public Policy run() {
                 try {
                     ClassLoader scl = ClassLoader.getSystemClassLoader();
-                    Class<?> c = Class.forName(policyProvider, true, scl);
-                    return (Policy)c.newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object o = Class.forName(policyProvider, true, scl).newInstance();
+                    return (Policy)o;
                 } catch (Exception e) {
                     if (debug != null) {
                         debug.println("policy provider " + policyProvider +
--- a/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -147,6 +147,7 @@
                 if (prop != null) {
                     try {
                         Class<?> c = Class.forName(prop, true, ClassLoader.getSystemClassLoader());
+                        @SuppressWarnings("deprecation")
                         ZoneRulesProvider provider = ZoneRulesProvider.class.cast(c.newInstance());
                         registerProvider(provider);
                         loaded.add(provider);
--- a/src/java.base/share/classes/java/util/Locale.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/Locale.java	Thu May 05 19:11:09 2016 +0000
@@ -858,7 +858,7 @@
 
     private static Locale initDefault() {
         String language, region, script, country, variant;
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         language = props.getProperty("user.language", "en");
         // for compatibility, check for old user.region property
         region = props.getProperty("user.region");
@@ -883,7 +883,7 @@
     }
 
     private static Locale initDefault(Locale.Category category) {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         return getInstance(
             props.getProperty(category.languageKey,
                     defaultLocale.getLanguage()),
--- a/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Thu May 05 19:11:09 2016 +0000
@@ -140,9 +140,8 @@
 
     // Check whether the strict encoding is specified.
     // The possible encoding is either "ISO-8859-1" or "UTF-8".
-    private static final String encoding =
-        GetPropertyAction
-                .getProperty("java.util.PropertyResourceBundle.encoding", "")
+    private static final String encoding = GetPropertyAction
+        .privilegedGetProperty("java.util.PropertyResourceBundle.encoding", "")
         .toUpperCase(Locale.ROOT);
 
     /**
--- a/src/java.base/share/classes/java/util/ServiceLoader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/ServiceLoader.java	Thu May 05 19:11:09 2016 +0000
@@ -29,8 +29,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Layer;
@@ -85,7 +83,7 @@
  * and deployed as a named module must have an appropriate <i>uses</i> clause
  * in its <i>module descriptor</i> to declare that the module uses
  * implementations of the service. A corresponding requirement is that a
- * provider deployed as a named modules must have an appropriate
+ * provider deployed as a named module must have an appropriate
  * <i>provides</i> clause in its module descriptor to declare that the module
  * provides an implementation of the service. The <i>uses</i> and
  * <i>provides</i> allow consumers of a service to be <i>linked</i> to
@@ -550,35 +548,29 @@
     /**
      * Implements lazy service provider lookup of service providers that
      * are provided by modules in a module Layer.
-     *
-     * For now, this iterator examines all modules in each Layer. This will
-     * be replaced once we decide on how the service-use graph is exposed
-     * in the module API.
      */
     private class LayerLookupIterator
         extends RestrictedIterator<S>
     {
         final String serviceName;
         Layer currentLayer;
-        Iterator<ModuleDescriptor> descriptorIterator;
-        Iterator<String> providersIterator;
-
-        Module nextModule;
-        String nextProvider;
+        Iterator<ServiceProvider> iterator;
+        ServiceProvider nextProvider;
 
         LayerLookupIterator() {
             serviceName = service.getName();
             currentLayer = layer;
 
             // need to get us started
-            descriptorIterator = descriptors(layer, serviceName);
+            iterator = providers(currentLayer, serviceName);
         }
 
-        Iterator<ModuleDescriptor> descriptors(Layer layer, String service) {
-            return layer.modules().stream()
-                    .map(Module::getDescriptor)
-                    .filter(d -> d.provides().get(service) != null)
-                    .iterator();
+        Iterator<ServiceProvider> providers(Layer layer, String service) {
+            ServicesCatalog catalog = SharedSecrets
+                    .getJavaLangReflectModuleAccess()
+                    .getServicesCatalog(layer);
+
+            return catalog.findServices(serviceName).iterator();
         }
 
         @Override
@@ -591,30 +583,18 @@
             while (true) {
 
                 // next provider
-                if (providersIterator != null && providersIterator.hasNext()) {
-                    nextProvider = providersIterator.next();
+                if (iterator != null && iterator.hasNext()) {
+                    nextProvider = iterator.next();
                     return true;
                 }
 
-                // next descriptor
-                if (descriptorIterator.hasNext()) {
-                    ModuleDescriptor descriptor = descriptorIterator.next();
-
-                    nextModule = currentLayer.findModule(descriptor.name()).get();
-
-                    Provides provides = descriptor.provides().get(serviceName);
-                    providersIterator = provides.providers().iterator();
-
-                    continue;
-                }
-
                 // next layer
                 Layer parent = currentLayer.parent().orElse(null);
                 if (parent == null)
                     return false;
 
                 currentLayer = parent;
-                descriptorIterator = descriptors(currentLayer, serviceName);
+                iterator = providers(currentLayer, serviceName);
             }
         }
 
@@ -623,13 +603,14 @@
             if (!hasNextService())
                 throw new NoSuchElementException();
 
-            assert nextModule != null && nextProvider != null;
-
-            String cn = nextProvider;
+            ServiceProvider provider = nextProvider;
             nextProvider = null;
 
+            Module module = provider.module();
+            String cn = provider.providerName();
+
             // attempt to load the provider
-            Class<?> c = loadClassInModule(nextModule, cn);
+            Class<?> c = loadClassInModule(module, cn);
             if (c == null)
                 fail(service, "Provider " + cn  + " not found");
             if (!service.isAssignableFrom(c))
@@ -830,7 +811,9 @@
             }
             S p = null;
             try {
-                p = service.cast(c.newInstance());
+                @SuppressWarnings("deprecation")
+                Object tmp = c.newInstance();
+                p = service.cast(tmp);
             } catch (Throwable x) {
                 fail(service,
                      "Provider " + cn + " could not be instantiated",
--- a/src/java.base/share/classes/java/util/TimeZone.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/TimeZone.java	Thu May 05 19:11:09 2016 +0000
@@ -42,6 +42,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.time.ZoneId;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 import sun.util.calendar.ZoneInfo;
 import sun.util.calendar.ZoneInfoFile;
@@ -660,12 +661,13 @@
     private static synchronized TimeZone setDefaultZone() {
         TimeZone tz;
         // get the time zone ID from the system properties
-        String zoneID = GetPropertyAction.getProperty("user.timezone");
+        Properties props = GetPropertyAction.privilegedGetProperties();
+        String zoneID = props.getProperty("user.timezone");
 
         // if the time zone ID is not set (yet), perform the
         // platform to Java time zone ID mapping.
         if (zoneID == null || zoneID.isEmpty()) {
-            String javaHome = GetPropertyAction.getProperty("java.home");
+            String javaHome = props.getProperty("java.home");
             try {
                 zoneID = getSystemTimeZoneID(javaHome);
                 if (zoneID == null) {
@@ -693,13 +695,7 @@
         assert tz != null;
 
         final String id = zoneID;
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-                public Void run() {
-                    System.setProperty("user.timezone", id);
-                    return null;
-                }
-            });
+        props.setProperty("user.timezone", id);
 
         defaultTimeZone = tz;
         return tz;
--- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Thu May 05 19:11:09 2016 +0000
@@ -3507,6 +3507,7 @@
      * Creates and returns the common pool, respecting user settings
      * specified via system properties.
      */
+    @SuppressWarnings("deprecation") // Class.newInstance
     static ForkJoinPool makeCommonPool() {
         int parallelism = -1;
         ForkJoinWorkerThreadFactory factory = null;
--- a/src/java.base/share/classes/java/util/jar/JarFile.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java	Thu May 05 19:11:09 2016 +0000
@@ -155,7 +155,7 @@
         BASE_VERSION = 8;  // one less than lowest version for versioned entries
         int runtimeVersion = jdk.Version.current().major();
         String jarVersion =
-                GetPropertyAction.getProperty("jdk.util.jar.version");
+                GetPropertyAction.privilegedGetProperty("jdk.util.jar.version");
         if (jarVersion != null) {
             int jarVer = Integer.parseInt(jarVersion);
             runtimeVersion = (jarVer > runtimeVersion)
@@ -163,7 +163,7 @@
         }
         RUNTIME_VERSION = runtimeVersion;
         String enableMultiRelease = GetPropertyAction
-                .getProperty("jdk.util.jar.enableMultiRelease", "true");
+                .privilegedGetProperty("jdk.util.jar.enableMultiRelease", "true");
         switch (enableMultiRelease) {
             case "true":
             default:
@@ -658,6 +658,28 @@
         return vze == null ? ze : vze;
     }
 
+    /**
+     * Returns the real name of a {@code JarEntry}.  If this {@code JarFile} is
+     * a multi-release jar file and is configured to be processed as such, the
+     * name returned by this method is the path name of the versioned entry
+     * that the {@code JarEntry} represents, rather than the path name of the
+     * base entry that {@link JarEntry#getName()} returns.  If the
+     * {@code JarEntry} does not represent a versioned entry, or the
+     * jar file is not a multi-release jar file or {@code JarFile} is not
+     * configured for processing a multi-release jar file, this method returns
+     * the same name that {@link JarEntry#getName()} returns.
+     *
+     * @param entry the JarEntry
+     * @return the real name of the JarEntry
+     * @since 9
+     */
+    String getRealName(JarEntry entry) {
+        if (entry instanceof JarFileEntry) {
+            return ((JarFileEntry)entry).realName();
+        }
+        return entry.getName();
+    }
+
     private class JarFileEntry extends JarEntry {
         final private String name;
 
@@ -684,7 +706,7 @@
                 throw new RuntimeException(e);
             }
             if (certs == null && jv != null) {
-                certs = jv.getCerts(JarFile.this, reifiedEntry());
+                certs = jv.getCerts(JarFile.this, realEntry());
             }
             return certs == null ? null : certs.clone();
         }
@@ -695,17 +717,20 @@
                 throw new RuntimeException(e);
             }
             if (signers == null && jv != null) {
-                signers = jv.getCodeSigners(JarFile.this, reifiedEntry());
+                signers = jv.getCodeSigners(JarFile.this, realEntry());
             }
             return signers == null ? null : signers.clone();
         }
-        JarFileEntry reifiedEntry() {
+        JarFileEntry realEntry() {
             if (isMultiRelease()) {
                 String entryName = super.getName();
                 return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
             }
             return this;
         }
+        String realName() {
+            return super.getName();
+        }
 
         @Override
         public String getName() {
@@ -876,11 +901,11 @@
     private JarEntry verifiableEntry(ZipEntry ze) {
         if (ze instanceof JarFileEntry) {
             // assure the name and entry match for verification
-            return ((JarFileEntry)ze).reifiedEntry();
+            return ((JarFileEntry)ze).realEntry();
         }
         ze = getJarEntry(ze.getName());
         if (ze instanceof JarFileEntry) {
-            return ((JarFileEntry)ze).reifiedEntry();
+            return ((JarFileEntry)ze).realEntry();
         }
         return (JarEntry)ze;
     }
--- a/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -60,4 +60,8 @@
     public List<Object> getManifestDigests(JarFile jar) {
         return jar.getManifestDigests();
     }
+
+    public String getRealName(JarFile jar, JarEntry entry) {
+        return jar.getRealName(entry);
+    }
 }
--- a/src/java.base/share/classes/java/util/jar/Pack200.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/jar/Pack200.java	Thu May 05 19:11:09 2016 +0000
@@ -695,7 +695,7 @@
             Class<?> impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
             if (impl == null) {
                 // The first time, we must decide which class to use.
-                implName = GetPropertyAction.getProperty(prop,"");
+                implName = GetPropertyAction.privilegedGetProperty(prop,"");
                 if (implName != null && !implName.equals(""))
                     impl = Class.forName(implName);
                 else if (PACK_PROVIDER.equals(prop))
@@ -704,7 +704,9 @@
                     impl = com.sun.java.util.jar.pack.UnpackerImpl.class;
             }
             // We have a class.  Now instantiate it.
-            return impl.newInstance();
+            @SuppressWarnings("deprecation")
+            Object result = impl.newInstance();
+            return result;
         } catch (ClassNotFoundException e) {
             throw new Error("Class not found: " + implName +
                                 ":\ncheck property " + prop +
--- a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Thu May 05 19:11:09 2016 +0000
@@ -94,7 +94,7 @@
     }
 
     private static final String nl =
-            GetPropertyAction.getProperty("line.separator");
+            GetPropertyAction.privilegedGetProperty("line.separator");
 
     /**
      * Returns a multi-line string containing the description of the syntax
--- a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Thu May 05 19:11:09 2016 +0000
@@ -55,7 +55,7 @@
      */
     private static final boolean inhibitZip64 =
         Boolean.parseBoolean(
-            GetPropertyAction.getProperty("jdk.util.zip.inhibitZip64"));
+            GetPropertyAction.privilegedGetProperty("jdk.util.zip.inhibitZip64"));
 
     private static class XEntry {
         final ZipEntry entry;
--- a/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -97,6 +97,7 @@
                         }
                     }
                     log("class " + clsName + " is loaded");
+                    @SuppressWarnings("deprecation")
                     SSLServerSocketFactory fac = (SSLServerSocketFactory)cls.newInstance();
                     log("instantiated an instance of class " + clsName);
                     theFactory = fac;
--- a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -51,7 +51,7 @@
     static final boolean DEBUG;
 
     static {
-        String s = GetPropertyAction.getProperty("javax.net.debug", "")
+        String s = GetPropertyAction.privilegedGetProperty("javax.net.debug", "")
                 .toLowerCase(Locale.ENGLISH);
 
         DEBUG = s.contains("all") || s.contains("ssl");
@@ -106,6 +106,7 @@
                         }
                     }
                     log("class " + clsName + " is loaded");
+                    @SuppressWarnings("deprecation")
                     SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance();
                     log("instantiated an instance of class " + clsName);
                     theFactory = fac;
--- a/src/java.base/share/classes/javax/security/auth/login/Configuration.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/javax/security/auth/login/Configuration.java	Thu May 05 19:11:09 2016 +0000
@@ -250,7 +250,9 @@
                                             finalClass, false,
                                             Thread.currentThread().getContextClassLoader()
                                     ).asSubclass(Configuration.class);
-                                    return implClass.newInstance();
+                                    @SuppressWarnings("deprecation")
+                                    Configuration result = implClass.newInstance();
+                                    return result;
                                 }
                             });
                     AccessController.doPrivileged(
--- a/src/java.base/share/classes/javax/security/auth/login/LoginContext.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/javax/security/auth/login/LoginContext.java	Thu May 05 19:11:09 2016 +0000
@@ -304,7 +304,9 @@
                     Class<? extends CallbackHandler> c = Class.forName(
                             defaultHandler, true,
                             finalLoader).asSubclass(CallbackHandler.class);
-                    return c.newInstance();
+                    @SuppressWarnings("deprecation")
+                    CallbackHandler result = c.newInstance();
+                    return result;
                 }
             });
         } catch (java.security.PrivilegedActionException pae) {
@@ -697,8 +699,9 @@
 
                     if (moduleStack[i].module == null) {
                         try {
-                            moduleStack[i].module = (LoginModule) Class.forName(
-                                    name, false, contextClassLoader).newInstance();
+                            @SuppressWarnings("deprecation")
+                            Object tmp = Class.forName(name, false, contextClassLoader).newInstance();
+                            moduleStack[i].module = (LoginModule) tmp;
                             if (debug != null) {
                                 debug.println(name + " loaded via reflection");
                             }
--- a/src/java.base/share/classes/jdk/Version.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/Version.java	Thu May 05 19:11:09 2016 +0000
@@ -273,7 +273,8 @@
      */
     public static Version current() {
         if (current == null) {
-            current = parse(GetPropertyAction.getProperty("java.version"));
+            current = parse(
+                    GetPropertyAction.privilegedGetProperty("java.version"));
         }
         return current;
     }
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -124,7 +124,9 @@
         ClassLoader cl = newJrtFsLoader(jrtfs);
         try {
             Class<?> c = Class.forName(JrtFileSystemProvider.class.getName(), false, cl);
-            return ((FileSystemProvider)c.newInstance()).newFileSystem(uri, newEnv);
+            @SuppressWarnings("deprecation")
+            Object tmp = c.newInstance();
+            return ((FileSystemProvider)tmp).newFileSystem(uri, newEnv);
         } catch (ClassNotFoundException |
                  IllegalAccessException |
                  InstantiationException e) {
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -68,7 +68,7 @@
     }
 
     // ServiceCatalog for the boot class loader
-    private static final ServicesCatalog SERVICES_CATALOG = new ServicesCatalog();
+    private static final ServicesCatalog SERVICES_CATALOG = ServicesCatalog.create();
 
     // ClassLoaderValue map for boot class loader
     private static final ConcurrentHashMap<?, ?> CLASS_LOADER_VALUE_MAP =
--- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Thu May 05 19:11:09 2016 +0000
@@ -104,7 +104,7 @@
      * A module defined/loaded by a built-in class loader.
      *
      * A LoadedModule encapsulates a ModuleReference along with its CodeSource
-     * URL to avoid needing to create this URL when define classes.
+     * URL to avoid needing to create this URL when defining classes.
      */
     private static class LoadedModule {
         private final BuiltinClassLoader loader;
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Thu May 05 19:11:09 2016 +0000
@@ -85,7 +85,7 @@
     private static final boolean DISABLE_JAR_CHECKING;
 
     static {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         JAVA_VERSION = props.getProperty("java.version");
         DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
         String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
@@ -372,9 +372,15 @@
             return java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedExceptionAction<>() {
                 public Loader run() throws IOException {
+                    String protocol = url.getProtocol();  // lower cased in URL
                     String file = url.getFile();
-                    if (file != null && file.endsWith("/")) {
-                        if ("file".equals(url.getProtocol())) {
+                    if ("jar".equals(protocol)
+                            && file != null && (file.indexOf("!/") == file.length() - 2)) {
+                        // extract the nested URL
+                        URL nestedUrl = new URL(file.substring(0, file.length() - 2));
+                        return new JarLoader(nestedUrl, jarHandler, lmap);
+                    } else if (file != null && file.endsWith("/")) {
+                        if ("file".equals(protocol)) {
                             return new FileLoader(url);
                         } else {
                             return new Loader(url);
@@ -718,13 +724,13 @@
 
             final URL url;
             try {
+                String nm;
                 if (jar.isMultiRelease()) {
-                    // add #runtime fragment to tell JarURLConnection to use
-                    // runtime versioning if the underlying jar file is multi-release
-                    url = new URL(getBaseURL(), ParseUtil.encodePath(name, false) + "#runtime");
+                    nm = SharedSecrets.javaUtilJarAccess().getRealName(jar, entry);
                 } else {
-                    url = new URL(getBaseURL(), ParseUtil.encodePath(name, false));
+                    nm = name;
                 }
+                url = new URL(getBaseURL(), ParseUtil.encodePath(nm, false));
                 if (check) {
                     URLClassPath.check(url);
                 }
@@ -940,7 +946,8 @@
 
             ensureOpen();
 
-            if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
+            // Only get manifest when necessary
+            if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) {
                 Manifest man = jar.getManifest();
                 if (man != null) {
                     Attributes attr = man.getMainAttributes();
--- a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Thu May 05 19:11:09 2016 +0000
@@ -81,7 +81,7 @@
     // Get configuration error policy
     private static ErrorPolicy configurationErrorPolicy() {
         String errorPolicy =
-                GetPropertyAction.getProperty("jdk.logger.finder.error");
+                GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error");
         if (errorPolicy == null || errorPolicy.isEmpty()) {
             return ErrorPolicy.WARNING;
         }
@@ -96,7 +96,7 @@
     // This is further submitted to the configuration error policy.
     private static boolean ensureSingletonProvider() {
         return Boolean.parseBoolean(
-                GetPropertyAction.getProperty("jdk.logger.finder.singleton"));
+                GetPropertyAction.privilegedGetProperty("jdk.logger.finder.singleton"));
     }
 
     private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
--- a/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Thu May 05 19:11:09 2016 +0000
@@ -56,7 +56,7 @@
 
     static Level getDefaultLevel() {
         String levelName = GetPropertyAction
-                .getProperty("jdk.system.logger.level", "INFO");
+                .privilegedGetProperty("jdk.system.logger.level", "INFO");
         try {
             return Level.valueOf(levelName);
         } catch (IllegalArgumentException iae) {
@@ -426,7 +426,7 @@
         static private final String[] skips;
         static {
             String additionalPkgs =
-                    GetPropertyAction.getProperty("jdk.logger.packages");
+                    GetPropertyAction.privilegedGetProperty("jdk.logger.packages");
             skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(",");
         }
 
@@ -485,7 +485,7 @@
             //    jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java
             // to fail - because that test has a testcase which somehow references
             // PlatformLogger and counts the number of generated lambda classes.
-            String format = GetPropertyAction.getProperty(key);
+            String format = GetPropertyAction.privilegedGetProperty(key);
 
             if (format == null && defaultPropertyGetter != null) {
                 format = defaultPropertyGetter.apply(key);
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,13 +25,24 @@
 
 package jdk.internal.misc;
 
+import java.io.PrintStream;
+import java.lang.module.Configuration;
+import jdk.internal.module.ModuleHashes;
+
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleDescriptor.Exports;
 import java.lang.module.ModuleDescriptor.Requires;
 import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.module.ModuleDescriptor.Version;
+import java.lang.module.ModuleFinder;
+import java.util.Collection;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.net.URI;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.function.Supplier;
 
 /**
  * Provides access to non-public methods in java.lang.module.
@@ -89,5 +100,29 @@
                                          String osArch,
                                          String osVersion,
                                          Set<String> conceals,
-                                         Set<String> packages);
+                                         Set<String> packages,
+                                         ModuleHashes hashes);
+
+    /**
+     * Resolves a collection of root modules, with service binding
+     * and the empty configuration as the parent. The post resolution
+     * checks are optionally run.
+     */
+    Configuration resolveRequiresAndUses(ModuleFinder finder,
+                                         Collection<String> roots,
+                                         boolean check,
+                                         PrintStream traceOutput);
+
+    /**
+     * Creates a ModuleReference to a "patched" module.
+     */
+    ModuleReference newPatchedModule(ModuleDescriptor descriptor,
+                                     URI location,
+                                     Supplier<ModuleReader> readerSupplier);
+
+    /**
+     * Returns the object with the hashes of other modules
+     */
+    Optional<ModuleHashes> hashes(ModuleDescriptor descriptor);
+
 }
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -26,9 +26,12 @@
 package jdk.internal.misc;
 
 import java.lang.module.ModuleDescriptor;
+import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
 import java.net.URI;
 
+import jdk.internal.module.ServicesCatalog;
+
 /**
  * Provides access to non-public methods in java.lang.reflect.Module
  */
@@ -57,6 +60,11 @@
     void addReads(Module m1, Module m2);
 
     /**
+     * Updates module m to read all unnamed modules.
+     */
+    void addReadsAllUnnamed(Module m);
+
+    /**
      * Updates module m1 to export a package to module m2. The export does
      * not result in a strong reference to m2 (m2 can be GC'ed).
      */
@@ -76,4 +84,10 @@
      * Add a package to the given module.
      */
     void addPackage(Module m, String pkg);
-}
+
+    /**
+     * Returns the ServicesCatalog for the given Layer.
+     */
+    ServicesCatalog getServicesCatalog(Layer layer);
+
+}
\ No newline at end of file
--- a/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java	Thu May 05 19:11:09 2016 +0000
@@ -41,4 +41,5 @@
     public Enumeration<JarEntry> entries2(JarFile jar);
     public void setEagerValidation(JarFile jar, boolean eager);
     public List<Object> getManifestDigests(JarFile jar);
+    public String getRealName(JarFile jar, JarEntry entry);
 }
--- a/src/java.base/share/classes/jdk/internal/module/Builder.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/Builder.java	Thu May 05 19:11:09 2016 +0000
@@ -74,6 +74,8 @@
     String osName;
     String osArch;
     String osVersion;
+    String algorithm;
+    Map<String, String> hashes;
 
     Builder(String name, int reqs, int exports,
             int provides, int conceals, int packages) {
@@ -252,6 +254,25 @@
     }
 
     /**
+     * Sets the algorithm of the module hashes
+     */
+    public Builder algorithm(String algorithm) {
+        this.algorithm = algorithm;
+        return this;
+    }
+
+    /**
+     * Sets the module hash for the given module name
+     */
+    public Builder moduleHash(String mn, String hash) {
+        if (hashes == null)
+            hashes = new HashMap<>();
+
+        hashes.put(mn, hash);
+        return this;
+    }
+
+    /**
      * Returns the set of packages that is the union of the exported and
      * concealed packages.
      */
@@ -273,6 +294,9 @@
     public ModuleDescriptor build() {
         assert name != null;
 
+        ModuleHashes moduleHashes =
+            hashes != null ? new ModuleHashes(algorithm, hashes) : null;
+
         return jlma.newModuleDescriptor(name,
                                         false,    // automatic
                                         false,    // assume not synthetic for now
@@ -286,6 +310,7 @@
                                         osArch,
                                         osVersion,
                                         conceals,
-                                        computePackages(exports, conceals));
+                                        computePackages(exports, conceals),
+                                        moduleHashes);
     }
 }
--- a/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java	Thu May 05 19:11:09 2016 +0000
@@ -34,6 +34,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -42,7 +43,6 @@
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Label;
-import jdk.internal.module.Hasher.DependencyHashes;
 import static jdk.internal.module.ClassFileConstants.*;
 
 
@@ -148,7 +148,7 @@
                 for (int i=0; i<provides_count; i++) {
                     String sn = cr.readClass(off, buf).replace('/', '.');
                     String cn = cr.readClass(off + 2, buf).replace('/', '.');
-                    provides.computeIfAbsent(sn, k -> new HashSet<>()).add(cn);
+                    provides.computeIfAbsent(sn, k -> new LinkedHashSet<>()).add(cn);
                     off += 4;
                 }
                 provides.entrySet().forEach(e -> builder.provides(e.getKey(),
@@ -281,10 +281,10 @@
      *   u4 attribute_length;
      *
      *   // the number of entries in the packages table
-     *   u2 package_count;
+     *   u2 packages_count;
      *   { // index to CONSTANT_CONSTANT_utf8_info structure with the package name
      *     u2 package_index
-     *   } package[package_count];
+     *   } packages[package_count];
      *
      * }</pre>
      */
@@ -579,9 +579,9 @@
      * alternative is to store it as an array of u1.
      */
     static class HashesAttribute extends Attribute {
-        private final DependencyHashes hashes;
+        private final ModuleHashes hashes;
 
-        HashesAttribute(DependencyHashes hashes) {
+        HashesAttribute(ModuleHashes hashes) {
             super(HASHES);
             this.hashes = hashes;
         }
@@ -613,7 +613,7 @@
                 map.put(dn, hash);
             }
 
-            DependencyHashes hashes = new DependencyHashes(algorithm, map);
+            ModuleHashes hashes = new ModuleHashes(algorithm, map);
 
             return new HashesAttribute(hashes);
         }
--- a/src/java.base/share/classes/jdk/internal/module/Hasher.java	Thu May 05 17:35:48 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +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.  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 jdk.internal.module;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.file.Path;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Supporting class for computing, encoding and decoding hashes (message
- * digests).
- */
-
-public class Hasher {
-    private Hasher() { }
-
-    /**
-     * A supplier of an encoded message digest.
-     */
-    public static interface HashSupplier {
-        String generate(String algorithm);
-    }
-
-    /**
-     * Encapsulates the result of hashing the contents of a number of module
-     * artifacts.
-     */
-    public static class DependencyHashes {
-        private final String algorithm;
-        private final Map<String, String> nameToHash;
-
-        public DependencyHashes(String algorithm, Map<String, String> nameToHash) {
-            this.algorithm = algorithm;
-            this.nameToHash = nameToHash;
-        }
-
-        /**
-         * Returns the algorithm used to hash the dependences ("SHA-256" or
-         * "MD5" for example).
-         */
-        public String algorithm() {
-            return algorithm;
-        }
-
-        /**
-         * Returns the set of module names for which hashes are recorded.
-         */
-        public Set<String> names() {
-            return nameToHash.keySet();
-        }
-
-        /**
-         * Retruns the hash string for the given module name, {@code null}
-         * if there is no hash recorded for the module.
-         */
-        public String hashFor(String dn) {
-            return nameToHash.get(dn);
-        }
-    }
-
-
-    /**
-     * Computes the hash for the given file with the given message digest
-     * algorithm. Returns the results a base64-encoded String.
-     *
-     * @throws UncheckedIOException if an I/O error occurs
-     * @throws RuntimeException if the algorithm is not available
-     */
-    public static String generate(Path file, String algorithm) {
-        try {
-            MessageDigest md = MessageDigest.getInstance(algorithm);
-
-            // Ideally we would just mmap the file but this consumes too much
-            // memory when jlink is running concurrently on very large jmods
-            try (FileChannel fc = FileChannel.open(file)) {
-                ByteBuffer bb = ByteBuffer.allocate(32*1024);
-                int nread;
-                while ((nread = fc.read(bb)) > 0) {
-                    bb.flip();
-                    md.update(bb);
-                    assert bb.remaining() == 0;
-                    bb.clear();
-                }
-            }
-
-            byte[] bytes = md.digest();
-            return Base64.getEncoder().encodeToString(bytes);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        } catch (IOException ioe) {
-            throw new UncheckedIOException(ioe);
-        }
-    }
-
-    /**
-     * Computes the hash for every entry in the given map, returning a
-     * {@code DependencyHashes} to encapsulate the result. The map key is
-     * the entry name, typically the module name. The map value is the file
-     * path to the entry (module artifact).
-     *
-     * @return DependencyHashes encapsulate the hashes
-     */
-    public static DependencyHashes generate(Map<String, Path> map, String algorithm) {
-        Map<String, String> nameToHash = new HashMap<>();
-        for (Map.Entry<String, Path> entry: map.entrySet()) {
-            String name = entry.getKey();
-            Path path = entry.getValue();
-            nameToHash.put(name, generate(path, algorithm));
-        }
-        return new DependencyHashes(algorithm, nameToHash);
-    }
-}
--- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Thu May 05 19:11:09 2016 +0000
@@ -26,12 +26,15 @@
 package jdk.internal.module;
 
 import java.io.File;
+import java.io.PrintStream;
 import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReference;
-import java.lang.module.ModuleFinder;
 import java.lang.module.ResolvedModule;
 import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
+import java.net.URI;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Collections;
@@ -41,10 +44,10 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import jdk.internal.loader.BootLoader;
 import jdk.internal.loader.BuiltinClassLoader;
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.perf.PerfCounter;
 
 /**
@@ -54,10 +57,9 @@
  * the module system. In summary, the boot method creates a Configuration by
  * resolving a set of module names specified via the launcher (or equivalent)
  * -m and -addmods options. The modules are located on a module path that is
- * constructed from the upgrade, system and application module paths. The
- * Configuration is reified by creating the boot Layer with each module in the
- * the configuration defined to one of the built-in class loaders. The mapping
- * of modules to class loaders is statically mapped in a helper class.
+ * constructed from the upgrade module path, system modules, and application
+ * module path. The Configuration is instantiated as the boot Layer with each
+ * module in the the configuration defined to one of the built-in class loaders.
  */
 
 public final class ModuleBootstrap {
@@ -65,6 +67,11 @@
 
     private static final String JAVA_BASE = "java.base";
 
+    private static final String JAVA_SE = "java.se";
+
+    // the token for "all default modules"
+    private static final String ALL_DEFAULT = "ALL-DEFAULT";
+
     // the token for "all unnamed modules"
     private static final String ALL_UNNAMED = "ALL-UNNAMED";
 
@@ -94,47 +101,65 @@
 
         long t0 = System.nanoTime();
 
-        // system module path
-        ModuleFinder systemModulePath = ModuleFinder.ofSystem();
+        // system modules
+        ModuleFinder systemModules = ModuleFinder.ofSystem();
 
-        // Once we have the system module path then we define the base module.
-        // We do this here so that java.base is defined to the VM as early as
+        PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
+
+
+        long t1 = System.nanoTime();
+
+        // Once we have the system modules then we define the base module to
+        // the VM. We do this here so that java.base is defined as early as
         // possible and also that resources in the base module can be located
         // for error messages that may happen from here on.
-        Optional<ModuleReference> obase = systemModulePath.find(JAVA_BASE);
-        if (!obase.isPresent())
+        ModuleReference base = systemModules.find(JAVA_BASE).orElse(null);
+        if (base == null)
             throw new InternalError(JAVA_BASE + " not found");
-        ModuleReference base = obase.get();
+        URI baseUri = base.location().orElse(null);
+        if (baseUri == null)
+            throw new InternalError(JAVA_BASE + " does not have a location");
         BootLoader.loadModule(base);
-        Modules.defineModule(null, base.descriptor(), base.location().orElse(null));
+        Modules.defineModule(null, base.descriptor(), baseUri);
 
+        PerfCounters.defineBaseTime.addElapsedTimeFrom(t1);
+
+
+        long t2 = System.nanoTime();
 
         // -upgrademodulepath option specified to launcher
         ModuleFinder upgradeModulePath
             = createModulePathFinder("jdk.upgrade.module.path");
+        if (upgradeModulePath != null)
+            systemModules = ModuleFinder.compose(upgradeModulePath, systemModules);
 
         // -modulepath option specified to the launcher
         ModuleFinder appModulePath = createModulePathFinder("jdk.module.path");
 
-        // The module finder: [-upgrademodulepath] system-module-path [-modulepath]
-        ModuleFinder finder = systemModulePath;
-        if (upgradeModulePath != null)
-            finder = ModuleFinder.compose(upgradeModulePath, finder);
+        // The module finder: [-upgrademodulepath] system [-modulepath]
+        ModuleFinder finder = systemModules;
         if (appModulePath != null)
             finder = ModuleFinder.compose(finder, appModulePath);
 
-        // launcher -m option to specify the initial module
+        // The root modules to resolve
+        Set<String> roots = new HashSet<>();
+
+        // launcher -m option to specify the main/initial module
         String mainModule = System.getProperty("jdk.module.main");
+        if (mainModule != null)
+            roots.add(mainModule);
 
         // additional module(s) specified by -addmods
+        boolean addAllDefaultModules = false;
         boolean addAllSystemModules = false;
         boolean addAllApplicationModules = false;
-        Set<String> addModules = null;
         String propValue = System.getProperty("jdk.launcher.addmods");
         if (propValue != null) {
-            addModules = new HashSet<>();
             for (String mod: propValue.split(",")) {
                 switch (mod) {
+                    case ALL_DEFAULT:
+                        addAllDefaultModules = true;
+                        break;
                     case ALL_SYSTEM:
                         addAllSystemModules = true;
                         break;
@@ -142,28 +167,12 @@
                         addAllApplicationModules = true;
                         break;
                     default :
-                        addModules.add(mod);
+                        roots.add(mod);
                 }
             }
         }
 
-        // The root modules to resolve
-        Set<String> roots = new HashSet<>();
-
-        // main/initial module
-        if (mainModule != null) {
-            roots.add(mainModule);
-            if (addAllApplicationModules)
-                fail(ALL_MODULE_PATH + " not allowed with initial module");
-        }
-
-        // If -addmods is specified then those modules need to be resolved
-        if (addModules != null)
-            roots.addAll(addModules);
-
-
         // -limitmods
-        boolean limitmods = false;
         propValue = System.getProperty("jdk.launcher.limitmods");
         if (propValue != null) {
             Set<String> mods = new HashSet<>();
@@ -171,62 +180,101 @@
                 mods.add(mod);
             }
             finder = limitFinder(finder, mods, roots);
-            limitmods = true;
         }
 
-
-        // If there is no initial module specified then assume that the
-        // initial module is the unnamed module of the application class
-        // loader. By convention, and for compatibility, this is
-        // implemented by putting the names of all modules on the system
-        // module path into the set of modules to resolve.
-        //
-        // If `-addmods ALL-SYSTEM` is used then all modules on the system
-        // module path will be resolved, irrespective of whether an initial
-        // module is specified.
-        //
-        // If `-addmods ALL-MODULE-PATH` is used, and no initial module is
-        // specified, then all modules on the application module path will
-        // be resolved.
-        //
-        if (mainModule == null || addAllSystemModules) {
-            Set<ModuleReference> mrefs;
-            if (addAllApplicationModules) {
-                assert mainModule == null;
-                mrefs = finder.findAll();
-            } else {
-                mrefs = systemModulePath.findAll();
-                if (limitmods) {
-                    ModuleFinder f = finder;
-                    mrefs = mrefs.stream()
-                        .filter(m -> f.find(m.descriptor().name()).isPresent())
-                        .collect(Collectors.toSet());
+        // If there is no initial module specified then assume that the initial
+        // module is the unnamed module of the application class loader. This
+        // is implemented by resolving "java.se" and all (non-java.*) modules
+        // that export an API. If "java.se" is not observable then all java.*
+        // modules are resolved.
+        if (mainModule == null || addAllDefaultModules) {
+            boolean hasJava = false;
+            if (systemModules.find(JAVA_SE).isPresent()) {
+                // java.se is a system module
+                if (finder == systemModules || finder.find(JAVA_SE).isPresent()) {
+                    // java.se is observable
+                    hasJava = true;
+                    roots.add(JAVA_SE);
                 }
             }
-            // map to module names
-            for (ModuleReference mref : mrefs) {
-                roots.add(mref.descriptor().name());
+
+            for (ModuleReference mref : systemModules.findAll()) {
+                String mn = mref.descriptor().name();
+                if (hasJava && mn.startsWith("java."))
+                    continue;
+
+                // add as root if observable and exports at least one package
+                if ((finder == systemModules || finder.find(mn).isPresent())) {
+                    ModuleDescriptor descriptor = mref.descriptor();
+                    for (ModuleDescriptor.Exports e : descriptor.exports()) {
+                        if (!e.isQualified()) {
+                            roots.add(mn);
+                            break;
+                        }
+                    }
+                }
             }
         }
 
-        long t1 = System.nanoTime();
+        // If `-addmods ALL-SYSTEM` is specified then all observable system
+        // modules will be resolved.
+        if (addAllSystemModules) {
+            ModuleFinder f = finder;  // observable modules
+            systemModules.findAll()
+                .stream()
+                .map(ModuleReference::descriptor)
+                .map(ModuleDescriptor::name)
+                .filter(mn -> f.find(mn).isPresent())  // observable
+                .forEach(mn -> roots.add(mn));
+        }
+
+        // If `-addmods ALL-MODULE-PATH` is specified then all observable
+        // modules on the application module path will be resolved.
+        if  (appModulePath != null && addAllApplicationModules) {
+            ModuleFinder f = finder;  // observable modules
+            appModulePath.findAll()
+                .stream()
+                .map(ModuleReference::descriptor)
+                .map(ModuleDescriptor::name)
+                .filter(mn -> f.find(mn).isPresent())  // observable
+                .forEach(mn -> roots.add(mn));
+        }
+
+        PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t2);
+
+
+        long t3 = System.nanoTime();
+
+        // determine if post resolution checks are needed
+        boolean needPostResolutionChecks = true;
+        if (baseUri.getScheme().equals("jrt")   // toLowerCase not needed here
+                && (upgradeModulePath == null)
+                && (appModulePath == null)
+                && (System.getProperty("jdk.launcher.patch.0") == null)) {
+            needPostResolutionChecks = false;
+        }
+
+        PrintStream traceOutput = null;
+        if (Boolean.getBoolean("jdk.launcher.traceResolver"))
+            traceOutput = System.out;
 
         // run the resolver to create the configuration
-
-        Configuration cf = Configuration.empty()
+        Configuration cf = SharedSecrets.getJavaLangModuleAccess()
                 .resolveRequiresAndUses(finder,
-                                        ModuleFinder.empty(),
-                                        roots);
+                                        roots,
+                                        needPostResolutionChecks,
+                                        traceOutput);
 
         // time to create configuration
-        PerfCounters.resolveTime.addElapsedTimeFrom(t1);
+        PerfCounters.resolveTime.addElapsedTimeFrom(t3);
+
 
         // mapping of modules to class loaders
         Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
 
         // check that all modules to be mapped to the boot loader will be
-        // loaded from the system module path
-        if (finder != systemModulePath) {
+        // loaded from the runtime image
+        if (needPostResolutionChecks) {
             for (ResolvedModule resolvedModule : cf.modules()) {
                 ModuleReference mref = resolvedModule.reference();
                 String name = mref.descriptor().name();
@@ -237,20 +285,22 @@
                             && upgradeModulePath.find(name).isPresent())
                         fail(name + ": cannot be loaded from upgrade module path");
 
-                    if (!systemModulePath.find(name).isPresent())
+                    if (!systemModules.find(name).isPresent())
                         fail(name + ": cannot be loaded from application module path");
                 }
             }
         }
 
-        long t2 = System.nanoTime();
+
+        long t4 = System.nanoTime();
 
         // define modules to VM/runtime
         Layer bootLayer = Layer.empty().defineModules(cf, clf);
 
-        PerfCounters.layerCreateTime.addElapsedTimeFrom(t2);
+        PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
 
-        long t3 = System.nanoTime();
+
+        long t5 = System.nanoTime();
 
         // define the module to its class loader, except java.base
         for (ResolvedModule resolvedModule : cf.modules()) {
@@ -264,7 +314,8 @@
             }
         }
 
-        PerfCounters.loadModulesTime.addElapsedTimeFrom(t3);
+        PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
+
 
         // -XaddReads and -XaddExports
         addExtraReads(bootLayer);
@@ -295,25 +346,21 @@
 
         // module name -> reference
         Map<String, ModuleReference> map = new HashMap<>();
+
+        // root modules and their transitive dependences
         cf.modules().stream()
             .map(ResolvedModule::reference)
             .forEach(mref -> map.put(mref.descriptor().name(), mref));
 
+        // additional modules
+        otherMods.stream()
+            .map(finder::find)
+            .flatMap(Optional::stream)
+            .forEach(mref -> map.putIfAbsent(mref.descriptor().name(), mref));
+
         // set of modules that are observable
         Set<ModuleReference> mrefs = new HashSet<>(map.values());
 
-        // add the other modules
-        for (String mod : otherMods) {
-            Optional<ModuleReference> omref = finder.find(mod);
-            if (omref.isPresent()) {
-                ModuleReference mref = omref.get();
-                map.putIfAbsent(mod, mref);
-                mrefs.add(mref);
-            } else {
-                // no need to fail
-            }
-        }
-
         return new ModuleFinder() {
             @Override
             public Optional<ModuleReference> find(String name) {
@@ -369,15 +416,15 @@
 
                 Module other;
                 if (ALL_UNNAMED.equals(name)) {
-                    other = null;  // loose
+                    Modules.addReadsAllUnnamed(m);
                 } else {
                     om = bootLayer.findModule(name);
                     if (!om.isPresent())
                         fail("Unknown module: " + name);
                     other = om.get();
+                    Modules.addReads(m, other);
                 }
 
-                Modules.addReads(m, other);
             }
         }
     }
@@ -439,10 +486,6 @@
      * Decodes the values of -XaddReads or -XaddExports options
      *
      * The format of the options is: $KEY=$MODULE(,$MODULE)*
-     *
-     * For transition purposes, this method allows the first usage to be
-     *     $KEY=$MODULE(,$KEY=$MODULE)
-     * This format will eventually be removed.
      */
     private static Map<String, Set<String>> decode(String prefix) {
         int index = 0;
@@ -467,42 +510,15 @@
             if (rhs.isEmpty())
                 fail("Unable to parse: " + value);
 
-            // new format $MODULE(,$MODULE)* or old format $(MODULE)=...
-            pos = rhs.indexOf('=');
 
-            // old format only allowed in first -X option
-            if (pos >= 0 && index > 0)
-                fail("Unable to parse: " + value);
+            // value is <module>(,<module>)*
+            if (map.containsKey(key))
+                fail(key + " specified more than once");
 
-            if (pos == -1) {
-
-                // new format: $KEY=$MODULE(,$MODULE)*
-
-                Set<String> values = map.get(key);
-                if (values != null)
-                    fail(key + " specified more than once");
-
-                values = new HashSet<>();
-                map.put(key, values);
-                for (String s : rhs.split(",")) {
-                    if (s.length() > 0) values.add(s);
-                }
-
-            } else {
-
-                // old format: $KEY=$MODULE(,$KEY=$MODULE)*
-
-                assert index == 0;  // old format only allowed in first usage
-
-                for (String expr : value.split(",")) {
-                    if (expr.length() > 0) {
-                        String[] s = expr.split("=");
-                        if (s.length != 2)
-                            fail("Unable to parse: " + expr);
-
-                        map.computeIfAbsent(s[0], k -> new HashSet<>()).add(s[1]);
-                    }
-                }
+            Set<String> values = new HashSet<>();
+            map.put(key, values);
+            for (String s : rhs.split(",")) {
+                if (s.length() > 0) values.add(s);
             }
 
             index++;
@@ -521,6 +537,13 @@
     }
 
     static class PerfCounters {
+
+        static PerfCounter systemModulesTime
+            = PerfCounter.newPerfCounter("jdk.module.bootstrap.systemModulesTime");
+        static PerfCounter defineBaseTime
+            = PerfCounter.newPerfCounter("jdk.module.bootstrap.defineBaseTime");
+        static PerfCounter optionsAndRootsTime
+            = PerfCounter.newPerfCounter("jdk.module.bootstrap.optionsAndRootsTime");
         static PerfCounter resolveTime
             = PerfCounter.newPerfCounter("jdk.module.bootstrap.resolveTime");
         static PerfCounter layerCreateTime
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleHashes.java	Thu May 05 19:11:09 2016 +0000
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, 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.  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 jdk.internal.module;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The result of hashing the contents of a number of module artifacts.
+ */
+
+public final class ModuleHashes {
+
+    /**
+     * A supplier of an encoded message digest.
+     */
+    public static interface HashSupplier {
+        String generate(String algorithm);
+    }
+
+
+    private final String algorithm;
+    private final Map<String, String> nameToHash;
+
+    /**
+     * Creates a {@code ModuleHashes}.
+     *
+     * @param algorithm   the algorithm used to create the hashes
+     * @param nameToHash  the map of module name to hash value (in string form)
+     */
+    public ModuleHashes(String algorithm, Map<String, String> nameToHash) {
+        this.algorithm = algorithm;
+        this.nameToHash = Collections.unmodifiableMap(nameToHash);
+    }
+
+    /**
+     * Returns the algorithm used to hash the modules ("SHA-256" for example).
+     */
+    public String algorithm() {
+        return algorithm;
+    }
+
+    /**
+     * Returns the set of module names for which hashes are recorded.
+     */
+    public Set<String> names() {
+        return nameToHash.keySet();
+    }
+
+    /**
+     * Returns the hash string for the given module name, {@code null}
+     * if there is no hash recorded for the module.
+     */
+    public String hashFor(String mn) {
+        return nameToHash.get(mn);
+    }
+
+    /**
+     * Returns unmodifiable map of module name to hash string.
+     */
+    public Map<String, String> hashes() {
+        return nameToHash;
+    }
+
+    /**
+     * Computes the hash for the given file with the given message digest
+     * algorithm. Returns the results a base64-encoded String.
+     *
+     * @throws UncheckedIOException if an I/O error occurs
+     * @throws RuntimeException if the algorithm is not available
+     */
+    public static String computeHashAsString(Path file, String algorithm) {
+        try {
+            MessageDigest md = MessageDigest.getInstance(algorithm);
+
+            // Ideally we would just mmap the file but this consumes too much
+            // memory when jlink is running concurrently on very large jmods
+            try (FileChannel fc = FileChannel.open(file)) {
+                ByteBuffer bb = ByteBuffer.allocate(32*1024);
+                while (fc.read(bb) > 0) {
+                    bb.flip();
+                    md.update(bb);
+                    assert bb.remaining() == 0;
+                    bb.clear();
+                }
+            }
+
+            byte[] bytes = md.digest();
+            return Base64.getEncoder().encodeToString(bytes);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        } catch (IOException ioe) {
+            throw new UncheckedIOException(ioe);
+        }
+    }
+
+    /**
+     * Computes the hash for every entry in the given map, returning a
+     * {@code ModuleHashes} to encapsulate the result. The map key is
+     * the entry name, typically the module name. The map value is the file
+     * path to the entry (module artifact).
+     *
+     * @return ModuleHashes encapsulate the hashes
+     */
+    public static ModuleHashes generate(Map<String, Path> map, String algorithm) {
+        Map<String, String> nameToHash = new HashMap<>();
+        for (Map.Entry<String, Path> entry: map.entrySet()) {
+            String name = entry.getKey();
+            Path path = entry.getValue();
+            nameToHash.put(name, computeHashAsString(path, algorithm));
+        }
+        return new ModuleHashes(algorithm, nameToHash);
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -41,7 +41,6 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Opcodes;
-import jdk.internal.module.Hasher.DependencyHashes;
 
 import static jdk.internal.module.ClassFileAttributes.*;
 
@@ -69,7 +68,7 @@
     private String osVersion;
 
     // the hashes for the Hashes attribute
-    private DependencyHashes hashes;
+    private ModuleHashes hashes;
 
     private ModuleInfoExtender(InputStream in) {
         this.in = in;
@@ -113,10 +112,10 @@
 
     /**
      * The Hashes attribute will be emitted to the module-info with
-     * the hashes encapsulated in the given {@code DependencyHashes}
+     * the hashes encapsulated in the given {@code ModuleHashes}
      * object.
      */
-    public ModuleInfoExtender hashes(DependencyHashes hashes) {
+    public ModuleInfoExtender hashes(ModuleHashes hashes) {
         this.hashes = hashes;
         return this;
     }
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -49,28 +49,22 @@
      * Writes the given module descriptor to a module-info.class file,
      * returning it in a byte array.
      */
-    private static byte[] toModuleInfo(ModuleDescriptor descriptor) {
+    private static byte[] toModuleInfo(ModuleDescriptor md) {
 
         ClassWriter cw = new ClassWriter(0);
 
-        String name = descriptor.name().replace('.', '/') + "/module-info";
+        String name = md.name().replace('.', '/') + "/module-info";
         cw.visit(Opcodes.V1_8, ACC_MODULE, name, null, null, null);
 
-        cw.visitAttribute(new ModuleAttribute(descriptor));
-        cw.visitAttribute(new ConcealedPackagesAttribute(descriptor.conceals()));
-
-        Optional<Version> oversion = descriptor.version();
-        if (oversion.isPresent())
-            cw.visitAttribute(new VersionAttribute(oversion.get()));
-
-        Optional<String> omain = descriptor.mainClass();
-        if (omain.isPresent())
-            cw.visitAttribute(new MainClassAttribute(omain.get()));
+        cw.visitAttribute(new ModuleAttribute(md));
+        cw.visitAttribute(new ConcealedPackagesAttribute(md.conceals()));
+        md.version().ifPresent(v -> cw.visitAttribute(new VersionAttribute(v)));
+        md.mainClass().ifPresent(mc -> cw.visitAttribute(new MainClassAttribute(mc)));
 
         // write the TargetPlatform attribute if have any of OS name/arch/version
-        String osName = descriptor.osName().orElse(null);
-        String osArch = descriptor.osArch().orElse(null);
-        String osVersion = descriptor.osVersion().orElse(null);
+        String osName = md.osName().orElse(null);
+        String osArch = md.osArch().orElse(null);
+        String osVersion = md.osVersion().orElse(null);
         if (osName != null || osArch != null || osVersion != null) {
             cw.visitAttribute(new TargetPlatformAttribute(osName,
                                                           osArch,
--- a/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Thu May 05 19:11:09 2016 +0000
@@ -91,56 +91,29 @@
 
         Map<String, List<Path>> map = new HashMap<>();
         while (value != null) {
+
+            // <module>=<file>(:<file>)*
+
             int pos = value.indexOf('=');
-
-            if (pos == -1 && index > 0)
+            if (pos == -1)
                 throwIAE("Unable to parse: " + value);
-
             if (pos == 0)
                 throwIAE("Missing module name: " + value);
 
-            if (pos > 0) {
+            String mn = value.substring(0, pos);
+            List<Path> list = map.get(mn);
+            if (list != null)
+                throwIAE("Module " + mn + " specified more than once");
+            list = new ArrayList<>();
+            map.put(mn, list);
 
-                // new format: <module>=<file>(:<file>)*
-
-                String mn = value.substring(0, pos);
-                List<Path> list = map.get(mn);
-                if (list != null)
-                    throwIAE("Module " + mn + " specified more than once");
-                list = new ArrayList<>();
-                map.put(mn, list);
-
-                String paths = value.substring(pos+1);
-                for (String path : paths.split(File.pathSeparator)) {
-                    if (!path.isEmpty()) {
-                        list.add(Paths.get(path));
-                    }
+            String paths = value.substring(pos+1);
+            for (String path : paths.split(File.pathSeparator)) {
+                if (!path.isEmpty()) {
+                    list.add(Paths.get(path));
                 }
-
-            } else {
-
-                // old format: <dir>(:<dir>)*
-
-                assert index == 0; // old format only allowed in first -Xpatch
-
-                String[] dirs = value.split(File.pathSeparator);
-                for (String d : dirs) {
-                    if (d.length() > 0) {
-                        Path top = Paths.get(d);
-                        try {
-                            Files.list(top).forEach(e -> {
-                                String mn = e.getFileName().toString();
-                                Path dir = top.resolve(mn);
-                                map.computeIfAbsent(mn, k -> new ArrayList<>())
-                                    .add(dir);
-                            });
-                        } catch (IOException ignore) { }
-                    }
-                }
-
             }
 
-
             index++;
             value = System.getProperty(PATCH_PROPERTY_PREFIX + index);
         }
@@ -175,7 +148,8 @@
             for (Path file : paths) {
                 if (Files.isRegularFile(file)) {
 
-                    // JAR file
+                    // JAR file - do not open as a multi-release JAR as this
+                    // is not supported by the boot class loader
                     try (JarFile jf = new JarFile(file.toFile())) {
                         jf.stream()
                           .filter(e -> e.getName().endsWith(".class"))
@@ -209,10 +183,11 @@
             descriptor = JLMA.newModuleDescriptor(descriptor, packages);
         }
 
-        // return a new module reference
+        // return a module reference to the patched module
         URI location = mref.location().orElse(null);
-        return new ModuleReference(descriptor, location,
-                                   () -> new PatchedModuleReader(paths, mref));
+        return JLMA.newPatchedModule(descriptor,
+                                     location,
+                                     () -> new PatchedModuleReader(paths, mref));
 
     }
 
--- a/src/java.base/share/classes/jdk/internal/module/Modules.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/Modules.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -58,7 +58,7 @@
      * Creates a new Module. The module has the given ModuleDescriptor and
      * is defined to the given class loader.
      *
-     * The resulting Module is in a larva state in that it does not not read
+     * The resulting Module is in a larval state in that it does not not read
      * any other module and does not have any exports.
      *
      * The URI is for information purposes only.
@@ -74,7 +74,7 @@
      * Define a new module to the VM. The module has the given set of
      * concealed packages and is defined to the given class loader.
      *
-     * The resulting Module is in a larva state in that it does not not read
+     * The resulting Module is in a larval state in that it does not not read
      * any other module and does not have any exports.
      */
     public static Module defineModule(ClassLoader loader,
@@ -96,6 +96,13 @@
     }
 
     /**
+     * Update module {@code m} to read all unnamed modules.
+     */
+    public static void addReadsAllUnnamed(Module m) {
+        JLRMA.addReadsAllUnnamed(m);
+    }
+
+    /**
      * Updates module m1 to export a package to module m2.
      * Same as m1.addExports(pkg, m2) but without a caller check.
      */
--- a/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -29,94 +29,105 @@
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleDescriptor.Provides;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * A services catalog. Each {@code ClassLoader} has an optional {@code
- * ServicesCatalog} for modules that provide services. This is to support
- * ClassLoader centric ServiceLoader.load methods.
+ * A <em>services catalog</em>. Each {@code ClassLoader} and {@code Layer} has
+ * an optional {@code ServicesCatalog} for modules that provide services.
+ *
+ * @see java.util.ServiceLoader
  */
-public class ServicesCatalog {
-
-    // use RW locks as register is rare
-    private final ReadWriteLock lock = new ReentrantReadWriteLock();
-    private final Lock readLock = lock.readLock();
-    private final Lock writeLock = lock.writeLock();
+public interface ServicesCatalog {
 
     /**
      * Represents a service provider in the services catalog.
      */
-    public class ServiceProvider {
+    public final class ServiceProvider {
         private final Module module;
         private final String providerName;
-        ServiceProvider(Module module, String providerName) {
+
+        public ServiceProvider(Module module, String providerName) {
             this.module = module;
             this.providerName = providerName;
         }
+
         public Module module() {
             return module;
         }
+
         public String providerName() {
             return providerName;
         }
-    }
 
-    // service providers
-    private final Map<String, Set<ServiceProvider>> loaderServices = new HashMap<>();
+        @Override
+        public int hashCode() {
+            return Objects.hash(module, providerName);
+        }
 
-    /**
-     * Creates a new module catalog.
-     */
-    public ServicesCatalog() { }
-
-    /**
-     * Registers the module in this module catalog.
-     */
-    public void register(Module m) {
-        ModuleDescriptor descriptor = m.getDescriptor();
-
-        writeLock.lock();
-        try {
-            // extend the services map
-            for (Provides ps : descriptor.provides().values()) {
-                String service = ps.service();
-                Set<String> providerNames = ps.providers();
-
-                // create a new set to replace the existing
-                Set<ServiceProvider> result = new HashSet<>();
-                Set<ServiceProvider> providers = loaderServices.get(service);
-                if (providers != null) {
-                    result.addAll(providers);
-                }
-                for (String pn : providerNames) {
-                    result.add(new ServiceProvider(m, pn));
-                }
-                loaderServices.put(service, Collections.unmodifiableSet(result));
-            }
-
-        } finally {
-            writeLock.unlock();
+        @Override
+        public boolean equals(Object ob) {
+            if (!(ob instanceof ServiceProvider))
+                return false;
+            ServiceProvider that = (ServiceProvider)ob;
+            return Objects.equals(this.module, that.module)
+                    && Objects.equals(this.providerName, that.providerName);
         }
     }
 
     /**
+     * Registers the providers in the given module in this services catalog.
+     *
+     * @throws UnsupportedOperationException
+     *         If this services catalog is immutable
+     */
+    void register(Module module);
+
+    /**
      * Returns the (possibly empty) set of service providers that implement the
      * given service type.
-     *
-     * @see java.util.ServiceLoader
      */
-    public Set<ServiceProvider> findServices(String service) {
-        readLock.lock();
-        try {
-            return loaderServices.getOrDefault(service, Collections.emptySet());
-        } finally {
-            readLock.unlock();
-        }
+    Set<ServiceProvider> findServices(String service);
+
+    /**
+     * Creates a ServicesCatalog that supports concurrent registration and
+     * and lookup.
+     */
+    static ServicesCatalog create() {
+        return new ServicesCatalog() {
+
+            private Map<String, Set<ServiceProvider>> map = new ConcurrentHashMap<>();
+
+            @Override
+            public void register(Module m) {
+                ModuleDescriptor descriptor = m.getDescriptor();
+
+                for (Provides provides : descriptor.provides().values()) {
+                    String service = provides.service();
+                    Set<String> providerNames = provides.providers();
+
+                    // create a new set to replace the existing
+                    Set<ServiceProvider> result = new HashSet<>();
+                    Set<ServiceProvider> providers = map.get(service);
+                    if (providers != null) {
+                        result.addAll(providers);
+                    }
+                    for (String pn : providerNames) {
+                        result.add(new ServiceProvider(m, pn));
+                    }
+                    map.put(service, Collections.unmodifiableSet(result));
+                }
+
+            }
+
+            @Override
+            public Set<ServiceProvider> findServices(String service) {
+                return map.getOrDefault(service, Collections.emptySet());
+            }
+
+        };
     }
-}
+}
\ No newline at end of file
--- a/src/java.base/share/classes/jdk/internal/module/SystemModules.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/module/SystemModules.java	Thu May 05 19:11:09 2016 +0000
@@ -40,21 +40,26 @@
  */
 public final class SystemModules {
     /**
-     * Name of the installed modules.
+     * Name of the system modules.
      *
-     * This array provides a way for InstalledModuleFinder to fallback
+     * This array provides a way for SystemModuleFinder to fallback
      * and read module-info.class from the run-time image instead of
      * the fastpath.
      */
     public static final String[] MODULE_NAMES = new String[1];
 
     /**
+     * Hash of system modules.
+     */
+    public static String[] MODULES_TO_HASH = new String[1];
+
+    /**
      * Number of packages in the boot layer from the installed modules.
      *
      * Don't make it final to avoid inlining during compile time as
      * the value will be changed at jlink time.
      */
-    public static final int PACKAGES_IN_BOOT_LAYER = 1024;
+    public static int PACKAGES_IN_BOOT_LAYER = 1024;
 
     /**
      * Returns a non-empty array of ModuleDescriptors in the run-time image.
@@ -64,4 +69,5 @@
     public static ModuleDescriptor[] modules() {
         return new ModuleDescriptor[0];
     }
-}
\ No newline at end of file
+
+}
--- a/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java	Thu May 05 19:11:09 2016 +0000
@@ -392,6 +392,7 @@
         // matter.
         return AccessController.doPrivileged(
             new PrivilegedAction<MagicAccessorImpl>() {
+                @SuppressWarnings("deprecation") // Class.newInstance
                 public MagicAccessorImpl run() {
                         try {
                         return (MagicAccessorImpl)
--- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Thu May 05 19:11:09 2016 +0000
@@ -343,8 +343,8 @@
 
     private static void printStackTraceIfNeeded(Throwable e) {
         if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) {
-            String s = GetPropertyAction
-                    .getProperty("sun.reflect.debugModuleAccessChecks");
+            String s = GetPropertyAction.privilegedGetProperty(
+                    "sun.reflect.debugModuleAccessChecks");
             printStackWhenAccessFails =
                     (s != null && !s.equalsIgnoreCase("false"));
             printStackWhenAccessFailsSet = true;
--- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -398,7 +398,7 @@
             return;
         }
 
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         String val = props.getProperty("sun.reflect.noInflation");
         if (val != null && val.equals("true")) {
             noInflation = true;
--- a/src/java.base/share/classes/module-info.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/module-info.java	Thu May 05 19:11:09 2016 +0000
@@ -166,6 +166,8 @@
         java.sql,
         java.xml,
         jdk.charsets,
+        jdk.jartool,
+        jdk.jlink,
         jdk.net,
         jdk.scripting.nashorn,
         jdk.unsupported,
--- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Thu May 05 19:11:09 2016 +0000
@@ -84,8 +84,10 @@
 import jdk.internal.misc.VM;
 
 
-public enum LauncherHelper {
-    INSTANCE;
+public final class LauncherHelper {
+
+    // No instantiation
+    private LauncherHelper() {}
 
     // used to identify JavaFX applications
     private static final String JAVAFX_APPLICATION_MARKER =
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 05 19:11:09 2016 +0000
@@ -27,7 +27,7 @@
 java.launcher.opt.header  =   Usage: {0} [options] class [args...]\n\
 \           (to execute a class)\n   or  {0} [options] -jar jarfile [args...]\n\
 \           (to execute a jar file)\n\
-\   or  {0} [-options] -mp <modulepath> -m <modulename> | <modulename>/<mainclass>\n\
+\   or  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n\
 \           (to execute the main class in a module)\n\
 where options include:\n
 
@@ -51,8 +51,9 @@
 \                  A {0} separated list of directories, each directory\n\
 \                  is a directory of modules that replace upgradeable\n\
 \                  modules in the runtime image\n\
-\    -m <modulename> | <modulename>/<mainclass>\n\
-\                  the initial or main module to resolve\n\
+\    -m <modulename>[/<mainclass>]\n\
+\                  the initial module to resolve, and the name of the main class\n\
+\                  to execute if not specified by the module\n\
 \    -addmods <modulename>[,<modulename>...]\n\
 \                  root modules to resolve in addition to the initial module\n\
 \    -limitmods <modulename>[,<modulename>...]\n\
--- a/src/java.base/share/classes/sun/net/ResourceManager.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/ResourceManager.java	Thu May 05 19:11:09 2016 +0000
@@ -53,8 +53,8 @@
     private static final AtomicInteger numSockets;
 
     static {
-        String prop =
-                GetPropertyAction.getProperty("sun.net.maxDatagramSockets");
+        String prop = GetPropertyAction
+                .privilegedGetProperty("sun.net.maxDatagramSockets");
         int defmax = DEFAULT_MAX_SOCKETS;
         try {
             if (prop != null) {
--- a/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -67,8 +67,9 @@
             return false;
         }
         try {
-            Class<?> c = Class.forName(cm, true, null);
-            provider = (FtpClientProvider) c.newInstance();
+            @SuppressWarnings("deprecation")
+            Object o = Class.forName(cm, true, null).newInstance();
+            provider = (FtpClientProvider)o;
             return true;
         } catch (ClassNotFoundException |
                  IllegalAccessException |
--- a/src/java.base/share/classes/sun/net/sdp/SdpSupport.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/sdp/SdpSupport.java	Thu May 05 19:11:09 2016 +0000
@@ -40,7 +40,7 @@
  */
 
 public final class SdpSupport {
-    private static final String os = GetPropertyAction.getProperty("os.name");
+    private static final String os = GetPropertyAction.privilegedGetProperty("os.name");
     private static final boolean isSupported = (os.equals("SunOS") || (os.equals("Linux")));
     private static final JavaIOFileDescriptorAccess fdAccess =
         SharedSecrets.getJavaIOFileDescriptorAccess();
--- a/src/java.base/share/classes/sun/net/smtp/SmtpClient.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/smtp/SmtpClient.java	Thu May 05 19:11:09 2016 +0000
@@ -157,7 +157,7 @@
         }
         try {
             String s;
-            mailhost = GetPropertyAction.getProperty("mail.host");
+            mailhost = GetPropertyAction.privilegedGetProperty("mail.host");
             if (mailhost != null) {
                 openServer(mailhost);
                 return;
@@ -183,7 +183,7 @@
         setConnectTimeout(to);
         try {
             String s;
-            mailhost = GetPropertyAction.getProperty("mail.host");
+            mailhost = GetPropertyAction.privilegedGetProperty("mail.host");
             if (mailhost != null) {
                 openServer(mailhost);
                 return;
--- a/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Thu May 05 19:11:09 2016 +0000
@@ -183,7 +183,7 @@
         }
 
         String execPathList;
-        execPathList = GetPropertyAction.getProperty("exec.path");
+        execPathList = GetPropertyAction.privilegedGetProperty("exec.path");
         if (execPathList == null) {
             // exec.path property not set
             return false;
--- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Thu May 05 19:11:09 2016 +0000
@@ -145,7 +145,7 @@
     }
 
     static {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         String keepAlive = props.getProperty("http.keepAlive");
         String retryPost = props.getProperty("sun.net.http.retryPost");
 
--- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Thu May 05 19:11:09 2016 +0000
@@ -278,7 +278,7 @@
 
         if (user == null) {
             user = "anonymous";
-            Properties props = GetPropertyAction.getProperties();
+            Properties props = GetPropertyAction.privilegedGetProperties();
             String vers = props.getProperty("java.version");
             password = props.getProperty("ftp.protocol.user",
                     "Java" + vers + "@");
--- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Thu May 05 19:11:09 2016 +0000
@@ -94,7 +94,7 @@
     }
 
     static {
-        authPref = GetPropertyAction.getProperty("http.auth.preference");
+        authPref = GetPropertyAction.privilegedGetProperty("http.auth.preference");
 
         // http.auth.preference can be set to SPNEGO or Kerberos.
         // In fact they means "Negotiate with SPNEGO" and "Negotiate with
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu May 05 19:11:09 2016 +0000
@@ -207,9 +207,9 @@
     };
 
     static {
-        Properties props = GetPropertyAction.getProperties();
-        maxRedirects = GetIntegerAction.getProperty("http.maxRedirects",
-                        defaultmaxRedirects);
+        Properties props = GetPropertyAction.privilegedGetProperties();
+        maxRedirects = GetIntegerAction.privilegedGetProperty(
+                "http.maxRedirects", defaultmaxRedirects);
         version = props.getProperty("java.version");
         String agent = props.getProperty("http.agent");
         if (agent == null) {
@@ -225,14 +225,14 @@
 
         enableESBuffer = Boolean.parseBoolean(
                 props.getProperty("sun.net.http.errorstream.enableBuffering"));
-        timeout4ESBuffer = GetIntegerAction
-                .getProperty("sun.net.http.errorstream.timeout", 300);
+        timeout4ESBuffer = GetIntegerAction.privilegedGetProperty(
+                "sun.net.http.errorstream.timeout", 300);
         if (timeout4ESBuffer <= 0) {
             timeout4ESBuffer = 300; // use the default
         }
 
-        bufSize4ES = GetIntegerAction
-                .getProperty("sun.net.http.errorstream.bufferSize", 4096);
+        bufSize4ES = GetIntegerAction.privilegedGetProperty(
+                "sun.net.http.errorstream.bufferSize", 4096);
         if (bufSize4ES <= 0) {
             bufSize4ES = 4096; // use the default
         }
--- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java	Thu May 05 19:11:09 2016 +0000
@@ -139,7 +139,7 @@
         //
         String ciphers [];
         String cipherString =
-                GetPropertyAction.getProperty("https.cipherSuites");
+                GetPropertyAction.privilegedGetProperty("https.cipherSuites");
 
         if (cipherString == null || "".equals(cipherString)) {
             ciphers = null;
@@ -163,7 +163,7 @@
         //
         String protocols [];
         String protocolString =
-                GetPropertyAction.getProperty("https.protocols");
+                GetPropertyAction.privilegedGetProperty("https.protocols");
 
         if (protocolString == null || "".equals(protocolString)) {
             protocols = null;
@@ -183,7 +183,8 @@
     }
 
     private String getUserAgent() {
-        String userAgent = GetPropertyAction.getProperty("https.agent");
+        String userAgent =
+                GetPropertyAction.privilegedGetProperty("https.agent");
         if (userAgent == null || userAgent.length() == 0) {
             userAgent = "JSSE";
         }
--- a/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Thu May 05 19:11:09 2016 +0000
@@ -161,7 +161,7 @@
     public Permission getPermission() throws IOException {
         Permission p = permission;
         if (p == null) {
-            String home = GetPropertyAction.getProperty("java.home");
+            String home = GetPropertyAction.privilegedGetProperty("java.home");
             p = new FilePermission(home + File.separator + "-", "read");
             permission = p;
         }
--- a/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java	Thu May 05 19:11:09 2016 +0000
@@ -56,9 +56,9 @@
         URL ru;
 
         boolean localonly = Boolean.parseBoolean(
-                GetPropertyAction.getProperty("newdoc.localonly"));
+                GetPropertyAction.privilegedGetProperty("newdoc.localonly"));
 
-        String docurl = GetPropertyAction.getProperty("doc.url");
+        String docurl = GetPropertyAction.privilegedGetProperty("doc.url");
 
         String file = u.getFile();
         if (!localonly) {
--- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -1019,7 +1019,7 @@
         if (!propertyChecked) {
             synchronized (FileChannelImpl.class) {
                 if (!propertyChecked) {
-                    String value = GetPropertyAction.getProperty(
+                    String value = GetPropertyAction.privilegedGetProperty(
                             "sun.nio.ch.disableSystemWideOverlappingFileLockCheck");
                     isSharedFileLockTable = ((value == null) || value.equals("false"));
                     propertyChecked = true;
--- a/src/java.base/share/classes/sun/nio/ch/Net.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/Net.java	Thu May 05 19:11:09 2016 +0000
@@ -374,8 +374,8 @@
     }
 
     public static boolean isFastTcpLoopbackRequested() {
-        String loopbackProp =
-                GetPropertyAction.getProperty("jdk.net.useFastTcpLoopback");
+        String loopbackProp = GetPropertyAction
+                .privilegedGetProperty("jdk.net.useFastTcpLoopback");
         boolean enable;
         if ("".equals(loopbackProp)) {
             enable = true;
@@ -633,8 +633,8 @@
     static {
         int availLevel = isExclusiveBindAvailable();
         if (availLevel >= 0) {
-            String exclBindProp =
-                    GetPropertyAction.getProperty("sun.net.useExclusiveBind");
+            String exclBindProp = GetPropertyAction
+                    .privilegedGetProperty("sun.net.useExclusiveBind");
             if (exclBindProp != null) {
                 exclusiveBind = exclBindProp.isEmpty() ?
                         true : Boolean.parseBoolean(exclBindProp);
--- a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java	Thu May 05 19:11:09 2016 +0000
@@ -165,14 +165,11 @@
             GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY));
         if (propValue != null) {
             try {
-                Class<?> c = Class
-                    .forName(propValue, true, ClassLoader.getSystemClassLoader());
-                return ((ThreadFactory)c.newInstance());
-            } catch (ClassNotFoundException x) {
-                throw new Error(x);
-            } catch (InstantiationException x) {
-                throw new Error(x);
-            } catch (IllegalAccessException x) {
+                @SuppressWarnings("deprecation")
+                Object tmp = Class
+                    .forName(propValue, true, ClassLoader.getSystemClassLoader()).newInstance();
+                return (ThreadFactory)tmp;
+            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException x) {
                 throw new Error(x);
             }
         }
--- a/src/java.base/share/classes/sun/nio/ch/Util.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/Util.java	Thu May 05 19:11:09 2016 +0000
@@ -64,7 +64,8 @@
      * for potential future-proofing.
      */
     private static long getMaxCachedBufferSize() {
-        String s = GetPropertyAction.getProperty("jdk.nio.maxCachedBufferSize");
+        String s = GetPropertyAction
+                .privilegedGetProperty("jdk.nio.maxCachedBufferSize");
         if (s != null) {
             try {
                 long m = Long.parseLong(s);
@@ -465,7 +466,8 @@
         if (bugLevel == null) {
             if (!jdk.internal.misc.VM.isBooted())
                 return false;
-            String value = GetPropertyAction.getProperty("sun.nio.ch.bugLevel");
+            String value = GetPropertyAction
+                    .privilegedGetProperty("sun.nio.ch.bugLevel");
             bugLevel = (value != null) ? value : "";
         }
         return bugLevel.equals(bl);
--- a/src/java.base/share/classes/sun/nio/cs/FastCharsetProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/cs/FastCharsetProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -115,10 +115,11 @@
 
         // Instantiate the charset and cache it
         try {
-            Class<?> c = Class.forName(packagePrefix + "." + cln,
+            @SuppressWarnings("deprecation")
+            Object o= Class.forName(packagePrefix + "." + cln,
                                     true,
-                                    this.getClass().getClassLoader());
-            cs = (Charset)c.newInstance();
+                                    this.getClass().getClassLoader()).newInstance();
+            cs = (Charset)o;
             cache.put(csn, cs);
             return cs;
         } catch (ClassNotFoundException |
--- a/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Thu May 05 19:11:09 2016 +0000
@@ -110,10 +110,11 @@
 
         // Instantiate the charset and cache it
         try {
-            Class<?> c = Class.forName(packagePrefix + "." + cln,
-                                    true,
-                                    this.getClass().getClassLoader());
-            cs = (Charset)c.newInstance();
+            @SuppressWarnings("deprecation")
+            Object o = Class.forName(packagePrefix + "." + cln,
+                                     true,
+                                     this.getClass().getClassLoader()).newInstance();
+            cs = (Charset)o;
             cache.put(csn, cs);
             return cs;
         } catch (ClassNotFoundException |
@@ -164,7 +165,7 @@
             return;
         initialized = true;
 
-        String map = getProperty("sun.nio.cs.map");
+        String map = GetPropertyAction.privilegedGetProperty("sun.nio.cs.map");
         if (map != null) {
             String[] maps = map.split(",");
             for (int i = 0; i < maps.length; i++) {
@@ -199,9 +200,4 @@
         }
     }
 
-    private static String getProperty(String key) {
-        return GetPropertyAction.getProperty(key);
-    }
-
-
 }
--- a/src/java.base/share/classes/sun/nio/fs/Util.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/nio/fs/Util.java	Thu May 05 19:11:09 2016 +0000
@@ -38,7 +38,7 @@
     private Util() { }
 
     private static final Charset jnuEncoding = Charset.forName(
-        GetPropertyAction.getProperty("sun.jnu.encoding"));
+        GetPropertyAction.privilegedGetProperty("sun.jnu.encoding"));
 
     /**
      * Returns {@code Charset} corresponding to the sun.jnu.encoding property
--- a/src/java.base/share/classes/sun/security/action/GetIntegerAction.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/action/GetIntegerAction.java	Thu May 05 19:11:09 2016 +0000
@@ -118,9 +118,14 @@
      * if no security manager is present. This is unsafe for inclusion in a
      * public API but allowable here since this class is now encapsulated.
      *
+     * Note that this method performs a privileged action using caller-provided
+     * inputs. The caller of this method should take care to ensure that the
+     * inputs are not tainted and the returned property is not made accessible
+     * to untrusted code if it contains sensitive information.
+     *
      * @param theProp the name of the system property.
      */
-    public static Integer getProperty(String theProp) {
+    public static Integer privilegedGetProperty(String theProp) {
         if (System.getSecurityManager() == null) {
             return Integer.getInteger(theProp);
         } else {
@@ -134,10 +139,16 @@
      * if no security manager is present. This is unsafe for inclusion in a
      * public API but allowable here since this class is now encapsulated.
      *
+     * Note that this method performs a privileged action using caller-provided
+     * inputs. The caller of this method should take care to ensure that the
+     * inputs are not tainted and the returned property is not made accessible
+     * to untrusted code if it contains sensitive information.
+     *
      * @param theProp the name of the system property.
      * @param defaultVal the default value.
      */
-    public static Integer getProperty(String theProp, int defaultVal) {
+    public static Integer privilegedGetProperty(String theProp,
+            int defaultVal) {
         Integer value;
         if (System.getSecurityManager() == null) {
             value = Integer.getInteger(theProp);
--- a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/action/GetPropertyAction.java	Thu May 05 19:11:09 2016 +0000
@@ -93,9 +93,14 @@
      * if no security manager is present. This is unsafe for inclusion in a
      * public API but allowable here since this class is now encapsulated.
      *
+     * Note that this method performs a privileged action using caller-provided
+     * inputs. The caller of this method should take care to ensure that the
+     * inputs are not tainted and the returned property is not made accessible
+     * to untrusted code if it contains sensitive information.
+     *
      * @param theProp the name of the system property.
      */
-    public static String getProperty(String theProp) {
+    public static String privilegedGetProperty(String theProp) {
         if (System.getSecurityManager() == null) {
             return System.getProperty(theProp);
         } else {
@@ -109,10 +114,16 @@
      * if no security manager is present. This is unsafe for inclusion in a
      * public API but allowable here since this class is now encapsulated.
      *
+     * Note that this method performs a privileged action using caller-provided
+     * inputs. The caller of this method should take care to ensure that the
+     * inputs are not tainted and the returned property is not made accessible
+     * to untrusted code if it contains sensitive information.
+     *
      * @param theProp the name of the system property.
      * @param defaultVal the default value.
      */
-    public static String getProperty(String theProp, String defaultVal) {
+    public static String privilegedGetProperty(String theProp,
+            String defaultVal) {
         if (System.getSecurityManager() == null) {
             return System.getProperty(theProp, defaultVal);
         } else {
@@ -126,8 +137,13 @@
      * having to go through doPrivileged if no security manager is present.
      * This is unsafe for inclusion in a public API but allowable here since
      * this class is now encapsulated.
+     *
+     * Note that this method performs a privileged action, and callers of
+     * this method should take care to ensure that the returned properties
+     * are not made accessible to untrusted code since it may contain
+     * sensitive information.
      */
-    public static Properties getProperties() {
+    public static Properties privilegedGetProperties() {
         if (System.getSecurityManager() == null) {
             return System.getProperties();
         } else {
--- a/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Thu May 05 19:11:09 2016 +0000
@@ -185,7 +185,9 @@
                     try {
                         Class<?> c = Class.forName("apple.security.AppleProvider");
                         if (Provider.class.isAssignableFrom(c)) {
-                            return (Provider) c.newInstance();
+                            @SuppressWarnings("deprecation")
+                            Object tmp = c.newInstance();
+                            return (Provider) tmp;
                         } else {
                             return null;
                         }
@@ -386,6 +388,7 @@
 
                 Provider p = AccessController.doPrivileged
                     (new PrivilegedExceptionAction<Provider>() {
+                    @SuppressWarnings("deprecation") // Class.newInstance
                     public Provider run() throws Exception {
                         return (Provider) provClass.newInstance();
                     }
--- a/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java	Thu May 05 19:11:09 2016 +0000
@@ -218,11 +218,10 @@
                 }
             }
 
-            Object      inst = null;
+            @SuppressWarnings("deprecation")
+            Object      inst = (keyClass != null) ? keyClass.newInstance() : null;
             PKCS8Key    result;
 
-            if (keyClass != null)
-                inst = keyClass.newInstance();
             if (inst instanceof PKCS8Key) {
                 result = (PKCS8Key) inst;
                 result.algid = algid;
--- a/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -70,7 +70,7 @@
          * By default this is false.
          * This incompatibility was introduced by 4532506.
          */
-        String prop = GetPropertyAction.getProperty(SERIAL_PROP);
+        String prop = GetPropertyAction.privilegedGetProperty(SERIAL_PROP);
         SERIAL_INTEROP = "true".equalsIgnoreCase(prop);
     }
 
--- a/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java	Thu May 05 19:11:09 2016 +0000
@@ -43,7 +43,6 @@
 
 import static sun.security.provider.certpath.OCSP.*;
 import static sun.security.provider.certpath.PKIX.*;
-import sun.security.action.GetPropertyAction;
 import sun.security.x509.*;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.util.Debug;
--- a/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -84,7 +84,7 @@
     public static final int MAX_RESTRICTED_EXPLEN = 64;
 
     private static final boolean restrictExpLen =
-        "true".equalsIgnoreCase(GetPropertyAction.getProperty(
+        "true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty(
                 "sun.security.rsa.restrictRSAExponent", "true"));
 
     // instance used for static translateKey();
--- a/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java	Thu May 05 19:11:09 2016 +0000
@@ -50,7 +50,7 @@
                 providers = new HashMap<>();
 
         static {
-            String path = GetPropertyAction.getProperty("java.home");
+            String path = GetPropertyAction.privilegedGetProperty("java.home");
             ServiceLoader<ClientKeyExchangeService> sc =
                     AccessController.doPrivileged(
                             (PrivilegedAction<ServiceLoader<ClientKeyExchangeService>>)
--- a/src/java.base/share/classes/sun/security/ssl/Debug.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/Debug.java	Thu May 05 19:11:09 2016 +0000
@@ -45,7 +45,7 @@
     private static String args;
 
     static {
-        args = GetPropertyAction.getProperty("javax.net.debug", "");
+        args = GetPropertyAction.privilegedGetProperty("javax.net.debug", "");
         args = args.toLowerCase(Locale.ENGLISH);
         if (args.equals("help")) {
             Help();
@@ -178,11 +178,11 @@
     /**
      * Return the value of the boolean System property propName.
      *
-     * Note use of doPrivileged(). Do make accessible to applications.
+     * Note use of privileged action. Do NOT make accessible to applications.
      */
     static boolean getBooleanProperty(String propName, boolean defaultValue) {
         // if set, require value of either true or false
-        String b = GetPropertyAction.getProperty(propName);
+        String b = GetPropertyAction.privilegedGetProperty(propName);
         if (b == null) {
             return defaultValue;
         } else if (b.equalsIgnoreCase("false")) {
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -656,7 +656,8 @@
         // the provider service. Instead, please handle the initialization
         // exception in the caller's constructor.
         static {
-            String property = GetPropertyAction.getProperty(PROPERTY_NAME);
+            String property = GetPropertyAction
+                    .privilegedGetProperty(PROPERTY_NAME);
             if (property != null && property.length() != 0) {
                 // remove double quote marks from beginning/end of the property
                 if (property.length() > 1 && property.charAt(0) == '"' &&
--- a/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Thu May 05 19:11:09 2016 +0000
@@ -119,8 +119,8 @@
     private long statusRespTimeout;
 
     static {
-        String property =
-                GetPropertyAction.getProperty("jdk.tls.ephemeralDHKeySize");
+        String property = GetPropertyAction
+                .privilegedGetProperty("jdk.tls.ephemeralDHKeySize");
         if (property == null || property.length() == 0) {
             useLegacyEphemeralDHKeys = false;
             useSmartEphemeralDHKeys = false;
--- a/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java	Thu May 05 19:11:09 2016 +0000
@@ -73,8 +73,8 @@
                     DEFAULT_CACHE_LIFETIME));
         cacheLifetime = life > 0 ? life : 0;
 
-        String uriStr =
-                GetPropertyAction.getProperty("jdk.tls.stapling.responderURI");
+        String uriStr = GetPropertyAction
+                .privilegedGetProperty("jdk.tls.stapling.responderURI");
         URI tmpURI;
         try {
             tmpURI = ((uriStr != null && !uriStr.isEmpty()) ?
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu May 05 19:11:09 2016 +0000
@@ -728,6 +728,7 @@
                     provClass = Class.forName(provName);
                 }
 
+                @SuppressWarnings("deprecation")
                 Object obj = provClass.newInstance();
                 if (!(obj instanceof Provider)) {
                     MessageFormat form = new MessageFormat
--- a/src/java.base/share/classes/sun/security/util/Debug.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/util/Debug.java	Thu May 05 19:11:09 2016 +0000
@@ -43,10 +43,10 @@
     private static String args;
 
     static {
-        args = GetPropertyAction.getProperty("java.security.debug");
+        args = GetPropertyAction.privilegedGetProperty("java.security.debug");
 
-        String args2 =
-                GetPropertyAction.getProperty("java.security.auth.debug");
+        String args2 = GetPropertyAction
+                .privilegedGetProperty("java.security.auth.debug");
 
         if (args == null) {
             args = args2;
--- a/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java	Thu May 05 19:11:09 2016 +0000
@@ -196,8 +196,9 @@
         // A new keystore is always created in the primary keystore format
         if (stream == null) {
             try {
-                keystore = primaryKeyStore.newInstance();
-
+                @SuppressWarnings("deprecation")
+                KeyStoreSpi tmp = primaryKeyStore.newInstance();
+                keystore = tmp;
             } catch (InstantiationException | IllegalAccessException e) {
                 // can safely ignore
             }
@@ -214,7 +215,9 @@
             bufferedStream.mark(Integer.MAX_VALUE);
 
             try {
-                keystore = primaryKeyStore.newInstance();
+                @SuppressWarnings("deprecation")
+                KeyStoreSpi tmp = primaryKeyStore.newInstance();
+                keystore = tmp;
                 type = primaryType;
                 keystore.engineLoad(bufferedStream, password);
 
@@ -232,7 +235,9 @@
                         throw e;
                     }
 
-                    keystore = secondaryKeyStore.newInstance();
+                    @SuppressWarnings("deprecation")
+                    KeyStoreSpi tmp= secondaryKeyStore.newInstance();
+                    keystore = tmp;
                     type = secondaryType;
                     bufferedStream.reset();
                     keystore.engineLoad(bufferedStream, password);
@@ -284,7 +289,9 @@
         boolean result = false;
 
         try {
-            keystore = primaryKeyStore.newInstance();
+            @SuppressWarnings("deprecation")
+            KeyStoreSpi tmp = primaryKeyStore.newInstance();
+            keystore = tmp;
             type = primaryType;
             result = keystore.engineProbe(stream);
 
--- a/src/java.base/share/classes/sun/security/x509/X509Key.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/security/x509/X509Key.java	Thu May 05 19:11:09 2016 +0000
@@ -255,11 +255,10 @@
                 }
             }
 
-            Object      inst = null;
+            @SuppressWarnings("deprecation")
+            Object      inst = (keyClass != null) ? keyClass.newInstance() : null;
             X509Key     result;
 
-            if (keyClass != null)
-                inst = keyClass.newInstance();
             if (inst instanceof X509Key) {
                 result = (X509Key) inst;
                 result.algid = algid;
--- a/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java	Thu May 05 19:11:09 2016 +0000
@@ -157,8 +157,9 @@
             cal = LocalGregorianCalendar.getLocalGregorianCalendar(calendarName);
         } else {
             try {
-                Class<?> cl = Class.forName(className);
-                cal = (CalendarSystem) cl.newInstance();
+                @SuppressWarnings("deprecation")
+                Object tmp = Class.forName(className).newInstance();
+                cal = (CalendarSystem) tmp;
             } catch (Exception e) {
                 throw new InternalError(e);
             }
--- a/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java	Thu May 05 19:11:09 2016 +0000
@@ -144,7 +144,7 @@
 
         // Append an era to the predefined eras if it's given by the property.
         String prop = GetPropertyAction
-                .getProperty("jdk.calendar.japanese.supplemental.era");
+                .privilegedGetProperty("jdk.calendar.japanese.supplemental.era");
         if (prop != null) {
             Era era = parseEraEntry(prop);
             if (era != null) {
--- a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java	Thu May 05 19:11:09 2016 +0000
@@ -246,7 +246,7 @@
 
     static {
         String oldmapping = GetPropertyAction
-                .getProperty("sun.timezone.ids.oldmapping", "false")
+                .privilegedGetProperty("sun.timezone.ids.oldmapping", "false")
                 .toLowerCase(Locale.ROOT);
         USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Thu May 05 19:11:09 2016 +0000
@@ -116,7 +116,7 @@
         adapterCache = new ConcurrentHashMap<>();
 
     static {
-        String order = GetPropertyAction.getProperty("java.locale.providers");
+        String order = GetPropertyAction.privilegedGetProperty("java.locale.providers");
         List<Type> typeList = new ArrayList<>();
 
         // Check user specified adapter preference
@@ -171,8 +171,9 @@
             if (cached == null) {
                 try {
                     // lazily load adapters here
-                    adapter = (LocaleProviderAdapter)Class.forName(type.getAdapterClassName())
-                        .newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object tmp = Class.forName(type.getAdapterClassName()).newInstance();
+                    adapter = (LocaleProviderAdapter)tmp;
                     cached = adapterInstances.putIfAbsent(type, adapter);
                     if (cached != null) {
                         adapter = cached;
--- a/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java	Thu May 05 19:11:09 2016 +0000
@@ -73,7 +73,7 @@
         try {
             return AccessController.doPrivileged(new PrivilegedExceptionAction<P>() {
                 @Override
-                @SuppressWarnings("unchecked")
+                @SuppressWarnings(value={"unchecked", "deprecation"})
                 public P run() {
                     P delegate = null;
 
--- a/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Thu May 05 19:11:09 2016 +0000
@@ -42,7 +42,7 @@
         super(provider, dir);
 
         // check os.version
-        String osversion = GetPropertyAction.getProperty("os.version");
+        String osversion = GetPropertyAction.privilegedGetProperty("os.version");
         String[] vers = Util.split(osversion, '.');
         assert vers.length >= 2;
         int majorVersion = Integer.parseInt(vers[0]);
--- a/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -85,7 +85,7 @@
     @Override
     FileTypeDetector getFileTypeDetector() {
         Path userMimeTypes = Paths.get(
-            GetPropertyAction.getProperty("user.home"), ".mime.types");
+            GetPropertyAction.privilegedGetProperty("user.home"), ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
         return chain(new GioFileTypeDetector(),
--- a/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -94,6 +94,7 @@
                     return 0;
                 }
                 start = now;
+                a.dp_timeout = remaining;
             }
         } else {
             return res;
--- a/src/java.base/unix/classes/java/io/UnixFileSystem.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/java/io/UnixFileSystem.java	Thu May 05 19:11:09 2016 +0000
@@ -36,7 +36,7 @@
     private final String javaHome;
 
     public UnixFileSystem() {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         slash = props.getProperty("file.separator").charAt(0);
         colon = props.getProperty("path.separator").charAt(0);
         javaHome = props.getProperty("java.home");
--- a/src/java.base/unix/classes/java/lang/ProcessImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -125,7 +125,7 @@
         }
 
         String helperPath() {
-            Properties props = GetPropertyAction.getProperties();
+            Properties props = GetPropertyAction.privilegedGetProperties();
             return helperPath(props.getProperty("java.home"),
                               props.getProperty("os.arch"));
         }
@@ -159,7 +159,7 @@
         }
 
         static Platform get() {
-            String osName = GetPropertyAction.getProperty("os.name");
+            String osName = GetPropertyAction.privilegedGetProperty("os.name");
 
             if (osName.equals("Linux")) { return LINUX; }
             if (osName.contains("OS X")) { return BSD; }
--- a/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -40,7 +40,7 @@
     static {
         String prefix = null;
         try {
-            prefix = GetPropertyAction.getProperty("impl.prefix", null);
+            prefix = GetPropertyAction.privilegedGetProperty("impl.prefix");
             if (prefix != null)
                 prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
         } catch (Exception e) {
@@ -61,7 +61,9 @@
         throws SocketException {
         if (prefixImplClass != null) {
             try {
-                return (DatagramSocketImpl)prefixImplClass.newInstance();
+                @SuppressWarnings("deprecation")
+                DatagramSocketImpl result = (DatagramSocketImpl)prefixImplClass.newInstance();
+                return result;
             } catch (Exception e) {
                 throw new SocketException("can't instantiate DatagramSocketImpl");
             }
--- a/src/java.base/unix/classes/sun/net/NetHooks.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/net/NetHooks.java	Thu May 05 19:11:09 2016 +0000
@@ -28,9 +28,6 @@
 import java.net.InetAddress;
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import sun.security.action.GetPropertyAction;
 
 /**
  * Defines static methods to be invoked prior to binding or connecting TCP sockets.
--- a/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -55,8 +55,9 @@
     private PrintStream log;
 
     public SdpProvider() {
+        Properties props = GetPropertyAction.privilegedGetProperties();
         // if this property is not defined then there is nothing to do.
-        String file = GetPropertyAction.getProperty("com.sun.sdp.conf");
+        String file = props.getProperty("com.sun.sdp.conf");
         if (file == null) {
             this.enabled = false;
             this.rules = null;
@@ -65,17 +66,15 @@
 
         // load configuration file
         List<Rule> list = null;
-        if (file != null) {
-            try {
-                list = loadRulesFromFile(file);
-            } catch (IOException e) {
-                fail("Error reading %s: %s", file, e.getMessage());
-            }
+        try {
+            list = loadRulesFromFile(file);
+        } catch (IOException e) {
+            fail("Error reading %s: %s", file, e.getMessage());
         }
 
         // check if debugging is enabled
         PrintStream out = null;
-        String logfile = GetPropertyAction.getProperty("com.sun.sdp.debug");
+        String logfile = props.getProperty("com.sun.sdp.debug");
         if (logfile != null) {
             out = System.out;
             if (logfile.length() > 0) {
--- a/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu May 05 19:11:09 2016 +0000
@@ -76,7 +76,7 @@
     private String hostname;
     /* Domain to use if not specified by user */
     private static String defaultDomain =
-            GetPropertyAction.getProperty("http.auth.ntlm.domain", "");
+            GetPropertyAction.privilegedGetProperty("http.auth.ntlm.domain", "");
 
     public static boolean supportsTransparentAuth () {
         return false;
@@ -141,7 +141,7 @@
         password = pw.getPassword();
         init0();
         try {
-            String version = GetPropertyAction.getProperty("ntlm.version");
+            String version = GetPropertyAction.privilegedGetProperty("ntlm.version");
             client = new Client(version, hostname, username, ntdomain, password);
         } catch (NTLMException ne) {
             try {
--- a/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -48,7 +48,9 @@
             throw new AssertionError(x);
         }
         try {
-            return c.newInstance();
+            @SuppressWarnings("deprecation")
+            AsynchronousChannelProvider result = c.newInstance();
+            return result;
         } catch (IllegalAccessException | InstantiationException x) {
             throw new AssertionError(x);
         }
@@ -59,7 +61,7 @@
      * Returns the default AsynchronousChannelProvider.
      */
     public static AsynchronousChannelProvider create() {
-        String osname = GetPropertyAction.getProperty("os.name");
+        String osname = GetPropertyAction.privilegedGetProperty("os.name");
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.ch.SolarisAsynchronousChannelProvider");
         if (osname.equals("Linux"))
--- a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -46,8 +46,8 @@
 
     private static final boolean disableSynchronousRead;
     static {
-        String propValue = GetPropertyAction
-                .getProperty("sun.nio.ch.disableSynchronousRead", "false");
+        String propValue = GetPropertyAction.privilegedGetProperty(
+            "sun.nio.ch.disableSynchronousRead", "false");
         disableSynchronousRead = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
     }
--- a/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Thu May 05 19:11:09 2016 +0000
@@ -44,7 +44,9 @@
             throw new AssertionError(x);
         }
         try {
-            return c.newInstance();
+            @SuppressWarnings("deprecation")
+            FileSystemProvider result = c.newInstance();
+            return result;
         } catch (IllegalAccessException | InstantiationException x) {
             throw new AssertionError(x);
         }
@@ -54,7 +56,7 @@
      * Returns the default FileSystemProvider.
      */
     public static FileSystemProvider create() {
-        String osname = GetPropertyAction.getProperty("os.name");
+        String osname = GetPropertyAction.privilegedGetProperty("os.name");
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.fs.SolarisFileSystemProvider");
         if (osname.equals("Linux"))
--- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java	Thu May 05 19:11:09 2016 +0000
@@ -57,7 +57,7 @@
         // process working directory then paths must be resolved against the
         // default directory.
         String propValue = GetPropertyAction
-                .getProperty("sun.nio.fs.chdirAllowed", "false");
+                .privilegedGetProperty("sun.nio.fs.chdirAllowed", "false");
         boolean chdirAllowed = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
         if (chdirAllowed) {
--- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java	Thu May 05 19:11:09 2016 +0000
@@ -42,7 +42,7 @@
     private final char semicolon;
 
     public WinNTFileSystem() {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         slash = props.getProperty("file.separator").charAt(0);
         semicolon = props.getProperty("path.separator").charAt(0);
         altSlash = (this.slash == '\\') ? '/' : '\\';
--- a/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu May 05 19:11:09 2016 +0000
@@ -56,7 +56,7 @@
     static {
         Class<?> prefixImplClassLocal = null;
 
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         preferIPv4Stack = Boolean.parseBoolean(
                 props.getProperty("java.net.preferIPv4Stack"));
 
@@ -90,7 +90,9 @@
         throws SocketException {
         if (prefixImplClass != null) {
             try {
-                return (DatagramSocketImpl) prefixImplClass.newInstance();
+                @SuppressWarnings("deprecation")
+                Object result = prefixImplClass.newInstance();
+                return (DatagramSocketImpl) result;
             } catch (Exception e) {
                 throw new SocketException("can't instantiate DatagramSocketImpl");
             }
--- a/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu May 05 19:11:09 2016 +0000
@@ -53,8 +53,8 @@
     private static String defaultDomain; /* Domain to use if not specified by user */
 
     static {
-        defaultDomain = GetPropertyAction.getProperty("http.auth.ntlm.domain",
-                                                      "domain");
+        defaultDomain = GetPropertyAction
+                .privilegedGetProperty("http.auth.ntlm.domain", "domain");
     };
 
     private void init0() {
--- a/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Thu May 05 19:11:09 2016 +0000
@@ -120,7 +120,7 @@
 
     static boolean isFastFileTransferRequested() {
         String fileTransferProp = GetPropertyAction
-                .getProperty("jdk.nio.enableFastFileTransfer");
+                .privilegedGetProperty("jdk.nio.enableFastFileTransfer");
         boolean enable;
         if ("".equals(fileTransferProp)) {
             enable = true;
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Thu May 05 19:11:09 2016 +0000
@@ -114,8 +114,8 @@
     // indicates if accurate metadata is required (interesting on NTFS only)
     private static final boolean ensureAccurateMetadata;
     static {
-        String propValue = GetPropertyAction
-                .getProperty("sun.nio.fs.ensureAccurateMetadata", "false");
+        String propValue = GetPropertyAction.privilegedGetProperty(
+            "sun.nio.fs.ensureAccurateMetadata", "false");
         ensureAccurateMetadata = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
     }
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,12 +25,15 @@
 
 package sun.lwawt.macosx;
 
+import sun.lwawt.LWWindowPeer;
+
 import java.awt.*;
 import java.beans.*;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.util.*;
 import java.util.concurrent.Callable;
+import sun.awt.AWTAccessor;
 
 import javax.accessibility.*;
 import javax.swing.*;
@@ -421,6 +424,8 @@
     }
 
     public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) {
+        if (a == null) return null;
+
         return invokeAndWait(new Callable<AccessibleAction>() {
             public AccessibleAction call() throws Exception {
                 final AccessibleContext ac = a.getAccessibleContext();
@@ -667,4 +672,28 @@
             }
         }, c);
     }
+
+    /**
+     * @return AWTView ptr, a peer of the CPlatformView associated with the toplevel container of the Accessible, if any
+     */
+    private static long getAWTView(Accessible a) {
+        Accessible ax = CAccessible.getSwingAccessible(a);
+        if (!(ax instanceof Component)) return 0;
+
+        return invokeAndWait(new Callable<Long>() {
+            public Long call() throws Exception {
+                Component cont = (Component) ax;
+                while (cont != null && !(cont instanceof Window)) {
+                    cont = cont.getParent();
+                }
+                if (cont != null) {
+                    LWWindowPeer peer = (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(cont);
+                    if (peer != null) {
+                        return ((CPlatformWindow) peer.getPlatformWindow()).getContentView().getAWTView();
+                    }
+                }
+                return 0L;
+            }
+        }, (Component)ax);
+    }
 }
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -264,6 +264,8 @@
                 final double localY = boundsUnion.getY();
 
                 final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
+                if (componentLocation == null) return ret;
+
                 final double screenX = componentLocation.getX() + localX;
                 final double screenY = componentLocation.getY() + localY;
 
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.h	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.h	Thu May 05 19:11:09 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -62,6 +62,8 @@
 - (void) deliverJavaMouseEvent: (NSEvent *) event;
 - (jobject) awtComponent:(JNIEnv *)env;
 
++ (AWTView *) awtView:(JNIEnv *)env ofAccessible:(jobject)jaccessible;
+
 // Input method-related events
 - (void)setInputMethod:(jobject)inputMethod;
 - (void)abandonInput;
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Thu May 05 17:35:48 2016 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Thu May 05 19:11:09 2016 +0000
@@ -29,6 +29,7 @@
 #import "AWTWindow.h"
 #import "JavaComponentAccessibility.h"
 #import "JavaTextAccessibility.h"
+#import "JavaAccessibilityUtilities.h"
 #import "GeomUtilities.h"
 #import "OSVersion.h"
 #import "ThreadUtilities.h"
@@ -129,7 +130,7 @@
     self.cglLayer = nil;
     
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
-    (*env)->DeleteGlobalRef(env, m_cPlatformView);
+    (*env)->DeleteWeakGlobalRef(env, m_cPlatformView);
     m_cPlatformView = NULL;
     
     if (fInputMethodLOCKABLE != NULL)
@@ -396,7 +397,11 @@
     
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
     static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
-    JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
+    jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
+    if (!(*env)->IsSameObject(env, jlocal, NULL)) {
+        JNFCallVoidMethod(env, jlocal, jm_deliverMouseEvent, jEvent);
+        (*env)->DeleteLocalRef(env, jlocal);
+    }
     (*env)->DeleteLocalRef(env, jEvent);
 }
 </