Mercurial > hg > shenandoah-preopenjdk-archive > openjdk8 > jdk
changeset 9995:c9cc83fba300
8057657: Annotate LambdaForm parameters with types
Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
author | vlivanov |
---|---|
date | Wed, 10 Sep 2014 18:34:03 +0400 |
parents | 4b2bc06d521c |
children | 4a505ea8cc0a |
files | src/share/classes/java/lang/invoke/BoundMethodHandle.java src/share/classes/java/lang/invoke/DelegatingMethodHandle.java src/share/classes/java/lang/invoke/Invokers.java src/share/classes/java/lang/invoke/LambdaForm.java src/share/classes/java/lang/invoke/MethodHandleImpl.java |
diffstat | 5 files changed, 37 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Sep 10 18:34:03 2014 +0400 +++ b/src/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Sep 10 18:34:03 2014 +0400 @@ -138,7 +138,8 @@ */ static BoundMethodHandle makeReinvoker(MethodHandle target) { 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); }
--- a/src/share/classes/java/lang/invoke/DelegatingMethodHandle.java Wed Sep 10 18:34:03 2014 +0400 +++ b/src/share/classes/java/lang/invoke/DelegatingMethodHandle.java Wed Sep 10 18:34:03 2014 +0400 @@ -85,12 +85,13 @@ private static LambdaForm chooseDelegatingForm(MethodHandle target) { if (target instanceof SimpleMethodHandle) 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. */ static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, + Object constraint, NamedFunction getTargetFn) { MethodType mtype = target.type().basicType(); boolean customized = (whichCache < 0 || @@ -108,6 +109,7 @@ final int REINVOKE = nameCursor++; LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); assert(names.length == nameCursor); + names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint); Object[] targetArgs; if (customized) { targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class);
--- a/src/share/classes/java/lang/invoke/Invokers.java Wed Sep 10 18:34:03 2014 +0400 +++ b/src/share/classes/java/lang/invoke/Invokers.java Wed Sep 10 18:34:03 2014 +0400 @@ -260,7 +260,9 @@ : Arrays.asList(mtype, customized, which, nameCursor, names.length); if (MTYPE_ARG >= INARG_LIMIT) { 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]); // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM) }
--- a/src/share/classes/java/lang/invoke/LambdaForm.java Wed Sep 10 18:34:03 2014 +0400 +++ b/src/share/classes/java/lang/invoke/LambdaForm.java Wed Sep 10 18:34:03 2014 +0400 @@ -460,6 +460,11 @@ return param; } + /** Report the N-th argument type constraint. */ + Object parameterConstraint(int n) { + return parameter(n).constraint; + } + /** Report the arity. */ int arity() { return arity; @@ -1421,6 +1426,7 @@ final BasicType type; private short index; final NamedFunction function; + final Object constraint; // additional type information, if not null @Stable final Object[] arguments; private Name(int index, BasicType type, NamedFunction function, Object[] arguments) { @@ -1428,8 +1434,18 @@ this.type = type; this.function = function; this.arguments = arguments; + this.constraint = null; 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) { this(new NamedFunction(function), arguments); } @@ -1477,7 +1493,11 @@ } Name cloneWithIndex(int i) { 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 if (oldName == newName) return this; @@ -1557,7 +1577,12 @@ return (function == null) ? s : s + "=" + exprString(); } 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() { if (function == null) return toString(); @@ -1679,6 +1704,7 @@ static Name internArgument(Name n) { assert(n.isParam()) : "not param: " + n; assert(n.index < INTERNED_ARGUMENT_LIMIT); + if (n.constraint != null) return n; return argument(n.index, n.type); } static Name[] arguments(int extra, String types) {
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Sep 10 18:34:03 2014 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Sep 10 18:34:03 2014 +0400 @@ -710,6 +710,7 @@ Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType); 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_CLASS] = new Name(data.getterFunction(1), names[THIS_MH]); names[GET_CATCHER] = new Name(data.getterFunction(2), names[THIS_MH]);