240 mtypeWithArg = mtypeWithArg
241 .insertParameterTypes(0, Object.class) // insert newly allocated obj
242 .changeReturnType(void.class); // <init> returns void
243 MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
244 try {
245 linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
246 } catch (ReflectiveOperationException ex) {
247 throw newInternalError(ex);
248 }
249 final int DMH_THIS = 0;
250 final int ARG_BASE = 1;
251 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
252 int nameCursor = ARG_LIMIT;
253 final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
254 final int GET_MEMBER = nameCursor++;
255 final int LINKER_CALL = nameCursor++;
256 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
257 assert(names.length == nameCursor);
258 if (doesAlloc) {
259 // names = { argx,y,z,... new C, init method }
260 names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
261 names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
262 } else if (needsInit) {
263 names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
264 } else {
265 names[GET_MEMBER] = new Name(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))
620 if (!isStatic)
621 mtype = mtype.insertParameterTypes(0, Object.class);
622 final int DMH_THIS = 0;
623 final int ARG_BASE = 1;
624 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
625 // if this is for non-static access, the base pointer is stored at this index:
626 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
627 // if this is for write access, the value to be written is stored at this index:
628 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
629 int nameCursor = ARG_LIMIT;
630 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
631 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
632 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
633 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
634 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
635 final int LINKER_CALL = nameCursor++;
636 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
637 final int RESULT = nameCursor-1; // either the call or the cast
638 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
639 if (needsInit)
640 names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
641 if (needsCast && !isGetter)
642 names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
643 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
644 assert(outArgs.length == (isGetter ? 3 : 4));
645 outArgs[0] = UNSAFE;
646 if (isStatic) {
647 outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
648 outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
649 } else {
650 outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
651 outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]);
652 }
653 if (!isGetter) {
654 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
655 }
656 for (Object a : outArgs) assert(a != null);
657 names[LINKER_CALL] = new Name(linker, outArgs);
658 if (needsCast && isGetter)
659 names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
660 for (Name n : names) assert(n != null);
661 String fieldOrStatic = (isStatic ? "Static" : "Field");
662 String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
663 if (needsCast) lambdaName += "Cast";
664 if (needsInit) lambdaName += "Init";
665 return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
666 }
667
668 private static final NamedFunction
669 NF_internalMemberName,
670 NF_internalMemberNameEnsureInit,
671 NF_ensureInitialized,
672 NF_fieldOffset,
673 NF_checkBase,
674 NF_staticBase,
675 NF_staticOffset,
676 NF_checkCast,
677 NF_allocateInstance,
678 NF_constructorMethod;
679 static {
680 try {
681 NamedFunction nfs[] = {
682 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
683 .getDeclaredMethod("internalMemberName", Object.class)),
684 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
685 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
686 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
687 .getDeclaredMethod("ensureInitialized", Object.class)),
688 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
692 NF_staticBase = new NamedFunction(DirectMethodHandle.class
693 .getDeclaredMethod("staticBase", Object.class)),
694 NF_staticOffset = new NamedFunction(DirectMethodHandle.class
695 .getDeclaredMethod("staticOffset", Object.class)),
696 NF_checkCast = new NamedFunction(DirectMethodHandle.class
697 .getDeclaredMethod("checkCast", Object.class, Object.class)),
698 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
699 .getDeclaredMethod("allocateInstance", Object.class)),
700 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
701 .getDeclaredMethod("constructorMethod", Object.class))
702 };
703 for (NamedFunction nf : nfs) {
704 // Each nf must be statically invocable or we get tied up in our bootstraps.
705 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
706 nf.resolve();
707 }
708 } catch (ReflectiveOperationException ex) {
709 throw newInternalError(ex);
710 }
711 }
712 }
|
240 mtypeWithArg = mtypeWithArg
241 .insertParameterTypes(0, Object.class) // insert newly allocated obj
242 .changeReturnType(void.class); // <init> returns void
243 MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
244 try {
245 linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
246 } catch (ReflectiveOperationException ex) {
247 throw newInternalError(ex);
248 }
249 final int DMH_THIS = 0;
250 final int ARG_BASE = 1;
251 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
252 int nameCursor = ARG_LIMIT;
253 final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
254 final int GET_MEMBER = nameCursor++;
255 final int LINKER_CALL = nameCursor++;
256 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
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))
620 if (!isStatic)
621 mtype = mtype.insertParameterTypes(0, Object.class);
622 final int DMH_THIS = 0;
623 final int ARG_BASE = 1;
624 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
625 // if this is for non-static access, the base pointer is stored at this index:
626 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
627 // if this is for write access, the value to be written is stored at this index:
628 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
629 int nameCursor = ARG_LIMIT;
630 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
631 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
632 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
633 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
634 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
635 final int LINKER_CALL = nameCursor++;
636 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
637 final int RESULT = nameCursor-1; // either the call or the cast
638 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
639 if (needsInit)
640 names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
641 if (needsCast && !isGetter)
642 names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
643 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
644 assert(outArgs.length == (isGetter ? 3 : 4));
645 outArgs[0] = UNSAFE;
646 if (isStatic) {
647 outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
648 outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
649 } else {
650 outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
651 outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
652 }
653 if (!isGetter) {
654 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
655 }
656 for (Object a : outArgs) assert(a != null);
657 names[LINKER_CALL] = new Name(linker, outArgs);
658 if (needsCast && isGetter)
659 names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
660 for (Name n : names) assert(n != null);
661 String fieldOrStatic = (isStatic ? "Static" : "Field");
662 String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
663 if (needsCast) lambdaName += "Cast";
664 if (needsInit) lambdaName += "Init";
665 return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
666 }
667
668 /**
669 * Pre-initialized NamedFunctions for bootstrapping purposes.
670 * Factored in an inner class to delay initialization until first usage.
671 */
672 private static class Lazy {
673 static final NamedFunction
674 NF_internalMemberName,
675 NF_internalMemberNameEnsureInit,
676 NF_ensureInitialized,
677 NF_fieldOffset,
678 NF_checkBase,
679 NF_staticBase,
680 NF_staticOffset,
681 NF_checkCast,
682 NF_allocateInstance,
683 NF_constructorMethod;
684 static {
685 try {
686 NamedFunction nfs[] = {
687 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
688 .getDeclaredMethod("internalMemberName", Object.class)),
689 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
690 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
691 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
692 .getDeclaredMethod("ensureInitialized", Object.class)),
693 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
697 NF_staticBase = new NamedFunction(DirectMethodHandle.class
698 .getDeclaredMethod("staticBase", Object.class)),
699 NF_staticOffset = new NamedFunction(DirectMethodHandle.class
700 .getDeclaredMethod("staticOffset", Object.class)),
701 NF_checkCast = new NamedFunction(DirectMethodHandle.class
702 .getDeclaredMethod("checkCast", Object.class, Object.class)),
703 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
704 .getDeclaredMethod("allocateInstance", Object.class)),
705 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
706 .getDeclaredMethod("constructorMethod", Object.class))
707 };
708 for (NamedFunction nf : nfs) {
709 // Each nf must be statically invocable or we get tied up in our bootstraps.
710 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
711 nf.resolve();
712 }
713 } catch (ReflectiveOperationException ex) {
714 throw newInternalError(ex);
715 }
716 }
717 }
718 }
|