110 }
111 static DirectMethodHandle make(Method method) {
112 return make(method.getDeclaringClass(), new MemberName(method));
113 }
114 static DirectMethodHandle make(Field field) {
115 return make(field.getDeclaringClass(), new MemberName(field));
116 }
117 private static DirectMethodHandle makeAllocator(MemberName ctor) {
118 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
119 Class<?> instanceClass = ctor.getDeclaringClass();
120 ctor = ctor.asConstructor();
121 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
122 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
123 LambdaForm lform = preparedLambdaForm(ctor);
124 MemberName init = ctor.asSpecial();
125 assert(init.getMethodType().returnType() == void.class);
126 return new Constructor(mtype, lform, ctor, init, instanceClass);
127 }
128
129 @Override
130 String internalProperties() {
131 return "\n& DMH.MN="+internalMemberName();
132 }
133
134 //// Implementation methods.
135 @Override
136 MethodHandle viewAsType(MethodType newType) {
137 return new DirectMethodHandle(newType, form, member);
138 }
139 @Override
140 @ForceInline
141 MemberName internalMemberName() {
142 return member;
143 }
144
145 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
146
147 /**
148 * Create a LF which can invoke the given method.
149 * Cache and share this structure among all methods with
150 * the same basicType and refKind.
151 */
152 private static LambdaForm preparedLambdaForm(MemberName m) {
153 assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
154 MethodType mtype = m.getInvocationType().basicType();
155 assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
156 int which;
157 switch (m.getReferenceKind()) {
158 case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
159 case REF_invokeStatic: which = LF_INVSTATIC; break;
347 assert(!UNSAFE.shouldBeInitialized(defc));
348 // put it into the final state
349 EnsureInitialized.INSTANCE.remove(defc);
350 return true;
351 }
352
353 /*non-public*/ static void ensureInitialized(Object mh) {
354 ((DirectMethodHandle)mh).ensureInitialized();
355 }
356
357 /** This subclass represents invokespecial instructions. */
358 static class Special extends DirectMethodHandle {
359 private Special(MethodType mtype, LambdaForm form, MemberName member) {
360 super(mtype, form, member);
361 }
362 @Override
363 boolean isInvokeSpecial() {
364 return true;
365 }
366 @Override
367 MethodHandle viewAsType(MethodType newType) {
368 return new Special(newType, form, member);
369 }
370 }
371
372 /** This subclass handles constructor references. */
373 static class Constructor extends DirectMethodHandle {
374 final MemberName initMethod;
375 final Class<?> instanceClass;
376
377 private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
378 MemberName initMethod, Class<?> instanceClass) {
379 super(mtype, form, constructor);
380 this.initMethod = initMethod;
381 this.instanceClass = instanceClass;
382 assert(initMethod.isResolved());
383 }
384 @Override
385 MethodHandle viewAsType(MethodType newType) {
386 return new Constructor(newType, form, member, initMethod, instanceClass);
387 }
388 }
389
390 /*non-public*/ static Object constructorMethod(Object mh) {
391 Constructor dmh = (Constructor)mh;
392 return dmh.initMethod;
393 }
394
395 /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
396 Constructor dmh = (Constructor)mh;
397 return UNSAFE.allocateInstance(dmh.instanceClass);
398 }
399
400 /** This subclass handles non-static field references. */
401 static class Accessor extends DirectMethodHandle {
402 final Class<?> fieldType;
403 final int fieldOffset;
404 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
405 int fieldOffset) {
406 super(mtype, form, member);
407 this.fieldType = member.getFieldType();
408 this.fieldOffset = fieldOffset;
409 }
410
411 @Override Object checkCast(Object obj) {
412 return fieldType.cast(obj);
413 }
414 @Override
415 MethodHandle viewAsType(MethodType newType) {
416 return new Accessor(newType, form, member, fieldOffset);
417 }
418 }
419
420 @ForceInline
421 /*non-public*/ static long fieldOffset(Object accessorObj) {
422 // Note: We return a long because that is what Unsafe.getObject likes.
423 // We store a plain int because it is more compact.
424 return ((Accessor)accessorObj).fieldOffset;
425 }
426
427 @ForceInline
428 /*non-public*/ static Object checkBase(Object obj) {
429 // Note that the object's class has already been verified,
430 // since the parameter type of the Accessor method handle
431 // is either member.getDeclaringClass or a subclass.
432 // This was verified in DirectMethodHandle.make.
433 // Therefore, the only remaining check is for null.
434 // Since this check is *not* guaranteed by Unsafe.getInt
435 // and its siblings, we need to make an explicit one here.
436 obj.getClass(); // maybe throw NPE
438 }
439
440 /** This subclass handles static field references. */
441 static class StaticAccessor extends DirectMethodHandle {
442 final private Class<?> fieldType;
443 final private Object staticBase;
444 final private long staticOffset;
445
446 private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
447 Object staticBase, long staticOffset) {
448 super(mtype, form, member);
449 this.fieldType = member.getFieldType();
450 this.staticBase = staticBase;
451 this.staticOffset = staticOffset;
452 }
453
454 @Override Object checkCast(Object obj) {
455 return fieldType.cast(obj);
456 }
457 @Override
458 MethodHandle viewAsType(MethodType newType) {
459 return new StaticAccessor(newType, form, member, staticBase, staticOffset);
460 }
461 }
462
463 @ForceInline
464 /*non-public*/ static Object nullCheck(Object obj) {
465 obj.getClass();
466 return obj;
467 }
468
469 @ForceInline
470 /*non-public*/ static Object staticBase(Object accessorObj) {
471 return ((StaticAccessor)accessorObj).staticBase;
472 }
473
474 @ForceInline
475 /*non-public*/ static long staticOffset(Object accessorObj) {
476 return ((StaticAccessor)accessorObj).staticOffset;
477 }
478
479 @ForceInline
|
110 }
111 static DirectMethodHandle make(Method method) {
112 return make(method.getDeclaringClass(), new MemberName(method));
113 }
114 static DirectMethodHandle make(Field field) {
115 return make(field.getDeclaringClass(), new MemberName(field));
116 }
117 private static DirectMethodHandle makeAllocator(MemberName ctor) {
118 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
119 Class<?> instanceClass = ctor.getDeclaringClass();
120 ctor = ctor.asConstructor();
121 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
122 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
123 LambdaForm lform = preparedLambdaForm(ctor);
124 MemberName init = ctor.asSpecial();
125 assert(init.getMethodType().returnType() == void.class);
126 return new Constructor(mtype, lform, ctor, init, instanceClass);
127 }
128
129 @Override
130 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
131 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
132 return new DirectMethodHandle(mt, lf, member);
133 }
134
135 @Override
136 String internalProperties() {
137 return "\n& DMH.MN="+internalMemberName();
138 }
139
140 //// Implementation methods.
141 @Override
142 @ForceInline
143 MemberName internalMemberName() {
144 return member;
145 }
146
147 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
148
149 /**
150 * Create a LF which can invoke the given method.
151 * Cache and share this structure among all methods with
152 * the same basicType and refKind.
153 */
154 private static LambdaForm preparedLambdaForm(MemberName m) {
155 assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
156 MethodType mtype = m.getInvocationType().basicType();
157 assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
158 int which;
159 switch (m.getReferenceKind()) {
160 case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
161 case REF_invokeStatic: which = LF_INVSTATIC; break;
349 assert(!UNSAFE.shouldBeInitialized(defc));
350 // put it into the final state
351 EnsureInitialized.INSTANCE.remove(defc);
352 return true;
353 }
354
355 /*non-public*/ static void ensureInitialized(Object mh) {
356 ((DirectMethodHandle)mh).ensureInitialized();
357 }
358
359 /** This subclass represents invokespecial instructions. */
360 static class Special extends DirectMethodHandle {
361 private Special(MethodType mtype, LambdaForm form, MemberName member) {
362 super(mtype, form, member);
363 }
364 @Override
365 boolean isInvokeSpecial() {
366 return true;
367 }
368 @Override
369 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
370 return new Special(mt, lf, member);
371 }
372 }
373
374 /** This subclass handles constructor references. */
375 static class Constructor extends DirectMethodHandle {
376 final MemberName initMethod;
377 final Class<?> instanceClass;
378
379 private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
380 MemberName initMethod, Class<?> instanceClass) {
381 super(mtype, form, constructor);
382 this.initMethod = initMethod;
383 this.instanceClass = instanceClass;
384 assert(initMethod.isResolved());
385 }
386 @Override
387 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
388 return new Constructor(mt, lf, member, initMethod, instanceClass);
389 }
390 }
391
392 /*non-public*/ static Object constructorMethod(Object mh) {
393 Constructor dmh = (Constructor)mh;
394 return dmh.initMethod;
395 }
396
397 /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
398 Constructor dmh = (Constructor)mh;
399 return UNSAFE.allocateInstance(dmh.instanceClass);
400 }
401
402 /** This subclass handles non-static field references. */
403 static class Accessor extends DirectMethodHandle {
404 final Class<?> fieldType;
405 final int fieldOffset;
406 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
407 int fieldOffset) {
408 super(mtype, form, member);
409 this.fieldType = member.getFieldType();
410 this.fieldOffset = fieldOffset;
411 }
412
413 @Override Object checkCast(Object obj) {
414 return fieldType.cast(obj);
415 }
416 @Override
417 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
418 return new Accessor(mt, lf, member, fieldOffset);
419 }
420 }
421
422 @ForceInline
423 /*non-public*/ static long fieldOffset(Object accessorObj) {
424 // Note: We return a long because that is what Unsafe.getObject likes.
425 // We store a plain int because it is more compact.
426 return ((Accessor)accessorObj).fieldOffset;
427 }
428
429 @ForceInline
430 /*non-public*/ static Object checkBase(Object obj) {
431 // Note that the object's class has already been verified,
432 // since the parameter type of the Accessor method handle
433 // is either member.getDeclaringClass or a subclass.
434 // This was verified in DirectMethodHandle.make.
435 // Therefore, the only remaining check is for null.
436 // Since this check is *not* guaranteed by Unsafe.getInt
437 // and its siblings, we need to make an explicit one here.
438 obj.getClass(); // maybe throw NPE
440 }
441
442 /** This subclass handles static field references. */
443 static class StaticAccessor extends DirectMethodHandle {
444 final private Class<?> fieldType;
445 final private Object staticBase;
446 final private long staticOffset;
447
448 private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
449 Object staticBase, long staticOffset) {
450 super(mtype, form, member);
451 this.fieldType = member.getFieldType();
452 this.staticBase = staticBase;
453 this.staticOffset = staticOffset;
454 }
455
456 @Override Object checkCast(Object obj) {
457 return fieldType.cast(obj);
458 }
459 @Override
460 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
461 return new StaticAccessor(mt, lf, member, staticBase, staticOffset);
462 }
463 }
464
465 @ForceInline
466 /*non-public*/ static Object nullCheck(Object obj) {
467 obj.getClass();
468 return obj;
469 }
470
471 @ForceInline
472 /*non-public*/ static Object staticBase(Object accessorObj) {
473 return ((StaticAccessor)accessorObj).staticBase;
474 }
475
476 @ForceInline
477 /*non-public*/ static long staticOffset(Object accessorObj) {
478 return ((StaticAccessor)accessorObj).staticOffset;
479 }
480
481 @ForceInline
|