equal
deleted
inserted
replaced
83 } |
83 } |
84 |
84 |
85 private static LambdaForm chooseDelegatingForm(MethodHandle target) { |
85 private static LambdaForm chooseDelegatingForm(MethodHandle target) { |
86 if (target instanceof SimpleMethodHandle) |
86 if (target instanceof SimpleMethodHandle) |
87 return target.internalForm(); // no need for an indirection |
87 return target.internalForm(); // no need for an indirection |
88 return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, NF_getTarget); |
88 return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget); |
89 } |
89 } |
90 |
90 |
91 /** Create a LF which simply reinvokes a target of the given basic type. */ |
91 /** Create a LF which simply reinvokes a target of the given basic type. */ |
92 static LambdaForm makeReinvokerForm(MethodHandle target, |
92 static LambdaForm makeReinvokerForm(MethodHandle target, |
93 int whichCache, |
93 int whichCache, |
|
94 Object constraint, |
94 NamedFunction getTargetFn) { |
95 NamedFunction getTargetFn) { |
95 MethodType mtype = target.type().basicType(); |
96 MethodType mtype = target.type().basicType(); |
96 boolean customized = (whichCache < 0 || |
97 boolean customized = (whichCache < 0 || |
97 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); |
98 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); |
98 LambdaForm form; |
99 LambdaForm form; |
106 int nameCursor = ARG_LIMIT; |
107 int nameCursor = ARG_LIMIT; |
107 final int NEXT_MH = customized ? -1 : nameCursor++; |
108 final int NEXT_MH = customized ? -1 : nameCursor++; |
108 final int REINVOKE = nameCursor++; |
109 final int REINVOKE = nameCursor++; |
109 LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
110 LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
110 assert(names.length == nameCursor); |
111 assert(names.length == nameCursor); |
|
112 names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint); |
111 Object[] targetArgs; |
113 Object[] targetArgs; |
112 if (customized) { |
114 if (customized) { |
113 targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); |
115 targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); |
114 names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself |
116 names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself |
115 } else { |
117 } else { |