86 if (target instanceof SimpleMethodHandle) |
90 if (target instanceof SimpleMethodHandle) |
87 return target.internalForm(); // no need for an indirection |
91 return target.internalForm(); // no need for an indirection |
88 return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget); |
92 return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget); |
89 } |
93 } |
90 |
94 |
|
95 static LambdaForm makeReinvokerForm(MethodHandle target, |
|
96 int whichCache, |
|
97 Object constraint, |
|
98 NamedFunction getTargetFn) { |
|
99 String debugString; |
|
100 switch(whichCache) { |
|
101 case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; |
|
102 case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; |
|
103 default: debugString = "MH.reinvoke"; break; |
|
104 } |
|
105 // No pre-action needed. |
|
106 return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); |
|
107 } |
91 /** Create a LF which simply reinvokes a target of the given basic type. */ |
108 /** Create a LF which simply reinvokes a target of the given basic type. */ |
92 static LambdaForm makeReinvokerForm(MethodHandle target, |
109 static LambdaForm makeReinvokerForm(MethodHandle target, |
93 int whichCache, |
110 int whichCache, |
94 Object constraint, |
111 Object constraint, |
95 NamedFunction getTargetFn) { |
112 String debugString, |
|
113 boolean forceInline, |
|
114 NamedFunction getTargetFn, |
|
115 NamedFunction preActionFn) { |
96 MethodType mtype = target.type().basicType(); |
116 MethodType mtype = target.type().basicType(); |
97 boolean customized = (whichCache < 0 || |
117 boolean customized = (whichCache < 0 || |
98 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); |
118 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); |
|
119 boolean hasPreAction = (preActionFn != null); |
99 LambdaForm form; |
120 LambdaForm form; |
100 if (!customized) { |
121 if (!customized) { |
101 form = mtype.form().cachedLambdaForm(whichCache); |
122 form = mtype.form().cachedLambdaForm(whichCache); |
102 if (form != null) return form; |
123 if (form != null) return form; |
103 } |
124 } |
104 final int THIS_DMH = 0; |
125 final int THIS_DMH = 0; |
105 final int ARG_BASE = 1; |
126 final int ARG_BASE = 1; |
106 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); |
127 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); |
107 int nameCursor = ARG_LIMIT; |
128 int nameCursor = ARG_LIMIT; |
|
129 final int PRE_ACTION = hasPreAction ? nameCursor++ : -1; |
108 final int NEXT_MH = customized ? -1 : nameCursor++; |
130 final int NEXT_MH = customized ? -1 : nameCursor++; |
109 final int REINVOKE = nameCursor++; |
131 final int REINVOKE = nameCursor++; |
110 LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
132 LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
111 assert(names.length == nameCursor); |
133 assert(names.length == nameCursor); |
112 names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint); |
134 names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint); |
113 Object[] targetArgs; |
135 Object[] targetArgs; |
|
136 if (hasPreAction) { |
|
137 names[PRE_ACTION] = new LambdaForm.Name(preActionFn, names[THIS_DMH]); |
|
138 } |
114 if (customized) { |
139 if (customized) { |
115 targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); |
140 targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); |
116 names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself |
141 names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself |
117 } else { |
142 } else { |
118 names[NEXT_MH] = new LambdaForm.Name(getTargetFn, names[THIS_DMH]); |
143 names[NEXT_MH] = new LambdaForm.Name(getTargetFn, names[THIS_DMH]); |
119 targetArgs = Arrays.copyOfRange(names, THIS_DMH, ARG_LIMIT, Object[].class); |
144 targetArgs = Arrays.copyOfRange(names, THIS_DMH, ARG_LIMIT, Object[].class); |
120 targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH |
145 targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH |
121 names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); |
146 names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); |
122 } |
147 } |
123 String debugString; |
148 form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); |
124 switch(whichCache) { |
|
125 case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; |
|
126 case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; |
|
127 default: debugString = "MH.reinvoke"; break; |
|
128 } |
|
129 form = new LambdaForm(debugString, ARG_LIMIT, names); |
|
130 if (!customized) { |
149 if (!customized) { |
131 form = mtype.form().setCachedLambdaForm(whichCache, form); |
150 form = mtype.form().setCachedLambdaForm(whichCache, form); |
132 } |
151 } |
133 return form; |
152 return form; |
134 } |
153 } |
135 |
154 |
136 private static final NamedFunction NF_getTarget; |
155 static final NamedFunction NF_getTarget; |
137 static { |
156 static { |
138 try { |
157 try { |
139 NF_getTarget = new NamedFunction(DelegatingMethodHandle.class |
158 NF_getTarget = new NamedFunction(DelegatingMethodHandle.class |
140 .getDeclaredMethod("getTarget")); |
159 .getDeclaredMethod("getTarget")); |
141 } catch (ReflectiveOperationException ex) { |
160 } catch (ReflectiveOperationException ex) { |