207 mtypeWithArg = mtypeWithArg
208 .insertParameterTypes(0, Object.class) // insert newly allocated obj
209 .changeReturnType(void.class); // <init> returns void
210 MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
211 try {
212 linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
213 } catch (ReflectiveOperationException ex) {
214 throw newInternalError(ex);
215 }
216 final int DMH_THIS = 0;
217 final int ARG_BASE = 1;
218 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
219 int nameCursor = ARG_LIMIT;
220 final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
221 final int GET_MEMBER = nameCursor++;
222 final int LINKER_CALL = nameCursor++;
223 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
224 assert(names.length == nameCursor);
225 if (doesAlloc) {
226 // names = { argx,y,z,... new C, init method }
227 names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
228 names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
229 } else if (needsInit) {
230 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
231 } else {
232 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
233 }
234 assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
235 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
236 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
237 int result = LAST_RESULT;
238 if (doesAlloc) {
239 assert(outArgs[outArgs.length-2] == names[NEW_OBJ]); // got to move this one
240 System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
241 outArgs[0] = names[NEW_OBJ];
242 result = NEW_OBJ;
243 }
244 names[LINKER_CALL] = new Name(linker, outArgs);
245 lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
246 LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
247 // This is a tricky bit of code. Don't send it through the LF interpreter.
248 lform.compileToBytecode();
249 return lform;
250 }
251
252 static Object findDirectMethodHandle(Name name) {
253 if (name.function == Lazy.NF_internalMemberName ||
254 name.function == Lazy.NF_internalMemberNameEnsureInit ||
255 name.function == Lazy.NF_constructorMethod) {
256 assert(name.arguments.length == 1);
257 return name.arguments[0];
258 }
259 return null;
260 }
261
262 private static void maybeCompile(LambdaForm lform, MemberName m) {
263 if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
264 // Help along bootstrapping...
265 lform.compileToBytecode();
266 }
267
268 /** Static wrapper for DirectMethodHandle.internalMemberName. */
269 @ForceInline
270 /*non-public*/ static Object internalMemberName(Object mh) {
271 return ((DirectMethodHandle)mh).member;
272 }
273
274 /** Static wrapper for DirectMethodHandle.internalMemberName.
275 * This one also forces initialization.
596 if (!isStatic)
597 mtype = mtype.insertParameterTypes(0, Object.class);
598 final int DMH_THIS = 0;
599 final int ARG_BASE = 1;
600 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
601 // if this is for non-static access, the base pointer is stored at this index:
602 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
603 // if this is for write access, the value to be written is stored at this index:
604 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
605 int nameCursor = ARG_LIMIT;
606 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
607 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
608 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
609 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
610 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
611 final int LINKER_CALL = nameCursor++;
612 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
613 final int RESULT = nameCursor-1; // either the call or the cast
614 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
615 if (needsInit)
616 names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
617 if (needsCast && !isGetter)
618 names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
619 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
620 assert(outArgs.length == (isGetter ? 3 : 4));
621 outArgs[0] = UNSAFE;
622 if (isStatic) {
623 outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
624 outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
625 } else {
626 outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
627 outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
628 }
629 if (!isGetter) {
630 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
631 }
632 for (Object a : outArgs) assert(a != null);
633 names[LINKER_CALL] = new Name(linker, outArgs);
634 if (needsCast && isGetter)
635 names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
636 for (Name n : names) assert(n != null);
637 String fieldOrStatic = (isStatic ? "Static" : "Field");
638 String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
639 if (needsCast) lambdaName += "Cast";
640 if (needsInit) lambdaName += "Init";
641 return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
642 }
643
644 /**
645 * Pre-initialized NamedFunctions for bootstrapping purposes.
646 * Factored in an inner class to delay initialization until first usage.
647 */
648 private static class Lazy {
649 static final NamedFunction
650 NF_internalMemberName,
651 NF_internalMemberNameEnsureInit,
652 NF_ensureInitialized,
653 NF_fieldOffset,
654 NF_checkBase,
655 NF_staticBase,
656 NF_staticOffset,
657 NF_checkCast,
658 NF_allocateInstance,
659 NF_constructorMethod;
660 static {
661 try {
662 NamedFunction nfs[] = {
663 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
664 .getDeclaredMethod("internalMemberName", Object.class)),
665 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
666 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
667 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
668 .getDeclaredMethod("ensureInitialized", Object.class)),
669 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
670 .getDeclaredMethod("fieldOffset", Object.class)),
671 NF_checkBase = new NamedFunction(DirectMethodHandle.class
672 .getDeclaredMethod("checkBase", Object.class)),
673 NF_staticBase = new NamedFunction(DirectMethodHandle.class
674 .getDeclaredMethod("staticBase", Object.class)),
675 NF_staticOffset = new NamedFunction(DirectMethodHandle.class
676 .getDeclaredMethod("staticOffset", Object.class)),
677 NF_checkCast = new NamedFunction(DirectMethodHandle.class
678 .getDeclaredMethod("checkCast", Object.class, Object.class)),
679 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
680 .getDeclaredMethod("allocateInstance", Object.class)),
681 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
682 .getDeclaredMethod("constructorMethod", Object.class))
683 };
684 for (NamedFunction nf : nfs) {
685 // Each nf must be statically invocable or we get tied up in our bootstraps.
686 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
687 nf.resolve();
688 }
689 } catch (ReflectiveOperationException ex) {
690 throw newInternalError(ex);
691 }
692 }
693 }
694 }
|
207 mtypeWithArg = mtypeWithArg
208 .insertParameterTypes(0, Object.class) // insert newly allocated obj
209 .changeReturnType(void.class); // <init> returns void
210 MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
211 try {
212 linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
213 } catch (ReflectiveOperationException ex) {
214 throw newInternalError(ex);
215 }
216 final int DMH_THIS = 0;
217 final int ARG_BASE = 1;
218 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
219 int nameCursor = ARG_LIMIT;
220 final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
221 final int GET_MEMBER = nameCursor++;
222 final int LINKER_CALL = nameCursor++;
223 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
224 assert(names.length == nameCursor);
225 if (doesAlloc) {
226 // names = { argx,y,z,... new C, init method }
227 names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
228 names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
229 } else if (needsInit) {
230 names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
231 } else {
232 names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
233 }
234 assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
235 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
236 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
237 int result = LAST_RESULT;
238 if (doesAlloc) {
239 assert(outArgs[outArgs.length-2] == names[NEW_OBJ]); // got to move this one
240 System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
241 outArgs[0] = names[NEW_OBJ];
242 result = NEW_OBJ;
243 }
244 names[LINKER_CALL] = new Name(linker, outArgs);
245 lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
246 LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
247 // This is a tricky bit of code. Don't send it through the LF interpreter.
248 lform.compileToBytecode();
249 return lform;
250 }
251
252 static Object findDirectMethodHandle(Name name) {
253 if (name.function == NF_internalMemberName ||
254 name.function == NF_internalMemberNameEnsureInit ||
255 name.function == NF_constructorMethod) {
256 assert(name.arguments.length == 1);
257 return name.arguments[0];
258 }
259 return null;
260 }
261
262 private static void maybeCompile(LambdaForm lform, MemberName m) {
263 if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
264 // Help along bootstrapping...
265 lform.compileToBytecode();
266 }
267
268 /** Static wrapper for DirectMethodHandle.internalMemberName. */
269 @ForceInline
270 /*non-public*/ static Object internalMemberName(Object mh) {
271 return ((DirectMethodHandle)mh).member;
272 }
273
274 /** Static wrapper for DirectMethodHandle.internalMemberName.
275 * This one also forces initialization.
596 if (!isStatic)
597 mtype = mtype.insertParameterTypes(0, Object.class);
598 final int DMH_THIS = 0;
599 final int ARG_BASE = 1;
600 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
601 // if this is for non-static access, the base pointer is stored at this index:
602 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
603 // if this is for write access, the value to be written is stored at this index:
604 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
605 int nameCursor = ARG_LIMIT;
606 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
607 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
608 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
609 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
610 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
611 final int LINKER_CALL = nameCursor++;
612 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
613 final int RESULT = nameCursor-1; // either the call or the cast
614 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
615 if (needsInit)
616 names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
617 if (needsCast && !isGetter)
618 names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
619 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
620 assert(outArgs.length == (isGetter ? 3 : 4));
621 outArgs[0] = UNSAFE;
622 if (isStatic) {
623 outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
624 outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
625 } else {
626 outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
627 outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]);
628 }
629 if (!isGetter) {
630 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
631 }
632 for (Object a : outArgs) assert(a != null);
633 names[LINKER_CALL] = new Name(linker, outArgs);
634 if (needsCast && isGetter)
635 names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
636 for (Name n : names) assert(n != null);
637 String fieldOrStatic = (isStatic ? "Static" : "Field");
638 String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
639 if (needsCast) lambdaName += "Cast";
640 if (needsInit) lambdaName += "Init";
641 return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
642 }
643
644 /**
645 * Pre-initialized NamedFunctions for bootstrapping purposes.
646 * Factored in an inner class to delay initialization until first usage.
647 */
648 static final NamedFunction
649 NF_internalMemberName,
650 NF_internalMemberNameEnsureInit,
651 NF_ensureInitialized,
652 NF_fieldOffset,
653 NF_checkBase,
654 NF_staticBase,
655 NF_staticOffset,
656 NF_checkCast,
657 NF_allocateInstance,
658 NF_constructorMethod;
659 static {
660 try {
661 NamedFunction nfs[] = {
662 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
663 .getDeclaredMethod("internalMemberName", Object.class)),
664 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
665 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
666 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
667 .getDeclaredMethod("ensureInitialized", Object.class)),
668 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
669 .getDeclaredMethod("fieldOffset", Object.class)),
670 NF_checkBase = new NamedFunction(DirectMethodHandle.class
671 .getDeclaredMethod("checkBase", Object.class)),
672 NF_staticBase = new NamedFunction(DirectMethodHandle.class
673 .getDeclaredMethod("staticBase", Object.class)),
674 NF_staticOffset = new NamedFunction(DirectMethodHandle.class
675 .getDeclaredMethod("staticOffset", Object.class)),
676 NF_checkCast = new NamedFunction(DirectMethodHandle.class
677 .getDeclaredMethod("checkCast", Object.class, Object.class)),
678 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
679 .getDeclaredMethod("allocateInstance", Object.class)),
680 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
681 .getDeclaredMethod("constructorMethod", Object.class))
682 };
683 // Each nf must be statically invocable or we get tied up in our bootstraps.
684 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
685 } catch (ReflectiveOperationException ex) {
686 throw newInternalError(ex);
687 }
688 }
689 }
|