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 /**
48 * The flavor of method handle which implements a constant reference
49 * to a class member.
50 * @author jrose
51 */
52 class DirectMethodHandle extends MethodHandle {
53 final MemberName member;
54
55 // Constructors and factory methods in this class *must* be package scoped or private.
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 // Check for corner case: invokeinterface of Object method
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()); // else this.form is wrong
68 member = m;
69 }
70 }
71
72 this.member = member;
73 }
74
75 // Factory methods:
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 // refKind reflects the original type of lookup via findSpecial or
85 // findVirtual etc.
86 switch (refKind) {
87 case REF_invokeSpecial: {
88 member = member.asSpecial();
89 // if caller is an interface we need to adapt to get the
90 // receiver check inserted
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 // for interfaces we always need the receiver typecheck,
99 // so we always pass 'true' to ensure we adapt if needed
100 // to include the REF_invokeSpecial case
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 /* no callerClass context */);
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); // must override in subclasses
153 return new DirectMethodHandle(mt, lf, member);
154 }
155
156 @Override
157 String internalProperties() {
158 return "\n& DMH.MN="+internalMemberName();
159 }
160
161 //// Implementation methods.
162 @Override
163 @ForceInline
164 MemberName internalMemberName() {
165 return member;
166 }
167
168 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
169
170 /**
171 * Create a LF which can invoke the given method.
172 * Cache and share this structure among all methods with
173 * the same basicType and refKind.
174 */
175 private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) {
389 // Yes, we are running it; keep the barrier for now.
390 return false;
391 } else {
392 // We are in a random thread. Block.
393 UNSAFE.ensureClassInitialized(defc);
394 }
395 assert(!UNSAFE.shouldBeInitialized(defc));
396 // put it into the final state
397 EnsureInitialized.INSTANCE.remove(defc);
398 return true;
399 }
400
401 /*non-public*/
402 static void ensureInitialized(Object mh) {
403 ((DirectMethodHandle)mh).ensureInitialized();
404 }
405
406 /** This subclass represents invokespecial instructions. */
407 static class Special extends DirectMethodHandle {
408 private final Class<?> caller;
409 private Special(MethodType mtype, LambdaForm form, MemberName member, Class<?> caller) {
410 super(mtype, form, member);
411 this.caller = caller;
412 }
413 @Override
414 boolean isInvokeSpecial() {
415 return true;
416 }
417 @Override
418 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
419 return new Special(mt, lf, member, caller);
420 }
421 Object checkReceiver(Object recv) {
422 if (!caller.isInstance(recv)) {
423 String msg = String.format("Receiver class %s is not a subclass of caller class %s",
424 recv.getClass().getName(), caller.getName());
425 throw new IncompatibleClassChangeError(msg);
426 }
427 return recv;
428 }
429 }
430
431 /** This subclass represents invokeinterface instructions. */
432 static class Interface extends DirectMethodHandle {
433 private final Class<?> refc;
434 private Interface(MethodType mtype, LambdaForm form, MemberName member, Class<?> refc) {
435 super(mtype, form, member);
436 assert refc.isInterface() : refc;
437 this.refc = refc;
438 }
439 @Override
440 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
441 return new Interface(mt, lf, member, refc);
442 }
443 @Override
444 Object checkReceiver(Object recv) {
445 if (!refc.isInstance(recv)) {
446 String msg = String.format("Receiver class %s does not implement the requested interface %s",
447 recv.getClass().getName(), refc.getName());
448 throw new IncompatibleClassChangeError(msg);
449 }
450 return recv;
451 }
452 }
453
454 /** Used for interface receiver type checks, by Interface and Special modes. */
455 Object checkReceiver(Object recv) {
456 throw new InternalError("Should only be invoked on a subclass");
457 }
458
459
460 /** This subclass handles constructor references. */
461 static class Constructor extends DirectMethodHandle {
462 final MemberName initMethod;
463 final Class<?> instanceClass;
464
465 private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
466 MemberName initMethod, Class<?> instanceClass) {
467 super(mtype, form, constructor);
468 this.initMethod = initMethod;
469 this.instanceClass = instanceClass;
470 assert(initMethod.isResolved());
471 }
472 @Override
473 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
474 return new Constructor(mt, lf, member, initMethod, instanceClass);
475 }
476 }
477
478 /*non-public*/
479 static Object constructorMethod(Object mh) {
480 Constructor dmh = (Constructor)mh;
481 return dmh.initMethod;
482 }
483
484 /*non-public*/
485 static Object allocateInstance(Object mh) throws InstantiationException {
486 Constructor dmh = (Constructor)mh;
487 return UNSAFE.allocateInstance(dmh.instanceClass);
488 }
489
490 /** This subclass handles non-static field references. */
491 static class Accessor extends DirectMethodHandle {
492 final Class<?> fieldType;
493 final int fieldOffset;
494 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
495 int fieldOffset) {
496 super(mtype, form, member);
497 this.fieldType = member.getFieldType();
498 this.fieldOffset = fieldOffset;
499 }
500
501 @Override Object checkCast(Object obj) {
502 return fieldType.cast(obj);
503 }
504 @Override
505 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
506 return new Accessor(mt, lf, member, fieldOffset);
507 }
508 }
509
510 @ForceInline
511 /*non-public*/
512 static long fieldOffset(Object accessorObj) {
513 // Note: We return a long because that is what Unsafe.getObject likes.
514 // We store a plain int because it is more compact.
515 return ((Accessor)accessorObj).fieldOffset;
516 }
517
518 @ForceInline
519 /*non-public*/
520 static Object checkBase(Object obj) {
521 // Note that the object's class has already been verified,
522 // since the parameter type of the Accessor method handle
523 // is either member.getDeclaringClass or a subclass.
524 // This was verified in DirectMethodHandle.make.
525 // Therefore, the only remaining check is for null.
526 // Since this check is *not* guaranteed by Unsafe.getInt
527 // and its siblings, we need to make an explicit one here.
528 return Objects.requireNonNull(obj);
529 }
530
531 /** This subclass handles static field references. */
532 static class StaticAccessor extends DirectMethodHandle {
533 private final Class<?> fieldType;
534 private final Object staticBase;
535 private final long staticOffset;
536
537 private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
538 Object staticBase, long staticOffset) {
539 super(mtype, form, member);
540 this.fieldType = member.getFieldType();
541 this.staticBase = staticBase;
542 this.staticOffset = staticOffset;
543 }
544
545 @Override Object checkCast(Object obj) {
546 return fieldType.cast(obj);
547 }
548 @Override
549 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
550 return new StaticAccessor(mt, lf, member, staticBase, staticOffset);
551 }
552 }
553
554 @ForceInline
555 /*non-public*/
556 static Object nullCheck(Object obj) {
557 return Objects.requireNonNull(obj);
558 }
559
560 @ForceInline
561 /*non-public*/
562 static Object staticBase(Object accessorObj) {
563 return ((StaticAccessor)accessorObj).staticBase;
564 }
565
566 @ForceInline
567 /*non-public*/
568 static long staticOffset(Object accessorObj) {
569 return ((StaticAccessor)accessorObj).staticOffset;
570 }
|
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 /**
48 * The flavor of method handle which implements a constant reference
49 * to a class member.
50 * @author jrose
51 */
52 class DirectMethodHandle extends MethodHandle {
53 final MemberName member;
54 final boolean crackable;
55
56 // Constructors and factory methods in this class *must* be package scoped or private.
57 private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member, boolean crackable) {
58 super(mtype, form);
59 if (!member.isResolved()) throw new InternalError();
60
61 if (member.getDeclaringClass().isInterface() &&
62 member.getReferenceKind() == REF_invokeInterface &&
63 member.isMethod() && !member.isAbstract()) {
64 // Check for corner case: invokeinterface of Object method
65 MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
66 m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
67 if (m != null && m.isPublic()) {
68 assert(member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong
69 member = m;
70 }
71 }
72
73 this.member = member;
74 this.crackable = crackable;
75 }
76
77 // Factory methods:
78 static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) {
79 MethodType mtype = member.getMethodOrFieldType();
80 if (!member.isStatic()) {
81 if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor())
82 throw new InternalError(member.toString());
83 mtype = mtype.insertParameterTypes(0, refc);
84 }
85 if (!member.isField()) {
86 // refKind reflects the original type of lookup via findSpecial or
87 // findVirtual etc.
88 switch (refKind) {
89 case REF_invokeSpecial: {
90 member = member.asSpecial();
91 // if caller is an interface we need to adapt to get the
92 // receiver check inserted
93 if (callerClass == null) {
94 throw new InternalError("callerClass must not be null for REF_invokeSpecial");
95 }
96 LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
97 return new Special(mtype, lform, member, true, callerClass);
98 }
99 case REF_invokeInterface: {
100 // for interfaces we always need the receiver typecheck,
101 // so we always pass 'true' to ensure we adapt if needed
102 // to include the REF_invokeSpecial case
103 LambdaForm lform = preparedLambdaForm(member, true);
104 return new Interface(mtype, lform, member, true, refc);
105 }
106 default: {
107 LambdaForm lform = preparedLambdaForm(member);
108 return new DirectMethodHandle(mtype, lform, member, true);
109 }
110 }
111 } else {
112 LambdaForm lform = preparedFieldLambdaForm(member);
113 if (member.isStatic()) {
114 long offset = MethodHandleNatives.staticFieldOffset(member);
115 Object base = MethodHandleNatives.staticFieldBase(member);
116 return new StaticAccessor(mtype, lform, member, true, base, offset);
117 } else {
118 long offset = MethodHandleNatives.objectFieldOffset(member);
119 assert(offset == (int)offset);
120 return new Accessor(mtype, lform, member, true, (int)offset);
121 }
122 }
123 }
124 static DirectMethodHandle make(Class<?> refc, MemberName member) {
125 byte refKind = member.getReferenceKind();
126 if (refKind == REF_invokeSpecial)
127 refKind = REF_invokeVirtual;
128 return make(refKind, refc, member, null /* no callerClass context */);
129 }
130 static DirectMethodHandle make(MemberName member) {
131 if (member.isConstructor())
132 return makeAllocator(member);
133 return make(member.getDeclaringClass(), member);
134 }
135 private static DirectMethodHandle makeAllocator(MemberName ctor) {
136 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
137 Class<?> instanceClass = ctor.getDeclaringClass();
138 ctor = ctor.asConstructor();
139 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
140 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
141 LambdaForm lform = preparedLambdaForm(ctor);
142 MemberName init = ctor.asSpecial();
143 assert(init.getMethodType().returnType() == void.class);
144 return new Constructor(mtype, lform, ctor, true, init, instanceClass);
145 }
146
147 @Override
148 BoundMethodHandle rebind() {
149 return BoundMethodHandle.makeReinvoker(this);
150 }
151
152 @Override
153 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
154 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
155 return new DirectMethodHandle(mt, lf, member, crackable);
156 }
157 /*non-public*/
158 @Override
159 MethodHandle viewAsType(MethodType newType, boolean strict) {
160 // No actual conversions, just a new view of the same method.
161 // However, we must not expose a DMH that is crackable into a
162 // MethodHandleInfo, so we return a cloned, uncrackable DMH
163 assert viewAsTypeChecks(newType, strict);
164 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
165 return new DirectMethodHandle(newType, form, member, false);
166 }
167 /*non-public*/
168 @Override
169 boolean isCrackable() {
170 return crackable;
171 }
172
173
174 @Override
175 String internalProperties() {
176 return "\n& DMH.MN="+internalMemberName();
177 }
178
179 //// Implementation methods.
180 @Override
181 @ForceInline
182 MemberName internalMemberName() {
183 return member;
184 }
185
186 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
187
188 /**
189 * Create a LF which can invoke the given method.
190 * Cache and share this structure among all methods with
191 * the same basicType and refKind.
192 */
193 private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) {
407 // Yes, we are running it; keep the barrier for now.
408 return false;
409 } else {
410 // We are in a random thread. Block.
411 UNSAFE.ensureClassInitialized(defc);
412 }
413 assert(!UNSAFE.shouldBeInitialized(defc));
414 // put it into the final state
415 EnsureInitialized.INSTANCE.remove(defc);
416 return true;
417 }
418
419 /*non-public*/
420 static void ensureInitialized(Object mh) {
421 ((DirectMethodHandle)mh).ensureInitialized();
422 }
423
424 /** This subclass represents invokespecial instructions. */
425 static class Special extends DirectMethodHandle {
426 private final Class<?> caller;
427 private Special(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> caller) {
428 super(mtype, form, member, crackable);
429 this.caller = caller;
430 }
431 @Override
432 boolean isInvokeSpecial() {
433 return true;
434 }
435 @Override
436 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
437 return new Special(mt, lf, member, crackable, caller);
438 }
439 @Override
440 MethodHandle viewAsType(MethodType newType, boolean strict) {
441 assert viewAsTypeChecks(newType, strict);
442 return new Special(newType, form, member, false, caller);
443 }
444 Object checkReceiver(Object recv) {
445 if (!caller.isInstance(recv)) {
446 String msg = String.format("Receiver class %s is not a subclass of caller class %s",
447 recv.getClass().getName(), caller.getName());
448 throw new IncompatibleClassChangeError(msg);
449 }
450 return recv;
451 }
452 }
453
454 /** This subclass represents invokeinterface instructions. */
455 static class Interface extends DirectMethodHandle {
456 private final Class<?> refc;
457 private Interface(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> refc) {
458 super(mtype, form, member, crackable);
459 assert refc.isInterface() : refc;
460 this.refc = refc;
461 }
462 @Override
463 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
464 return new Interface(mt, lf, member, crackable, refc);
465 }
466 @Override
467 MethodHandle viewAsType(MethodType newType, boolean strict) {
468 assert viewAsTypeChecks(newType, strict);
469 return new Interface(newType, form, member, false, refc);
470 }
471 @Override
472 Object checkReceiver(Object recv) {
473 if (!refc.isInstance(recv)) {
474 String msg = String.format("Receiver class %s does not implement the requested interface %s",
475 recv.getClass().getName(), refc.getName());
476 throw new IncompatibleClassChangeError(msg);
477 }
478 return recv;
479 }
480 }
481
482 /** Used for interface receiver type checks, by Interface and Special modes. */
483 Object checkReceiver(Object recv) {
484 throw new InternalError("Should only be invoked on a subclass");
485 }
486
487
488 /** This subclass handles constructor references. */
489 static class Constructor extends DirectMethodHandle {
490 final MemberName initMethod;
491 final Class<?> instanceClass;
492
493 private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
494 boolean crackable, MemberName initMethod, Class<?> instanceClass) {
495 super(mtype, form, constructor, crackable);
496 this.initMethod = initMethod;
497 this.instanceClass = instanceClass;
498 assert(initMethod.isResolved());
499 }
500 @Override
501 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
502 return new Constructor(mt, lf, member, crackable, initMethod, instanceClass);
503 }
504 @Override
505 MethodHandle viewAsType(MethodType newType, boolean strict) {
506 assert viewAsTypeChecks(newType, strict);
507 return new Constructor(newType, form, member, false, initMethod, instanceClass);
508 }
509 }
510
511 /*non-public*/
512 static Object constructorMethod(Object mh) {
513 Constructor dmh = (Constructor)mh;
514 return dmh.initMethod;
515 }
516
517 /*non-public*/
518 static Object allocateInstance(Object mh) throws InstantiationException {
519 Constructor dmh = (Constructor)mh;
520 return UNSAFE.allocateInstance(dmh.instanceClass);
521 }
522
523 /** This subclass handles non-static field references. */
524 static class Accessor extends DirectMethodHandle {
525 final Class<?> fieldType;
526 final int fieldOffset;
527 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
528 boolean crackable, int fieldOffset) {
529 super(mtype, form, member, crackable);
530 this.fieldType = member.getFieldType();
531 this.fieldOffset = fieldOffset;
532 }
533
534 @Override Object checkCast(Object obj) {
535 return fieldType.cast(obj);
536 }
537 @Override
538 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
539 return new Accessor(mt, lf, member, crackable, fieldOffset);
540 }
541 @Override
542 MethodHandle viewAsType(MethodType newType, boolean strict) {
543 assert viewAsTypeChecks(newType, strict);
544 return new Accessor(newType, form, member, false, fieldOffset);
545 }
546 }
547
548 @ForceInline
549 /*non-public*/
550 static long fieldOffset(Object accessorObj) {
551 // Note: We return a long because that is what Unsafe.getObject likes.
552 // We store a plain int because it is more compact.
553 return ((Accessor)accessorObj).fieldOffset;
554 }
555
556 @ForceInline
557 /*non-public*/
558 static Object checkBase(Object obj) {
559 // Note that the object's class has already been verified,
560 // since the parameter type of the Accessor method handle
561 // is either member.getDeclaringClass or a subclass.
562 // This was verified in DirectMethodHandle.make.
563 // Therefore, the only remaining check is for null.
564 // Since this check is *not* guaranteed by Unsafe.getInt
565 // and its siblings, we need to make an explicit one here.
566 return Objects.requireNonNull(obj);
567 }
568
569 /** This subclass handles static field references. */
570 static class StaticAccessor extends DirectMethodHandle {
571 private final Class<?> fieldType;
572 private final Object staticBase;
573 private final long staticOffset;
574
575 private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
576 boolean crackable, Object staticBase, long staticOffset) {
577 super(mtype, form, member, crackable);
578 this.fieldType = member.getFieldType();
579 this.staticBase = staticBase;
580 this.staticOffset = staticOffset;
581 }
582
583 @Override Object checkCast(Object obj) {
584 return fieldType.cast(obj);
585 }
586 @Override
587 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
588 return new StaticAccessor(mt, lf, member, crackable, staticBase, staticOffset);
589 }
590 @Override
591 MethodHandle viewAsType(MethodType newType, boolean strict) {
592 assert viewAsTypeChecks(newType, strict);
593 return new StaticAccessor(newType, form, member, false, staticBase, staticOffset);
594 }
595 }
596
597 @ForceInline
598 /*non-public*/
599 static Object nullCheck(Object obj) {
600 return Objects.requireNonNull(obj);
601 }
602
603 @ForceInline
604 /*non-public*/
605 static Object staticBase(Object accessorObj) {
606 return ((StaticAccessor)accessorObj).staticBase;
607 }
608
609 @ForceInline
610 /*non-public*/
611 static long staticOffset(Object accessorObj) {
612 return ((StaticAccessor)accessorObj).staticOffset;
613 }
|