/** * Produce a string form of this member name. For types, it is simply the type's own string (as * reported by {@code toString}). For fields, it is {@code "DeclaringClass.name/type"}. For * methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}. If the declaring * class is null, the prefix {@code "DeclaringClass."} is omitted. If the member is unresolved, a * prefix {@code "*."} is prepended. */ @Override public String toString() { if (isType()) return type.toString(); // class java.lang.String // else it is a field, method, or constructor StringBuilder buf = new StringBuilder(); if (getDeclaringClass() != null) { buf.append(getName(clazz)); buf.append('.'); } String name = getName(); buf.append(name == null ? "*" : name); Object type = getType(); if (!isInvocable()) { buf.append('/'); buf.append(type == null ? "*" : getName(type)); } else { buf.append(type == null ? "(*)*" : getName(type)); } /* buf.append('/'); // key: Public, private, pRotected, sTatic, Final, sYnchronized, // transient/Varargs, native, (interface), abstract, sTrict, sYnthetic, // (annotation), Enum, (unused) final String FIELD_MOD_CHARS = "PprTF?vt????Y?E?"; final String METHOD_MOD_CHARS = "PprTFybVn?atY???"; String modChars = (isInvocable() ? METHOD_MOD_CHARS : FIELD_MOD_CHARS); for (int i = 0; i < modChars.length(); i++) { if ((flags & (1 << i)) != 0) { char mc = modChars.charAt(i); if (mc != '?') buf.append(mc); } } */ return buf.toString(); }
private static LambdaForm makePreparedFieldLambdaForm( byte formOp, boolean isVolatile, int ftypeKind) { boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1); boolean isStatic = (formOp >= AF_GETSTATIC); boolean needsInit = (formOp >= AF_GETSTATIC_INIT); boolean needsCast = (ftypeKind == FT_CHECKED_REF); Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]); Class<?> ft = fw.primitiveType(); assert (ftypeKind(needsCast ? String.class : ft) == ftypeKind); // getObject, putIntVolatile, etc. StringBuilder nameBuilder = new StringBuilder(); if (isGetter) { nameBuilder.append("get"); } else { nameBuilder.append("put"); } nameBuilder.append(fw.primitiveSimpleName()); nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3))); if (isVolatile) { nameBuilder.append("Volatile"); } MethodType linkerType; if (isGetter) linkerType = MethodType.methodType(ft, Object.class, long.class); else linkerType = MethodType.methodType(void.class, Object.class, long.class, ft); MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual); try { linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class); } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } // What is the external type of the lambda form? MethodType mtype; if (isGetter) mtype = MethodType.methodType(ft); else mtype = MethodType.methodType(void.class, ft); mtype = mtype.basicType(); // erase short to int, etc. if (!isStatic) mtype = mtype.insertParameterTypes(0, Object.class); final int DMH_THIS = 0; final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); // if this is for non-static access, the base pointer is stored at this index: final int OBJ_BASE = isStatic ? -1 : ARG_BASE; // if this is for write access, the value to be written is stored at this index: final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1; int nameCursor = ARG_LIMIT; final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any final int F_OFFSET = nameCursor++; // Either static offset or field offset. final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1); final int INIT_BAR = (needsInit ? nameCursor++ : -1); final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1); final int LINKER_CALL = nameCursor++; final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1); final int RESULT = nameCursor - 1; // either the call or the cast Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); if (needsInit) names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); if (needsCast && !isGetter) names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert (outArgs.length == (isGetter ? 3 : 4)); outArgs[0] = UNSAFE; if (isStatic) { outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); } else { outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); } if (!isGetter) { outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); } for (Object a : outArgs) assert (a != null); names[LINKER_CALL] = new Name(linker, outArgs); if (needsCast && isGetter) names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); for (Name n : names) assert (n != null); // add some detail to the lambdaForm debugname, // significant only for debugging if (isStatic) { nameBuilder.append("Static"); } else { nameBuilder.append("Field"); } if (needsCast) nameBuilder.append("Cast"); if (needsInit) nameBuilder.append("Init"); return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT); }