8175233: Remove LambdaForm.debugName
authorredestad
Wed, 22 Feb 2017 11:03:33 +0100
changeset 43893 0e72a2804a0c
parent 43892 065331fc590e
child 43894 c316ff1ea2c7
8175233: Remove LambdaForm.debugName Reviewed-by: vlivanov, psandoz, jrose
jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java
jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java
jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormBuffer.java
jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java
jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Wed Feb 22 11:03:33 2017 +0100
@@ -98,21 +98,17 @@
                                         Object constraint,
                                         NamedFunction getTargetFn) {
         // No pre-action needed.
-        return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null);
+        return makeReinvokerForm(target, whichCache, constraint, true, getTargetFn, null);
     }
     /** Create a LF which simply reinvokes a target of the given basic type. */
     static LambdaForm makeReinvokerForm(MethodHandle target,
                                         int whichCache,
                                         Object constraint,
-                                        String debugString,
                                         boolean forceInline,
                                         NamedFunction getTargetFn,
                                         NamedFunction preActionFn) {
         MethodType mtype = target.type().basicType();
         Kind kind = whichKind(whichCache);
-        if (debugString == null) {
-            debugString = kind.defaultLambdaName;
-        }
         boolean customized = (whichCache < 0 ||
                 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY);
         boolean hasPreAction = (preActionFn != null);
@@ -144,7 +140,7 @@
             targetArgs[0] = names[NEXT_MH];  // overwrite this MH with next MH
             names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs);
         }
-        form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind);
+        form = new LambdaForm(ARG_LIMIT, names, forceInline, kind);
         if (!customized) {
             form = mtype.form().setCachedLambdaForm(whichCache, form);
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Wed Feb 22 11:03:33 2017 +0100
@@ -242,8 +242,7 @@
             result = NEW_OBJ;
         }
         names[LINKER_CALL] = new Name(linker, outArgs);
-        String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype));
-        LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind);
+        LambdaForm lform = new LambdaForm(ARG_LIMIT, names, result, kind);
 
         // This is a tricky bit of code.  Don't send it through the LF interpreter.
         lform.compileToBytecode();
@@ -696,22 +695,33 @@
         if (needsCast && isGetter)
             names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
         for (Name n : names)  assert(n != null);
-        // add some detail to the lambdaForm debugname,
-        // significant only for debugging
-        StringBuilder nameBuilder = new StringBuilder(kind.methodName);
-        if (isStatic) {
-            nameBuilder.append("Static");
-        } else {
-            nameBuilder.append("Field");
-        }
-        if (needsCast)  nameBuilder.append("Cast");
-        if (needsInit)  nameBuilder.append("Init");
+
+        LambdaForm form;
         if (needsCast || needsInit) {
             // can't use the pre-generated form when casting and/or initializing
-            return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
+            form = new LambdaForm(ARG_LIMIT, names, RESULT);
         } else {
-            return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT, kind);
+            form = new LambdaForm(ARG_LIMIT, names, RESULT, kind);
         }
+
+        if (LambdaForm.debugNames()) {
+            // add some detail to the lambdaForm debugname,
+            // significant only for debugging
+            StringBuilder nameBuilder = new StringBuilder(kind.methodName);
+            if (isStatic) {
+                nameBuilder.append("Static");
+            } else {
+                nameBuilder.append("Field");
+            }
+            if (needsCast) {
+                nameBuilder.append("Cast");
+            }
+            if (needsInit) {
+                nameBuilder.append("Init");
+            }
+            LambdaForm.associateWithDebugName(form, nameBuilder.toString());
+        }
+        return form;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Feb 22 11:03:33 2017 +0100
@@ -130,7 +130,7 @@
 
     /** For generating customized code for a single LambdaForm. */
     private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
-        this(className, form.debugName, form, invokerType);
+        this(className, form.lambdaName(), form, invokerType);
     }
 
     /** For generating customized code for a single LambdaForm. */
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Wed Feb 22 11:03:33 2017 +0100
@@ -132,7 +132,7 @@
         MethodType mtype = targetType;
         MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
 
-        LambdaForm lform = varHandleMethodInvokerHandleForm(ak.methodName(), mtype, isExact);
+        LambdaForm lform = varHandleMethodInvokerHandleForm(ak, mtype, isExact);
         VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
         MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
 
@@ -325,9 +325,9 @@
         }
         names[LINKER_CALL] = new Name(outCallType, outArgs);
         if (customized) {
-            lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names);
+            lform = new LambdaForm(INARG_LIMIT, names);
         } else {
-            lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names, kind);
+            lform = new LambdaForm(INARG_LIMIT, names, kind);
         }
         if (isLinker)
             lform.compileToBytecode();  // JVM needs a real methodOop
@@ -337,11 +337,10 @@
     }
 
 
-    static MemberName varHandleInvokeLinkerMethod(String name,
-                                                  MethodType mtype) {
+    static MemberName varHandleInvokeLinkerMethod(VarHandle.AccessMode ak, MethodType mtype) {
         LambdaForm lform;
         if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
-            lform = varHandleMethodGenericLinkerHandleForm(name, mtype);
+            lform = varHandleMethodGenericLinkerHandleForm(ak, mtype);
         } else {
             // TODO
             throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount());
@@ -349,7 +348,8 @@
         return lform.vmentry;
     }
 
-    private static LambdaForm varHandleMethodGenericLinkerHandleForm(String name, MethodType mtype) {
+    private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.AccessMode ak,
+            MethodType mtype) {
         // TODO Cache form?
 
         final int THIS_VH      = 0;
@@ -383,14 +383,18 @@
         MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
                 .basicType();
         names[LINKER_CALL] = new Name(outCallType, outArgs);
-        LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)),
-                                          ARG_LIMIT + 1, names);
-
+        LambdaForm lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
+        if (LambdaForm.debugNames()) {
+            String name = ak.methodName() + ":VarHandle_invoke_MT_" +
+                    shortenSignature(basicTypeSignature(mtype));
+            LambdaForm.associateWithDebugName(lform, name);
+        }
         lform.compileToBytecode();
         return lform;
     }
 
-    private static LambdaForm varHandleMethodInvokerHandleForm(String name, MethodType mtype, boolean isExact) {
+    private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode ak,
+            MethodType mtype, boolean isExact) {
         // TODO Cache form?
 
         final int THIS_MH      = 0;
@@ -429,10 +433,14 @@
         MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
                 .basicType();
         names[LINKER_CALL] = new Name(outCallType, outArgs);
-        String debugName = isExact ? ":VarHandle_exactInvoker" : ":VarHandle_invoker";
-        LambdaForm lform = new LambdaForm(name + debugName + shortenSignature(basicTypeSignature(mtype)),
-                                          ARG_LIMIT, names);
-
+        Kind kind = isExact ? VARHANDLE_EXACT_INVOKER : VARHANDLE_INVOKER;
+        LambdaForm lform = new LambdaForm(ARG_LIMIT, names, kind);
+        if (LambdaForm.debugNames()) {
+            String name = ak.methodName() +
+                    (isExact ? ":VarHandle_exactInvoker_" : ":VarHandle_invoker_") +
+                    shortenSignature(basicTypeSignature(mtype));
+            LambdaForm.associateWithDebugName(lform, name);
+        }
         lform.prepare();
         return lform;
     }
@@ -543,7 +551,8 @@
         System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
         outArgs[PREPEND_MH] = names[CALL_MH];
         names[LINKER_CALL] = new Name(mtype, outArgs);
-        lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names);
+        lform = new LambdaForm(INARG_LIMIT, names,
+                (skipCallSite ? LINK_TO_TARGET_METHOD : LINK_TO_CALL_SITE));
         lform.compileToBytecode();  // JVM needs a real methodOop
         lform = mtype.form().setCachedLambdaForm(which, lform);
         return lform;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Wed Feb 22 11:03:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,7 +126,6 @@
     final boolean forceInline;
     final MethodHandle customized;
     @Stable final Name[] names;
-    final String debugName;
     final Kind kind;
     MemberName vmentry;   // low-level behavior, or null if not yet prepared
     private boolean isCompiled;
@@ -268,7 +267,7 @@
     }
 
     enum Kind {
-        GENERIC(""),
+        GENERIC("invoke"),
         ZERO("zero"),
         IDENTITY("identity"),
         BOUND_REINVOKER("BMH.reinvoke"),
@@ -278,6 +277,8 @@
         EXACT_INVOKER("MH.exactInvoker"),
         GENERIC_LINKER("MH.invoke_MT"),
         GENERIC_INVOKER("MH.invoker"),
+        LINK_TO_TARGET_METHOD("linkToTargetMethod"),
+        LINK_TO_CALL_SITE("linkToCallSite"),
         DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
         DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
         DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
@@ -319,7 +320,18 @@
         GET_DOUBLE("getDouble"),
         PUT_DOUBLE("putDouble"),
         GET_DOUBLE_VOLATILE("getDoubleVolatile"),
-        PUT_DOUBLE_VOLATILE("putDoubleVolatile");
+        PUT_DOUBLE_VOLATILE("putDoubleVolatile"),
+        TRY_FINALLY("tryFinally"),
+        COLLECT("collect"),
+        CONVERT("convert"),
+        SPREAD("spread"),
+        LOOP("loop"),
+        FIELD("field"),
+        GUARD("guard"),
+        GUARD_WITH_CATCH("guardWithCatch"),
+        VARHANDLE_EXACT_INVOKER("VH.exactInvoker"),
+        VARHANDLE_INVOKER("VH.invoker"),
+        VARHANDLE_LINKER("VH.invoke_MT");
 
         final String defaultLambdaName;
         final String methodName;
@@ -335,25 +347,20 @@
         }
     }
 
-    LambdaForm(String debugName,
-               int arity, Name[] names, int result) {
-        this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
+    LambdaForm(int arity, Name[] names, int result) {
+        this(arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names, int result, Kind kind) {
-        this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind);
+    LambdaForm(int arity, Name[] names, int result, Kind kind) {
+        this(arity, names, result, /*forceInline=*/true, /*customized=*/null, kind);
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) {
-        this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC);
+    LambdaForm(int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) {
+        this(arity, names, result, forceInline, customized, Kind.GENERIC);
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) {
+    LambdaForm(int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) {
         assert(namesOK(arity, names));
         this.arity = arity;
         this.result = fixResult(result, names);
         this.names = names.clone();
-        this.debugName = fixDebugName(debugName);
         this.forceInline = forceInline;
         this.customized = customized;
         this.kind = kind;
@@ -364,31 +371,23 @@
             compileToBytecode();
         }
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names) {
-        this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
+    LambdaForm(int arity, Name[] names) {
+        this(arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names, Kind kind) {
-        this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, kind);
+    LambdaForm(int arity, Name[] names, Kind kind) {
+        this(arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, kind);
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names, boolean forceInline) {
-        this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
+    LambdaForm(int arity, Name[] names, boolean forceInline) {
+        this(arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
     }
-    LambdaForm(String debugName,
-               int arity, Name[] names, boolean forceInline, Kind kind) {
-        this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind);
+    LambdaForm(int arity, Name[] names, boolean forceInline, Kind kind) {
+        this(arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind);
     }
-    LambdaForm(String debugName,
-               Name[] formals, Name[] temps, Name result) {
-        this(debugName,
-             formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
+    LambdaForm(Name[] formals, Name[] temps, Name result) {
+        this(formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
     }
-    LambdaForm(String debugName,
-               Name[] formals, Name[] temps, Name result, boolean forceInline) {
-        this(debugName,
-             formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline, /*customized=*/null);
+    LambdaForm(Name[] formals, Name[] temps, Name result, boolean forceInline) {
+        this(formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline, /*customized=*/null);
     }
 
     private static Name[] buildNames(Name[] formals, Name[] temps, Name result) {
@@ -408,10 +407,9 @@
         this.arity = mt.parameterCount();
         this.result = (mt.returnType() == void.class || mt.returnType() == Void.class) ? -1 : arity;
         this.names = buildEmptyNames(arity, mt, result == -1);
-        this.debugName = "LF.zero";
         this.forceInline = true;
         this.customized = null;
-        this.kind = Kind.GENERIC;
+        this.kind = Kind.ZERO;
         assert(nameRefsAreLegal());
         assert(isEmpty());
         String sig = null;
@@ -436,36 +434,46 @@
         return result;
     }
 
-    private static String fixDebugName(String debugName) {
-        if (DEBUG_NAME_COUNTERS != null) {
-            int under = debugName.indexOf('_');
-            int length = debugName.length();
-            if (under < 0)  under = length;
-            String debugNameStem = debugName.substring(0, under);
-            Integer ctr;
-            synchronized (DEBUG_NAME_COUNTERS) {
-                ctr = DEBUG_NAME_COUNTERS.get(debugNameStem);
-                if (ctr == null)  ctr = 0;
-                DEBUG_NAME_COUNTERS.put(debugNameStem, ctr+1);
+    static boolean debugNames() {
+        return DEBUG_NAME_COUNTERS != null;
+    }
+
+    static void associateWithDebugName(LambdaForm form, String name) {
+        assert (debugNames());
+        synchronized (DEBUG_NAMES) {
+            DEBUG_NAMES.put(form, name);
+        }
+    }
+
+    String lambdaName() {
+        if (DEBUG_NAMES != null) {
+            synchronized (DEBUG_NAMES) {
+                String name = DEBUG_NAMES.get(this);
+                if (name == null) {
+                    name = generateDebugName();
+                }
+                return name;
             }
-            StringBuilder buf = new StringBuilder(debugNameStem);
-            buf.append('_');
-            int leadingZero = buf.length();
-            buf.append((int) ctr);
-            for (int i = buf.length() - leadingZero; i < 3; i++)
-                buf.insert(leadingZero, '0');
-            if (under < length) {
-                ++under;    // skip "_"
-                while (under < length && Character.isDigit(debugName.charAt(under))) {
-                    ++under;
-                }
-                if (under < length && debugName.charAt(under) == '_')  ++under;
-                if (under < length)
-                    buf.append('_').append(debugName, under, length);
-            }
-            return buf.toString();
         }
-        return debugName;
+        return kind.defaultLambdaName;
+    }
+
+    private String generateDebugName() {
+        assert (debugNames());
+        String debugNameStem = kind.defaultLambdaName;
+        Integer ctr = DEBUG_NAME_COUNTERS.getOrDefault(debugNameStem, 0);
+        DEBUG_NAME_COUNTERS.put(debugNameStem, ctr + 1);
+        StringBuilder buf = new StringBuilder(debugNameStem);
+        int leadingZero = buf.length();
+        buf.append((int) ctr);
+        for (int i = buf.length() - leadingZero; i < 3; i++) {
+            buf.insert(leadingZero, '0');
+        }
+        buf.append('_');
+        buf.append(basicTypeSignature());
+        String name = buf.toString();
+        associateWithDebugName(this, name);
+        return name;
     }
 
     private static boolean namesOK(int arity, Name[] names) {
@@ -482,7 +490,7 @@
 
     /** Customize LambdaForm for a particular MethodHandle */
     LambdaForm customize(MethodHandle mh) {
-        LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind);
+        LambdaForm customForm = new LambdaForm(arity, names, result, forceInline, mh, kind);
         if (COMPILE_THRESHOLD >= 0 && isCompiled) {
             // If shared LambdaForm has been compiled, compile customized version as well.
             customForm.compileToBytecode();
@@ -1030,7 +1038,8 @@
     }
 
     public String toString() {
-        StringBuilder buf = new StringBuilder(debugName+"=Lambda(");
+        String lambdaName = lambdaName();
+        StringBuilder buf = new StringBuilder(lambdaName + "=Lambda(");
         for (int i = 0; i < names.length; i++) {
             if (i == arity)  buf.append(")=>{");
             Name n = names[i];
@@ -1742,7 +1751,7 @@
         // bootstrap dependency on this method in case we're interpreting LFs
         if (isVoid) {
             Name[] idNames = new Name[] { argument(0, L_TYPE) };
-            idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT, Kind.IDENTITY);
+            idForm = new LambdaForm(1, idNames, VOID_RESULT, Kind.IDENTITY);
             idForm.compileToBytecode();
             idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
 
@@ -1750,14 +1759,14 @@
             zeFun = idFun;
         } else {
             Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
-            idForm = new LambdaForm(idMem.getName(), 2, idNames, 1, Kind.IDENTITY);
+            idForm = new LambdaForm(2, idNames, 1, Kind.IDENTITY);
             idForm.compileToBytecode();
             idFun = new NamedFunction(idMem, MethodHandleImpl.makeIntrinsic(
                     idMem.getInvocationType(), idForm, MethodHandleImpl.Intrinsic.IDENTITY));
 
             Object zeValue = Wrapper.forBasicType(btChar).zero();
             Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
-            zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1, Kind.ZERO);
+            zeForm = new LambdaForm(1, zeNames, 1, Kind.ZERO);
             zeForm.compileToBytecode();
             zeFun = new NamedFunction(zeMem, MethodHandleImpl.makeIntrinsic(
                     zeMem.getInvocationType(), zeForm, MethodHandleImpl.Intrinsic.ZERO));
@@ -1805,11 +1814,15 @@
     }
 
     private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS;
+    private static final HashMap<LambdaForm,String> DEBUG_NAMES;
     static {
-        if (debugEnabled())
+        if (debugEnabled()) {
             DEBUG_NAME_COUNTERS = new HashMap<>();
-        else
+            DEBUG_NAMES = new HashMap<>();
+        } else {
             DEBUG_NAME_COUNTERS = null;
+            DEBUG_NAMES = null;
+        }
     }
 
     static {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormBuffer.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormBuffer.java	Wed Feb 22 11:03:33 2017 +0100
@@ -40,7 +40,6 @@
     private byte flags;
     private int firstChange;
     private Name resultName;
-    private String debugName;
     private ArrayList<Name> dups;
 
     private static final int F_TRANS = 0x10, F_OWNED = 0x03;
@@ -50,15 +49,15 @@
         setNames(lf.names);
         int result = lf.result;
         if (result == LAST_RESULT)  result = length - 1;
-        if (result >= 0 && lf.names[result].type != V_TYPE)
+        if (result >= 0 && lf.names[result].type != V_TYPE) {
             resultName = lf.names[result];
-        debugName = lf.debugName;
+        }
         assert(lf.nameRefsAreLegal());
     }
 
     private LambdaForm lambdaForm() {
         assert(!inTrans());  // need endEdit call to tidy things up
-        return new LambdaForm(debugName, arity, nameArray(), resultIndex());
+        return new LambdaForm(arity, nameArray(), resultIndex());
     }
 
     Name name(int i) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Wed Feb 22 11:03:33 2017 +0100
@@ -915,7 +915,7 @@
             }
         }
 
-        form = new LambdaForm(lambdaForm.debugName, arity2, names2, result2);
+        form = new LambdaForm(arity2, names2, result2);
         return putInCache(key, form);
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Feb 22 11:03:33 2017 +0100
@@ -399,7 +399,7 @@
             assert(RETURN_CONV == names.length-1);
         }
 
-        LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names, RESULT);
+        LambdaForm form = new LambdaForm(lambdaType.parameterCount(), names, RESULT, Kind.CONVERT);
         return SimpleMethodHandle.make(srcType, form);
     }
 
@@ -608,7 +608,7 @@
         }
         names[names.length - 1] = new Name(target, (Object[]) targetArgs);
 
-        LambdaForm form = new LambdaForm("spread", lambdaType.parameterCount(), names);
+        LambdaForm form = new LambdaForm(lambdaType.parameterCount(), names, Kind.SPREAD);
         return SimpleMethodHandle.make(srcType, form);
     }
 
@@ -676,7 +676,7 @@
         assert(inputArgPos + chunk == collectNamePos);  // use of rest of input args also
         names[targetNamePos] = new Name(target, (Object[]) targetArgs);
 
-        LambdaForm form = new LambdaForm("collect", lambdaType.parameterCount(), names);
+        LambdaForm form = new LambdaForm(lambdaType.parameterCount(), names, Kind.COLLECT);
         return SimpleMethodHandle.make(srcType, form);
     }
 
@@ -774,7 +774,7 @@
             @Override
             public LambdaForm apply(MethodHandle target) {
                 return DelegatingMethodHandle.makeReinvokerForm(target,
-                                   MethodTypeForm.LF_DELEGATE_BLOCK_INLINING, CountingWrapper.class, "reinvoker.dontInline", false,
+                                   MethodTypeForm.LF_DELEGATE_BLOCK_INLINING, CountingWrapper.class, false,
                                    DelegatingMethodHandle.NF_getTarget, CountingWrapper.NF_maybeStopCounting);
             }
         };
@@ -943,7 +943,7 @@
         invokeArgs[0] = names[SELECT_ALT];
         names[CALL_TARGET] = new Name(basicType, invokeArgs);
 
-        lform = new LambdaForm("guard", lambdaType.parameterCount(), names, /*forceInline=*/true);
+        lform = new LambdaForm(lambdaType.parameterCount(), names, /*forceInline=*/true, Kind.GUARD);
 
         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);
     }
@@ -1019,7 +1019,7 @@
         Object[] unboxArgs  = new Object[] {names[GET_UNBOX_RESULT], names[TRY_CATCH]};
         names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
 
-        lform = new LambdaForm("guardWithCatch", lambdaType.parameterCount(), names);
+        lform = new LambdaForm(lambdaType.parameterCount(), names, Kind.GUARD_WITH_CATCH);
 
         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform);
     }
@@ -1886,7 +1886,7 @@
             names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
 
             lform = basicType.form().setCachedLambdaForm(MethodTypeForm.LF_LOOP,
-                    new LambdaForm("loop", lambdaType.parameterCount(), names));
+                    new LambdaForm(lambdaType.parameterCount(), names, Kind.LOOP));
         }
 
         // BOXED_ARGS is the index into the names array where the loop idiom starts
@@ -2120,7 +2120,7 @@
         Object[] unboxArgs  = new Object[] {names[GET_UNBOX_RESULT], names[TRY_FINALLY]};
         names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
 
-        lform = new LambdaForm("tryFinally", lambdaType.parameterCount(), names);
+        lform = new LambdaForm(lambdaType.parameterCount(), names, Kind.TRY_FINALLY);
 
         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_TF, lform);
     }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Wed Feb 22 11:03:33 2017 +0100
@@ -471,7 +471,7 @@
             // Fall back to lambda form linkage if guard method is not available
             // TODO Optionally log fallback ?
         }
-        return Invokers.varHandleInvokeLinkerMethod(name, mtype);
+        return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
     }
     static String getVarHandleGuardMethodName(MethodType guardType) {
         String prefix = "guard_";
--- a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java	Wed Feb 22 11:03:33 2017 +0100
@@ -82,9 +82,9 @@
                 throw new Error("Unexpected error: Lambda form of the method handle is null");
             }
 
-            String debugName = (String)DEBUG_NAME.get(lambdaForm);
-            if (debugName != null && debugName.startsWith("identity_")) {
-                // Ignore identity_* LambdaForms.
+            String kind = KIND_FIELD.get(lambdaForm).toString();
+            if (kind.equals("IDENTITY")) {
+                // Ignore identity LambdaForms.
                 return;
             }
 
--- a/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java	Fri Jan 27 13:17:13 2017 -0800
+++ b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java	Wed Feb 22 11:03:33 2017 +0100
@@ -51,7 +51,7 @@
      * used to get a lambda form from a method handle.
      */
     protected static final Method INTERNAL_FORM;
-    protected static final Field DEBUG_NAME;
+    protected static final Field KIND_FIELD;
     protected static final Field REF_FIELD;
     private static final List<GarbageCollectorMXBean> gcInfo;
 
@@ -64,8 +64,8 @@
             INTERNAL_FORM = MethodHandle.class.getDeclaredMethod("internalForm");
             INTERNAL_FORM.setAccessible(true);
 
-            DEBUG_NAME = Class.forName("java.lang.invoke.LambdaForm").getDeclaredField("debugName");
-            DEBUG_NAME.setAccessible(true);
+            KIND_FIELD = Class.forName("java.lang.invoke.LambdaForm").getDeclaredField("kind");
+            KIND_FIELD.setAccessible(true);
 
             REF_FIELD = Reference.class.getDeclaredField("referent");
             REF_FIELD.setAccessible(true);