14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import sun.misc.Unsafe;
29 import java.lang.reflect.Method;
30 import java.util.Arrays;
31 import sun.invoke.util.VerifyAccess;
32 import static java.lang.invoke.MethodHandleNatives.Constants.*;
33 import static java.lang.invoke.LambdaForm.*;
34 import static java.lang.invoke.MethodTypeForm.*;
35 import static java.lang.invoke.MethodHandleStatics.*;
36 import java.lang.ref.WeakReference;
37 import java.lang.reflect.Field;
38 import sun.invoke.util.ValueConversions;
39 import sun.invoke.util.VerifyType;
40 import sun.invoke.util.Wrapper;
41
42 /**
43 * The flavor of method handle which implements a constant reference
44 * to a class member.
45 * @author jrose
46 */
47 class DirectMethodHandle extends MethodHandle {
48 final MemberName member;
49
50 // Constructors and factory methods in this class *must* be package scoped or private.
51 private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
52 super(mtype, form);
53 if (!member.isResolved()) throw new InternalError();
129 return new DirectMethodHandle(mt, lf, member);
130 }
131
132 @Override
133 String internalProperties() {
134 return "/DMH="+member.toString();
135 }
136
137 //// Implementation methods.
138 @Override
139 MethodHandle viewAsType(MethodType newType) {
140 return new DirectMethodHandle(newType, form, member);
141 }
142 @Override
143 @ForceInline
144 MemberName internalMemberName() {
145 return member;
146 }
147
148 @Override
149 MethodHandle bindArgument(int pos, char basicType, Object value) {
150 // If the member needs dispatching, do so.
151 if (pos == 0 && basicType == 'L') {
152 DirectMethodHandle concrete = maybeRebind(value);
153 if (concrete != null)
154 return concrete.bindReceiver(value);
155 }
156 return super.bindArgument(pos, basicType, value);
157 }
158
159 @Override
160 MethodHandle bindReceiver(Object receiver) {
161 // If the member needs dispatching, do so.
162 DirectMethodHandle concrete = maybeRebind(receiver);
163 if (concrete != null)
164 return concrete.bindReceiver(receiver);
165 return super.bindReceiver(receiver);
166 }
167
168 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
169
170 private DirectMethodHandle maybeRebind(Object receiver) {
171 if (receiver != null) {
257 assert(names.length == nameCursor);
258 if (doesAlloc) {
259 // names = { argx,y,z,... new C, init method }
260 names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
261 names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
262 } else if (needsInit) {
263 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
264 } else {
265 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
266 }
267 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
268 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
269 int result = LambdaForm.LAST_RESULT;
270 if (doesAlloc) {
271 assert(outArgs[outArgs.length-2] == names[NEW_OBJ]); // got to move this one
272 System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
273 outArgs[0] = names[NEW_OBJ];
274 result = NEW_OBJ;
275 }
276 names[LINKER_CALL] = new Name(linker, outArgs);
277 lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
278 LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
279 // This is a tricky bit of code. Don't send it through the LF interpreter.
280 lform.compileToBytecode();
281 return lform;
282 }
283
284 private static void maybeCompile(LambdaForm lform, MemberName m) {
285 if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
286 // Help along bootstrapping...
287 lform.compileToBytecode();
288 }
289
290 /** Static wrapper for DirectMethodHandle.internalMemberName. */
291 @ForceInline
292 /*non-public*/ static Object internalMemberName(Object mh) {
293 return ((DirectMethodHandle)mh).member;
294 }
295
296 /** Static wrapper for DirectMethodHandle.internalMemberName.
297 * This one also forces initialization.
|
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import sun.misc.Unsafe;
29 import java.lang.reflect.Method;
30 import java.util.Arrays;
31 import sun.invoke.util.VerifyAccess;
32 import static java.lang.invoke.MethodHandleNatives.Constants.*;
33 import static java.lang.invoke.LambdaForm.*;
34 import static java.lang.invoke.LambdaForm.BasicType.*;
35 import static java.lang.invoke.MethodTypeForm.*;
36 import static java.lang.invoke.MethodHandleStatics.*;
37 import java.lang.ref.WeakReference;
38 import java.lang.reflect.Field;
39 import sun.invoke.util.ValueConversions;
40 import sun.invoke.util.VerifyType;
41 import sun.invoke.util.Wrapper;
42
43 /**
44 * The flavor of method handle which implements a constant reference
45 * to a class member.
46 * @author jrose
47 */
48 class DirectMethodHandle extends MethodHandle {
49 final MemberName member;
50
51 // Constructors and factory methods in this class *must* be package scoped or private.
52 private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
53 super(mtype, form);
54 if (!member.isResolved()) throw new InternalError();
130 return new DirectMethodHandle(mt, lf, member);
131 }
132
133 @Override
134 String internalProperties() {
135 return "/DMH="+member.toString();
136 }
137
138 //// Implementation methods.
139 @Override
140 MethodHandle viewAsType(MethodType newType) {
141 return new DirectMethodHandle(newType, form, member);
142 }
143 @Override
144 @ForceInline
145 MemberName internalMemberName() {
146 return member;
147 }
148
149 @Override
150 MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
151 // If the member needs dispatching, do so.
152 if (pos == 0 && basicType == L_TYPE) {
153 DirectMethodHandle concrete = maybeRebind(value);
154 if (concrete != null)
155 return concrete.bindReceiver(value);
156 }
157 return super.bindArgument(pos, basicType, value);
158 }
159
160 @Override
161 MethodHandle bindReceiver(Object receiver) {
162 // If the member needs dispatching, do so.
163 DirectMethodHandle concrete = maybeRebind(receiver);
164 if (concrete != null)
165 return concrete.bindReceiver(receiver);
166 return super.bindReceiver(receiver);
167 }
168
169 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
170
171 private DirectMethodHandle maybeRebind(Object receiver) {
172 if (receiver != null) {
258 assert(names.length == nameCursor);
259 if (doesAlloc) {
260 // names = { argx,y,z,... new C, init method }
261 names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
262 names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
263 } else if (needsInit) {
264 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
265 } else {
266 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
267 }
268 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
269 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
270 int result = LambdaForm.LAST_RESULT;
271 if (doesAlloc) {
272 assert(outArgs[outArgs.length-2] == names[NEW_OBJ]); // got to move this one
273 System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
274 outArgs[0] = names[NEW_OBJ];
275 result = NEW_OBJ;
276 }
277 names[LINKER_CALL] = new Name(linker, outArgs);
278 lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
279 LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
280 // This is a tricky bit of code. Don't send it through the LF interpreter.
281 lform.compileToBytecode();
282 return lform;
283 }
284
285 private static void maybeCompile(LambdaForm lform, MemberName m) {
286 if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
287 // Help along bootstrapping...
288 lform.compileToBytecode();
289 }
290
291 /** Static wrapper for DirectMethodHandle.internalMemberName. */
292 @ForceInline
293 /*non-public*/ static Object internalMemberName(Object mh) {
294 return ((DirectMethodHandle)mh).member;
295 }
296
297 /** Static wrapper for DirectMethodHandle.internalMemberName.
298 * This one also forces initialization.
|