/**
  * Create a LF which can access the given field. Cache and share this structure among all fields
  * with the same basicType and refKind.
  */
 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
   Class<?> ftype = m.getFieldType();
   boolean isVolatile = m.isVolatile();
   byte formOp;
   switch (m.getReferenceKind()) {
     case REF_getField:
       formOp = AF_GETFIELD;
       break;
     case REF_putField:
       formOp = AF_PUTFIELD;
       break;
     case REF_getStatic:
       formOp = AF_GETSTATIC;
       break;
     case REF_putStatic:
       formOp = AF_PUTSTATIC;
       break;
     default:
       throw new InternalError(m.toString());
   }
   if (shouldBeInitialized(m)) {
     // precompute the barrier-free version:
     preparedFieldLambdaForm(formOp, isVolatile, ftype);
     assert ((AF_GETSTATIC_INIT - AF_GETSTATIC) == (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
     formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
   }
   LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
   maybeCompile(lform, m);
   assert (lform.methodType().dropParameterTypes(0, 1).equals(m.getInvocationType().basicType()))
       : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
   return lform;
 }
 // Factory methods:
 static DirectMethodHandle make(byte refKind, Class<?> receiver, MemberName member) {
   MethodType mtype = member.getMethodOrFieldType();
   if (!member.isStatic()) {
     if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
       throw new InternalError(member.toString());
     mtype = mtype.insertParameterTypes(0, receiver);
   }
   if (!member.isField()) {
     if (refKind == REF_invokeSpecial) {
       member = member.asSpecial();
       LambdaForm lform = preparedLambdaForm(member);
       return new Special(mtype, lform, member);
     } else {
       LambdaForm lform = preparedLambdaForm(member);
       return new DirectMethodHandle(mtype, lform, member);
     }
   } else {
     LambdaForm lform = preparedFieldLambdaForm(member);
     if (member.isStatic()) {
       long offset = MethodHandleNatives.staticFieldOffset(member);
       Object base = MethodHandleNatives.staticFieldBase(member);
       return new StaticAccessor(mtype, lform, member, base, offset);
     } else {
       long offset = MethodHandleNatives.objectFieldOffset(member);
       assert (offset == (int) offset);
       return new Accessor(mtype, lform, member, (int) offset);
     }
   }
 }
 /**
  * Create a LF which can invoke the given method. Cache and share this structure among all methods
  * with the same basicType and refKind.
  */
 private static LambdaForm preparedLambdaForm(MemberName m) {
   assert (m.isInvocable()) : m; // call preparedFieldLambdaForm instead
   MethodType mtype = m.getInvocationType().basicType();
   assert (!m.isMethodHandleInvoke()) : m;
   int which;
   switch (m.getReferenceKind()) {
     case REF_invokeVirtual:
       which = LF_INVVIRTUAL;
       break;
     case REF_invokeStatic:
       which = LF_INVSTATIC;
       break;
     case REF_invokeSpecial:
       which = LF_INVSPECIAL;
       break;
     case REF_invokeInterface:
       which = LF_INVINTERFACE;
       break;
     case REF_newInvokeSpecial:
       which = LF_NEWINVSPECIAL;
       break;
     default:
       throw new InternalError(m.toString());
   }
   if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
     // precompute the barrier-free version:
     preparedLambdaForm(mtype, which);
     which = LF_INVSTATIC_INIT;
   }
   LambdaForm lform = preparedLambdaForm(mtype, which);
   maybeCompile(lform, m);
   assert (lform.methodType().dropParameterTypes(0, 1).equals(m.getInvocationType().basicType()))
       : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
   return lform;
 }