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