提交 50959a7f 编写于 作者: V vlivanov

8057657: Annotate LambdaForm parameters with types

Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
上级 84c4c1ae
...@@ -138,7 +138,8 @@ import jdk.internal.org.objectweb.asm.Type; ...@@ -138,7 +138,8 @@ import jdk.internal.org.objectweb.asm.Type;
*/ */
static BoundMethodHandle makeReinvoker(MethodHandle target) { static BoundMethodHandle makeReinvoker(MethodHandle target) {
LambdaForm form = DelegatingMethodHandle.makeReinvokerForm( LambdaForm form = DelegatingMethodHandle.makeReinvokerForm(
target, MethodTypeForm.LF_REBIND, Species_L.SPECIES_DATA.getterFunction(0) ); target, MethodTypeForm.LF_REBIND,
Species_L.SPECIES_DATA, Species_L.SPECIES_DATA.getterFunction(0));
return Species_L.make(target.type(), form, target); return Species_L.make(target.type(), form, target);
} }
......
...@@ -85,12 +85,13 @@ abstract class DelegatingMethodHandle extends MethodHandle { ...@@ -85,12 +85,13 @@ abstract class DelegatingMethodHandle extends MethodHandle {
private static LambdaForm chooseDelegatingForm(MethodHandle target) { private static LambdaForm chooseDelegatingForm(MethodHandle target) {
if (target instanceof SimpleMethodHandle) if (target instanceof SimpleMethodHandle)
return target.internalForm(); // no need for an indirection return target.internalForm(); // no need for an indirection
return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, NF_getTarget); return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget);
} }
/** 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,
NamedFunction getTargetFn) { NamedFunction getTargetFn) {
MethodType mtype = target.type().basicType(); MethodType mtype = target.type().basicType();
boolean customized = (whichCache < 0 || boolean customized = (whichCache < 0 ||
...@@ -108,6 +109,7 @@ abstract class DelegatingMethodHandle extends MethodHandle { ...@@ -108,6 +109,7 @@ abstract class DelegatingMethodHandle extends MethodHandle {
final int REINVOKE = nameCursor++; final int REINVOKE = nameCursor++;
LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
assert(names.length == nameCursor); assert(names.length == nameCursor);
names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint);
Object[] targetArgs; Object[] targetArgs;
if (customized) { if (customized) {
targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class);
......
...@@ -260,7 +260,9 @@ class Invokers { ...@@ -260,7 +260,9 @@ class Invokers {
: Arrays.asList(mtype, customized, which, nameCursor, names.length); : Arrays.asList(mtype, customized, which, nameCursor, names.length);
if (MTYPE_ARG >= INARG_LIMIT) { if (MTYPE_ARG >= INARG_LIMIT) {
assert(names[MTYPE_ARG] == null); assert(names[MTYPE_ARG] == null);
NamedFunction getter = BoundMethodHandle.speciesData_L().getterFunction(0); BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
NamedFunction getter = speciesData.getterFunction(0);
names[MTYPE_ARG] = new Name(getter, names[THIS_MH]); names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
// else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM) // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
} }
......
...@@ -460,6 +460,11 @@ class LambdaForm { ...@@ -460,6 +460,11 @@ class LambdaForm {
return param; return param;
} }
/** Report the N-th argument type constraint. */
Object parameterConstraint(int n) {
return parameter(n).constraint;
}
/** Report the arity. */ /** Report the arity. */
int arity() { int arity() {
return arity; return arity;
...@@ -1421,6 +1426,7 @@ class LambdaForm { ...@@ -1421,6 +1426,7 @@ class LambdaForm {
final BasicType type; final BasicType type;
private short index; private short index;
final NamedFunction function; final NamedFunction function;
final Object constraint; // additional type information, if not null
@Stable final Object[] arguments; @Stable final Object[] arguments;
private Name(int index, BasicType type, NamedFunction function, Object[] arguments) { private Name(int index, BasicType type, NamedFunction function, Object[] arguments) {
...@@ -1428,8 +1434,18 @@ class LambdaForm { ...@@ -1428,8 +1434,18 @@ class LambdaForm {
this.type = type; this.type = type;
this.function = function; this.function = function;
this.arguments = arguments; this.arguments = arguments;
this.constraint = null;
assert(this.index == index); assert(this.index == index);
} }
private Name(Name that, Object constraint) {
this.index = that.index;
this.type = that.type;
this.function = that.function;
this.arguments = that.arguments;
this.constraint = constraint;
assert(constraint == null || isParam()); // only params have constraints
assert(constraint == null || constraint instanceof BoundMethodHandle.SpeciesData || constraint instanceof Class);
}
Name(MethodHandle function, Object... arguments) { Name(MethodHandle function, Object... arguments) {
this(new NamedFunction(function), arguments); this(new NamedFunction(function), arguments);
} }
...@@ -1477,7 +1493,11 @@ class LambdaForm { ...@@ -1477,7 +1493,11 @@ class LambdaForm {
} }
Name cloneWithIndex(int i) { Name cloneWithIndex(int i) {
Object[] newArguments = (arguments == null) ? null : arguments.clone(); Object[] newArguments = (arguments == null) ? null : arguments.clone();
return new Name(i, type, function, newArguments); return new Name(i, type, function, newArguments).withConstraint(constraint);
}
Name withConstraint(Object constraint) {
if (constraint == this.constraint) return this;
return new Name(this, constraint);
} }
Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly
if (oldName == newName) return this; if (oldName == newName) return this;
...@@ -1557,7 +1577,12 @@ class LambdaForm { ...@@ -1557,7 +1577,12 @@ class LambdaForm {
return (function == null) ? s : s + "=" + exprString(); return (function == null) ? s : s + "=" + exprString();
} }
public String paramString() { public String paramString() {
return toString(); String s = toString();
Object c = constraint;
if (c == null)
return s;
if (c instanceof Class) c = ((Class<?>)c).getSimpleName();
return s + "/" + c;
} }
public String exprString() { public String exprString() {
if (function == null) return toString(); if (function == null) return toString();
...@@ -1679,6 +1704,7 @@ class LambdaForm { ...@@ -1679,6 +1704,7 @@ class LambdaForm {
static Name internArgument(Name n) { static Name internArgument(Name n) {
assert(n.isParam()) : "not param: " + n; assert(n.isParam()) : "not param: " + n;
assert(n.index < INTERNED_ARGUMENT_LIMIT); assert(n.index < INTERNED_ARGUMENT_LIMIT);
if (n.constraint != null) return n;
return argument(n.index, n.type); return argument(n.index, n.type);
} }
static Name[] arguments(int extra, String types) { static Name[] arguments(int extra, String types) {
......
...@@ -710,6 +710,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -710,6 +710,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType); Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL(); BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
names[THIS_MH] = names[THIS_MH].withConstraint(data);
names[GET_TARGET] = new Name(data.getterFunction(0), names[THIS_MH]); names[GET_TARGET] = new Name(data.getterFunction(0), names[THIS_MH]);
names[GET_CLASS] = new Name(data.getterFunction(1), names[THIS_MH]); names[GET_CLASS] = new Name(data.getterFunction(1), names[THIS_MH]);
names[GET_CATCHER] = new Name(data.getterFunction(2), names[THIS_MH]); names[GET_CATCHER] = new Name(data.getterFunction(2), names[THIS_MH]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册