1
25
26 package java.lang.invoke;
27
28 import jdk.internal.misc.Unsafe;
29 import jdk.internal.vm.annotation.ForceInline;
30 import jdk.internal.vm.annotation.Stable;
31 import sun.invoke.util.ValueConversions;
32 import sun.invoke.util.VerifyAccess;
33 import sun.invoke.util.VerifyType;
34 import sun.invoke.util.Wrapper;
35
36 import java.lang.ref.WeakReference;
37 import java.util.Arrays;
38 import java.util.Objects;
39
40 import static java.lang.invoke.LambdaForm.*;
41 import static java.lang.invoke.LambdaForm.Kind.*;
42 import static java.lang.invoke.MethodHandleNatives.Constants.*;
43 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
44 import static java.lang.invoke.MethodHandleStatics.newInternalError;
45 import static java.lang.invoke.MethodTypeForm.*;
46
47
52 class DirectMethodHandle extends MethodHandle {
53 final MemberName member;
54
55
56 private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
57 super(mtype, form);
58 if (!member.isResolved()) throw new InternalError();
59
60 if (member.getDeclaringClass().isInterface() &&
61 member.getReferenceKind() == REF_invokeInterface &&
62 member.isMethod() && !member.isAbstract()) {
63
64 MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
65 m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
66 if (m != null && m.isPublic()) {
67 assert(member.getReferenceKind() == m.getReferenceKind());
68 member = m;
69 }
70 }
71
72 this.member = member;
73 }
74
75
76 static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) {
77 MethodType mtype = member.getMethodOrFieldType();
78 if (!member.isStatic()) {
79 if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor())
80 throw new InternalError(member.toString());
81 mtype = mtype.insertParameterTypes(0, refc);
82 }
83 if (!member.isField()) {
84
85
86 switch (refKind) {
87 case REF_invokeSpecial: {
88 member = member.asSpecial();
89
90
91 if (callerClass == null) {
92 throw new InternalError("callerClass must not be null for REF_invokeSpecial");
93 }
94 LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
95 return new Special(mtype, lform, member, callerClass);
96 }
97 case REF_invokeInterface: {
98
99
100
101 LambdaForm lform = preparedLambdaForm(member, true);
102 return new Interface(mtype, lform, member, refc);
103 }
104 default: {
105 LambdaForm lform = preparedLambdaForm(member);
106 return new DirectMethodHandle(mtype, lform, member);
107 }
108 }
109 } else {
110 LambdaForm lform = preparedFieldLambdaForm(member);
111 if (member.isStatic()) {
112 long offset = MethodHandleNatives.staticFieldOffset(member);
113 Object base = MethodHandleNatives.staticFieldBase(member);
114 return new StaticAccessor(mtype, lform, member, base, offset);
115 } else {
116 long offset = MethodHandleNatives.objectFieldOffset(member);
117 assert(offset == (int)offset);
118 return new Accessor(mtype, lform, member, (int)offset);
119 }
120 }
121 }
122 static DirectMethodHandle make(Class<?> refc, MemberName member) {
123 byte refKind = member.getReferenceKind();
124 if (refKind == REF_invokeSpecial)
125 refKind = REF_invokeVirtual;
126 return make(refKind, refc, member, null );
127 }
128 static DirectMethodHandle make(MemberName member) {
129 if (member.isConstructor())
130 return makeAllocator(member);
131 return make(member.getDeclaringClass(), member);
132 }
133 private static DirectMethodHandle makeAllocator(MemberName ctor) {
134 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
135 Class<?> instanceClass = ctor.getDeclaringClass();
136 ctor = ctor.asConstructor();
137 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
138 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
139 LambdaForm lform = preparedLambdaForm(ctor);
140 MemberName init = ctor.asSpecial();
141 assert(init.getMethodType().returnType() == void.class);
142 return new Constructor(mtype, lform, ctor, init, instanceClass);
143 }
144
145 @Override
146 BoundMethodHandle rebind() {
147 return BoundMethodHandle.makeReinvoker(this);
148 }
149
150 @Override
151 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
152 assert(this.getClass() == DirectMethodHandle.class);
153 return new DirectMethodHandle(mt, lf, member);
154 }
155
156 @Override
157 String internalProperties() {
158 return "\n& DMH.MN="+internalMemberName();
159 }
160
161
162 @Override
163 @ForceInline
164 MemberName internalMemberName() {
165 return member;
166 }
167
168 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
169
170
175 private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) {
176 assert(m.isInvocable()) : m;
177 MethodType mtype = m.getInvocationType().basicType();
178 assert(!m.isMethodHandleInvoke()) : m;
179 int which;
180
181
182
183
184
185 switch (m.getReferenceKind()) {
186 case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
187 case REF_invokeStatic: which = LF_INVSTATIC; break;
188 case REF_invokeSpecial: which = LF_INVSPECIAL; break;
189 case REF_invokeInterface: which = LF_INVINTERFACE; break;
190 case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
191 default: throw new InternalError(m.toString());
192 }
193 if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
194
195 preparedLambdaForm(mtype, which);
196 which = LF_INVSTATIC_INIT;
197 }
198 if (which == LF_INVSPECIAL && adaptToSpecialIfc) {
199 which = LF_INVSPECIAL_IFC;
200 }
201 LambdaForm lform = preparedLambdaForm(mtype, which);
202 maybeCompile(lform, m);
203 assert(lform.methodType().dropParameterTypes(0, 1)
204 .equals(m.getInvocationType().basicType()))
205 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
206 return lform;
207 }
208
209 private static LambdaForm preparedLambdaForm(MemberName m) {
210 return preparedLambdaForm(m, false);
211 }
212
213 private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
214 LambdaForm lform = mtype.form().cachedLambdaForm(which);
215 if (lform != null) return lform;
216 lform = makePreparedLambdaForm(mtype, which);
217 return mtype.form().setCachedLambdaForm(which, lform);
218 }
219
220 static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
221 boolean needsInit = (which == LF_INVSTATIC_INIT);
222 boolean doesAlloc = (which == LF_NEWINVSPECIAL);
223 boolean needsReceiverCheck = (which == LF_INVINTERFACE ||
224 which == LF_INVSPECIAL_IFC);
225
226 String linkerName;
227 LambdaForm.Kind kind;
228 switch (which) {
229 case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break;
230 case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break;
231 case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC_INIT; break;
232 case LF_INVSPECIAL_IFC:linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL_IFC; break;
233 case LF_INVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL; break;
234 case LF_INVINTERFACE: linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE; break;
235 case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_NEW_INVOKE_SPECIAL; break;
236 default: throw new InternalError("which="+which);
237 }
238
239 MethodType mtypeWithArg = mtype.appendParameterTypes(MemberName.class);
240 if (doesAlloc)
241 mtypeWithArg = mtypeWithArg
242 .insertParameterTypes(0, Object.class)
243 .changeReturnType(void.class);
244 MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
245 try {
246 linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
247 } catch (ReflectiveOperationException ex) {
248 throw newInternalError(ex);
249 }
250 final int DMH_THIS = 0;
251 final int ARG_BASE = 1;
252 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
253 int nameCursor = ARG_LIMIT;
254 final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
255 final int GET_MEMBER = nameCursor++;
256 final int CHECK_RECEIVER = (needsReceiverCheck ? nameCursor++ : -1);
257 final int LINKER_CALL = nameCursor++;
258 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
259 assert(names.length == nameCursor);
260 if (doesAlloc) {
261
262 names[NEW_OBJ] = new Name(getFunction(NF_allocateInstance), names[DMH_THIS]);
263 names[GET_MEMBER] = new Name(getFunction(NF_constructorMethod), names[DMH_THIS]);
264 } else if (needsInit) {
265 names[GET_MEMBER] = new Name(getFunction(NF_internalMemberNameEnsureInit), names[DMH_THIS]);
266 } else {
267 names[GET_MEMBER] = new Name(getFunction(NF_internalMemberName), names[DMH_THIS]);
268 }
269 assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
270 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
271 if (needsReceiverCheck) {
272 names[CHECK_RECEIVER] = new Name(getFunction(NF_checkReceiver), names[DMH_THIS], names[ARG_BASE]);
273 outArgs[0] = names[CHECK_RECEIVER];
274 }
275 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);
276 int result = LAST_RESULT;
277 if (doesAlloc) {
278 assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);
279 System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
280 outArgs[0] = names[NEW_OBJ];
281 result = NEW_OBJ;
282 }
283 names[LINKER_CALL] = new Name(linker, outArgs);
284 LambdaForm lform = new LambdaForm(ARG_LIMIT, names, result, kind);
285
286
287 lform.compileToBytecode();
288 return lform;
289 }
290
291 static Object findDirectMethodHandle(Name name) {
292 if (name.function.equals(getFunction(NF_internalMemberName)) ||
293 name.function.equals(getFunction(NF_internalMemberNameEnsureInit)) ||
294 name.function.equals(getFunction(NF_constructorMethod))) {
295 assert(name.arguments.length == 1);
296 return name.arguments[0];
297 }
298 return null;
299 }
300
301 private static void maybeCompile(LambdaForm lform, MemberName m) {
302 if (lform.vmentry == null && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
303
304 lform.compileToBytecode();
305 }
306
307
308 @ForceInline
309 static Object internalMemberName(Object mh) {
310 return ((DirectMethodHandle)mh).member;
311 }
312
313
316 static Object internalMemberNameEnsureInit(Object mh) {
317 DirectMethodHandle dmh = (DirectMethodHandle)mh;
318 dmh.ensureInitialized();
319 return dmh.member;
320 }
321
322 static
323 boolean shouldBeInitialized(MemberName member) {
324 switch (member.getReferenceKind()) {
325 case REF_invokeStatic:
326 case REF_getStatic:
327 case REF_putStatic:
328 case REF_newInvokeSpecial:
329 break;
330 default:
331
332 return false;
333 }
334 Class<?> cls = member.getDeclaringClass();
335 if (cls == ValueConversions.class ||
336 cls == MethodHandleImpl.class ||
337 cls == Invokers.class) {
338
339
340 return false;
341 }
342 if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
343 VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
344
345
346 if (UNSAFE.shouldBeInitialized(cls)) {
347 UNSAFE.ensureClassInitialized(cls);
348 }
349 return false;
350 }
351 return UNSAFE.shouldBeInitialized(cls);
352 }
353
354 private static class EnsureInitialized extends ClassValue<WeakReference<Thread>> {
355 @Override
356 protected WeakReference<Thread> computeValue(Class<?> type) {
357 UNSAFE.ensureClassInitialized(type);
358 if (UNSAFE.shouldBeInitialized(type))
359
360
361 return new WeakReference<>(Thread.currentThread());
362 return null;
363 }
364 static final EnsureInitialized INSTANCE = new EnsureInitialized();
365 }
366
367 private void ensureInitialized() {
368 if (checkInitialized(member)) {
369
370 if (member.isField())
371 updateForm(preparedFieldLambdaForm(member));
372 else
373 updateForm(preparedLambdaForm(member));
374 }
375 }
376 private static boolean checkInitialized(MemberName member) {
377 Class<?> defc = member.getDeclaringClass();
378 WeakReference<Thread> ref = EnsureInitialized.INSTANCE.get(defc);
379 if (ref == null) {
380 return true;
381 }
382 Thread clinitThread = ref.get();
383
384 if (clinitThread == Thread.currentThread()) {
385
386 if (UNSAFE.shouldBeInitialized(defc))
387
388 return false;
389 } else {
390
391 UNSAFE.ensureClassInitialized(defc);
392 }
393 assert(!UNSAFE.shouldBeInitialized(defc));
394
395 EnsureInitialized.INSTANCE.remove(defc);
396 return true;
397 }
398
399 static void ensureInitialized(Object mh) {
400 ((DirectMethodHandle)mh).ensureInitialized();
401 }
402
403
404 static class Special extends DirectMethodHandle {
405 private final Class<?> caller;
406 private Special(MethodType mtype, LambdaForm form, MemberName member, Class<?> caller) {
407 super(mtype, form, member);
408 this.caller = caller;
409 }
410 @Override
411 boolean isInvokeSpecial() {
412 return true;
413 }
414 @Override
415 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
416 return new Special(mt, lf, member, caller);
417 }
418 Object checkReceiver(Object recv) {
419 if (!caller.isInstance(recv)) {
420 String msg = String.format("Receiver class %s is not a subclass of caller class %s",
421 recv.getClass().getName(), caller.getName());
422 throw new IncompatibleClassChangeError(msg);
423 }
424 return recv;
425 }
426 }
427
428
429 static class Interface extends DirectMethodHandle {
430 private final Class<?> refc;
431 private Interface(MethodType mtype, LambdaForm form, MemberName member, Class<?> refc) {
432 super(mtype, form, member);
433 assert refc.isInterface() : refc;
434 this.refc = refc;
435 }
436 @Override
437 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
438 return new Interface(mt, lf, member, refc);
439 }
440 @Override
441 Object checkReceiver(Object recv) {
442 if (!refc.isInstance(recv)) {
443 String msg = String.format("Receiver class %s does not implement the requested interface %s",
444 recv.getClass().getName(), refc.getName());
445 throw new IncompatibleClassChangeError(msg);
446 }
447 return recv;
448 }
449 }
450
451
452 Object checkReceiver(Object recv) {
453 throw new InternalError("Should only be invoked on a subclass");
454 }
455
456
457
458 static class Constructor extends DirectMethodHandle {
459 final MemberName initMethod;
460 final Class<?> instanceClass;
461
462 private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
463 MemberName initMethod, Class<?> instanceClass) {
464 super(mtype, form, constructor);
465 this.initMethod = initMethod;
466 this.instanceClass = instanceClass;
467 assert(initMethod.isResolved());
468 }
469 @Override
470 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
471 return new Constructor(mt, lf, member, initMethod, instanceClass);
472 }
473 }
474
475 static Object constructorMethod(Object mh) {
476 Constructor dmh = (Constructor)mh;
477 return dmh.initMethod;
478 }
479
480 static Object allocateInstance(Object mh) throws InstantiationException {
481 Constructor dmh = (Constructor)mh;
482 return UNSAFE.allocateInstance(dmh.instanceClass);
483 }
484
485
486 static class Accessor extends DirectMethodHandle {
487 final Class<?> fieldType;
488 final int fieldOffset;
489 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
490 int fieldOffset) {
491 super(mtype, form, member);
492 this.fieldType = member.getFieldType();
493 this.fieldOffset = fieldOffset;
494 }
495
496 @Override Object checkCast(Object obj) {
497 return fieldType.cast(obj);
498 }
499 @Override
500 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
501 return new Accessor(mt, lf, member, fieldOffset);
502 }
503 }
504
505 @ForceInline
506 static long fieldOffset(Object accessorObj) {
507
508
509 return ((Accessor)accessorObj).fieldOffset;
510 }
511
512 @ForceInline
513 static Object checkBase(Object obj) {
514
515
516
517
518
519
520
521 return Objects.requireNonNull(obj);
522 }
523
524
525 static class StaticAccessor extends DirectMethodHandle {
526 private final Class<?> fieldType;
527 private final Object staticBase;
528 private final long staticOffset;
529
530 private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
531 Object staticBase, long staticOffset) {
532 super(mtype, form, member);
533 this.fieldType = member.getFieldType();
534 this.staticBase = staticBase;
535 this.staticOffset = staticOffset;
536 }
537
538 @Override Object checkCast(Object obj) {
539 return fieldType.cast(obj);
540 }
541 @Override
542 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
543 return new StaticAccessor(mt, lf, member, staticBase, staticOffset);
544 }
545 }
546
547 @ForceInline
548 static Object nullCheck(Object obj) {
549 return Objects.requireNonNull(obj);
550 }
551
552 @ForceInline
553 static Object staticBase(Object accessorObj) {
554 return ((StaticAccessor)accessorObj).staticBase;
555 }
556
557 @ForceInline
558 static long staticOffset(Object accessorObj) {
559 return ((StaticAccessor)accessorObj).staticOffset;
560 }
561
562 @ForceInline
563 static Object checkCast(Object mh, Object obj) {
564 return ((DirectMethodHandle) mh).checkCast(obj);
565 }
566
567 Object checkCast(Object obj) {
568 return member.getReturnType().cast(obj);
569 }
570
571
572 static final byte
573 AF_GETFIELD = 0,
574 AF_PUTFIELD = 1,
575 AF_GETSTATIC = 2,
576 AF_PUTSTATIC = 3,
577 AF_GETSTATIC_INIT = 4,
578 AF_PUTSTATIC_INIT = 5,
579 AF_LIMIT = 6;
580
581
582 static final int
583 FT_LAST_WRAPPER = Wrapper.COUNT-1,
584 FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
585 FT_CHECKED_REF = FT_LAST_WRAPPER+1,
586 FT_LIMIT = FT_LAST_WRAPPER+2;
587 private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
588 return ((formOp * FT_LIMIT * 2)
589 + (isVolatile ? FT_LIMIT : 0)
590 + ftypeKind);
591 }
592 @Stable
593 private static final LambdaForm[] ACCESSOR_FORMS
594 = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
595 static int ftypeKind(Class<?> ftype) {
596 if (ftype.isPrimitive())
597 return Wrapper.forPrimitiveType(ftype).ordinal();
598 else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
599 return FT_UNCHECKED_REF;
600 else
601 return FT_CHECKED_REF;
602 }
603
604
609 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
610 Class<?> ftype = m.getFieldType();
611 boolean isVolatile = m.isVolatile();
612 byte formOp;
613 switch (m.getReferenceKind()) {
614 case REF_getField: formOp = AF_GETFIELD; break;
615 case REF_putField: formOp = AF_PUTFIELD; break;
616 case REF_getStatic: formOp = AF_GETSTATIC; break;
617 case REF_putStatic: formOp = AF_PUTSTATIC; break;
618 default: throw new InternalError(m.toString());
619 }
620 if (shouldBeInitialized(m)) {
621
622 preparedFieldLambdaForm(formOp, isVolatile, ftype);
623 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
624 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
625 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
626 }
627 LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
628 maybeCompile(lform, m);
629 assert(lform.methodType().dropParameterTypes(0, 1)
630 .equals(m.getInvocationType().basicType()))
631 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
632 return lform;
633 }
634 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
635 int ftypeKind = ftypeKind(ftype);
636 int afIndex = afIndex(formOp, isVolatile, ftypeKind);
637 LambdaForm lform = ACCESSOR_FORMS[afIndex];
638 if (lform != null) return lform;
639 lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
640 ACCESSOR_FORMS[afIndex] = lform;
641 return lform;
642 }
643
644 private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
645
646 private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
647 if (isGetter) {
648 if (isVolatile) {
649 switch (wrapper) {
650 case BOOLEAN: return GET_BOOLEAN_VOLATILE;
651 case BYTE: return GET_BYTE_VOLATILE;
652 case SHORT: return GET_SHORT_VOLATILE;
653 case CHAR: return GET_CHAR_VOLATILE;
654 case INT: return GET_INT_VOLATILE;
655 case LONG: return GET_LONG_VOLATILE;
656 case FLOAT: return GET_FLOAT_VOLATILE;
657 case DOUBLE: return GET_DOUBLE_VOLATILE;
658 case OBJECT: return GET_OBJECT_VOLATILE;
659 }
660 } else {
661 switch (wrapper) {
662 case BOOLEAN: return GET_BOOLEAN;
663 case BYTE: return GET_BYTE;
664 case SHORT: return GET_SHORT;
665 case CHAR: return GET_CHAR;
666 case INT: return GET_INT;
667 case LONG: return GET_LONG;
668 case FLOAT: return GET_FLOAT;
669 case DOUBLE: return GET_DOUBLE;
670 case OBJECT: return GET_OBJECT;
671 }
672 }
673 } else {
674 if (isVolatile) {
675 switch (wrapper) {
676 case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
677 case BYTE: return PUT_BYTE_VOLATILE;
678 case SHORT: return PUT_SHORT_VOLATILE;
679 case CHAR: return PUT_CHAR_VOLATILE;
680 case INT: return PUT_INT_VOLATILE;
681 case LONG: return PUT_LONG_VOLATILE;
682 case FLOAT: return PUT_FLOAT_VOLATILE;
683 case DOUBLE: return PUT_DOUBLE_VOLATILE;
684 case OBJECT: return PUT_OBJECT_VOLATILE;
685 }
686 } else {
687 switch (wrapper) {
688 case BOOLEAN: return PUT_BOOLEAN;
689 case BYTE: return PUT_BYTE;
690 case SHORT: return PUT_SHORT;
691 case CHAR: return PUT_CHAR;
692 case INT: return PUT_INT;
693 case LONG: return PUT_LONG;
694 case FLOAT: return PUT_FLOAT;
695 case DOUBLE: return PUT_DOUBLE;
696 case OBJECT: return PUT_OBJECT;
697 }
698 }
699 }
700 throw new AssertionError("Invalid arguments");
701 }
702
703 static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
704 boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
705 boolean isStatic = (formOp >= AF_GETSTATIC);
706 boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
707 boolean needsCast = (ftypeKind == FT_CHECKED_REF);
708 Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
709 Class<?> ft = fw.primitiveType();
710 assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
711
712
713 Kind kind = getFieldKind(isGetter, isVolatile, fw);
714
715 MethodType linkerType;
716 if (isGetter)
717 linkerType = MethodType.methodType(ft, Object.class, long.class);
718 else
719 linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
720 MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
721 try {
722 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
723 } catch (ReflectiveOperationException ex) {
724 throw newInternalError(ex);
725 }
726
727
728 MethodType mtype;
729 if (isGetter)
730 mtype = MethodType.methodType(ft);
731 else
732 mtype = MethodType.methodType(void.class, ft);
733 mtype = mtype.basicType();
734 if (!isStatic)
735 mtype = mtype.insertParameterTypes(0, Object.class);
736 final int DMH_THIS = 0;
737 final int ARG_BASE = 1;
738 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
739
740 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
741
742 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
743 int nameCursor = ARG_LIMIT;
744 final int F_HOLDER = (isStatic ? nameCursor++ : -1);
745 final int F_OFFSET = nameCursor++;
746 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
747 final int U_HOLDER = nameCursor++;
748 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
749 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
750 final int LINKER_CALL = nameCursor++;
751 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
752 final int RESULT = nameCursor-1;
753 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
754 if (needsInit)
755 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
756 if (needsCast && !isGetter)
757 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
758 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
759 assert(outArgs.length == (isGetter ? 3 : 4));
760 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
761 if (isStatic) {
762 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
763 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
764 } else {
765 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
766 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
767 }
768 if (!isGetter) {
769 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
770 }
771 for (Object a : outArgs) assert(a != null);
772 names[LINKER_CALL] = new Name(linker, outArgs);
773 if (needsCast && isGetter)
774 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
775 for (Name n : names) assert(n != null);
776
777 LambdaForm form;
778 if (needsCast || needsInit) {
779
780 form = new LambdaForm(ARG_LIMIT, names, RESULT);
781 } else {
782 form = new LambdaForm(ARG_LIMIT, names, RESULT, kind);
783 }
784
785 if (LambdaForm.debugNames()) {
786
787
788 StringBuilder nameBuilder = new StringBuilder(kind.methodName);
789 if (isStatic) {
790 nameBuilder.append("Static");
791 } else {
792 nameBuilder.append("Field");
793 }
794 if (needsCast) {
795 nameBuilder.append("Cast");
796 }
797 if (needsInit) {
798 nameBuilder.append("Init");
799 }
800 LambdaForm.associateWithDebugName(form, nameBuilder.toString());
801 }
802 return form;
803 }
804
805
808 static final byte NF_internalMemberName = 0,
809 NF_internalMemberNameEnsureInit = 1,
810 NF_ensureInitialized = 2,
811 NF_fieldOffset = 3,
812 NF_checkBase = 4,
813 NF_staticBase = 5,
814 NF_staticOffset = 6,
815 NF_checkCast = 7,
816 NF_allocateInstance = 8,
817 NF_constructorMethod = 9,
818 NF_UNSAFE = 10,
819 NF_checkReceiver = 11,
820 NF_LIMIT = 12;
821
822 private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
823
824 private static NamedFunction getFunction(byte func) {
825 NamedFunction nf = NFS[func];
826 if (nf != null) {
827 return nf;
828 }
829
830 nf = NFS[func] = createFunction(func);
831 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
832 return nf;
833 }
834
835 private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
836
837 private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
838
839 private static NamedFunction createFunction(byte func) {
840 try {
841 switch (func) {
842 case NF_internalMemberName:
843 return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
844 case NF_internalMemberNameEnsureInit:
845 return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
846 case NF_ensureInitialized:
847 return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
848 case NF_fieldOffset:
849 return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
850 case NF_checkBase:
851 return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
852 case NF_staticBase:
853 return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
854 case NF_staticOffset:
855 return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
856 case NF_checkCast:
857 return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
858 case NF_allocateInstance:
859 return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
860 case NF_constructorMethod:
861 return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
862 case NF_UNSAFE:
863 MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
864 return new NamedFunction(
865 MemberName.getFactory()
866 .resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
867 case NF_checkReceiver:
868 member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
869 return new NamedFunction(
870 MemberName.getFactory()
871 .resolveOrFail(REF_invokeVirtual, member, DirectMethodHandle.class, NoSuchMethodException.class));
872 default:
873 throw newInternalError("Unknown function: " + func);
874 }
875 } catch (ReflectiveOperationException ex) {
876 throw newInternalError(ex);
877 }
878 }
879
880 private static NamedFunction getNamedFunction(String name, MethodType type)
881 throws ReflectiveOperationException
882 {
883 MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
884 return new NamedFunction(
885 MemberName.getFactory()
886 .resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
887 }
888
889 static {
890
891
892
893
894 UNSAFE.ensureClassInitialized(Holder.class);
895 }
896
897
898 final class Holder {}
899 }
900