< prev index next >

src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java

Print this page
rev 52487 : 8213741: Consolidate Object and String Stringifiers
Reviewed-by: TBD

*** 1627,1637 **** } @ForceInline private static byte[] newArray(long indexCoder) { byte coder = (byte)(indexCoder >> 32); ! int index = ((int)indexCoder & 0x7FFFFFFF); return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder); } private static MethodHandle prepender(Class<?> cl) { return PREPENDERS.computeIfAbsent(cl, PREPEND); --- 1627,1637 ---- } @ForceInline private static byte[] newArray(long indexCoder) { byte coder = (byte)(indexCoder >> 32); ! int index = (int)indexCoder; return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder); } private static MethodHandle prepender(Class<?> cl) { return PREPENDERS.computeIfAbsent(cl, PREPEND);
*** 1690,1723 **** private static final class Stringifiers { private Stringifiers() { // no instantiation } ! private static class StringifierMost extends ClassValue<MethodHandle> { ! @Override ! protected MethodHandle computeValue(Class<?> cl) { ! if (cl == String.class) { ! return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class); ! } else if (cl == float.class) { ! return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, float.class); ! } else if (cl == double.class) { ! return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, double.class); ! } else if (!cl.isPrimitive()) { ! MethodHandle mhObject = lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class); ! ! // We need the additional conversion here, because String.valueOf(Object) may return null. ! // String conversion rules in Java state we need to produce "null" String in this case. ! // It can be easily done with applying valueOf the second time. ! return MethodHandles.filterReturnValue(mhObject, ! mhObject.asType(MethodType.methodType(String.class, String.class))); } ! return null; } } private static class StringifierAny extends ClassValue<MethodHandle> { @Override protected MethodHandle computeValue(Class<?> cl) { if (cl == byte.class || cl == short.class || cl == int.class) { return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, int.class); } else if (cl == boolean.class) { --- 1690,1728 ---- private static final class Stringifiers { private Stringifiers() { // no instantiation } ! private static class StringStringifier { ! ! // We need some additional conversion for Objects in general, because String.valueOf(Object) ! // may return null. String conversion rules in Java state we need to produce "null" String ! // in this case, so we provide a customized version that deals with this problematic corner case. ! private static String valueOf(Object value) { ! String s; ! return (value == null || (s = value.toString()) == null) ? "null" : s; } ! // Could have used MethodHandles.lookup() instead of Lookup.IMPL_LOOKUP, if not for the fact ! // java.lang.invoke Lookups are explicitly forbidden to be retrieved using that API. ! private static final MethodHandle INSTANCE = ! lookupStatic(Lookup.IMPL_LOOKUP, StringStringifier.class, "valueOf", String.class, Object.class); ! } + + private static class FloatStringifiers { + private static final MethodHandle FLOAT_INSTANCE = + lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, float.class); + + private static final MethodHandle DOUBLE_INSTANCE = + lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, double.class); } private static class StringifierAny extends ClassValue<MethodHandle> { + + private static final ClassValue<MethodHandle> INSTANCE = new StringifierAny(); + @Override protected MethodHandle computeValue(Class<?> cl) { if (cl == byte.class || cl == short.class || cl == int.class) { return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, int.class); } else if (cl == boolean.class) {
*** 1725,1766 **** } else if (cl == char.class) { return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, char.class); } else if (cl == long.class) { return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, long.class); } else { ! MethodHandle mh = STRINGIFIERS_MOST.get(cl); if (mh != null) { return mh; } else { throw new IllegalStateException("Unknown class: " + cl); } } } } - private static final ClassValue<MethodHandle> STRINGIFIERS_MOST = new StringifierMost(); - private static final ClassValue<MethodHandle> STRINGIFIERS_ANY = new StringifierAny(); - /** * Returns a stringifier for references and floats/doubles only. * Always returns null for other primitives. * * @param t class to stringify * @return stringifier; null, if not available */ static MethodHandle forMost(Class<?> t) { ! return STRINGIFIERS_MOST.get(t); } /** * Returns a stringifier for any type. Never returns null. * * @param t class to stringify * @return stringifier */ static MethodHandle forAny(Class<?> t) { ! return STRINGIFIERS_ANY.get(t); } } /* ------------------------------- Common utilities ------------------------------------ */ --- 1730,1775 ---- } else if (cl == char.class) { return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, char.class); } else if (cl == long.class) { return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, long.class); } else { ! MethodHandle mh = forMost(cl); if (mh != null) { return mh; } else { throw new IllegalStateException("Unknown class: " + cl); } } } } /** * Returns a stringifier for references and floats/doubles only. * Always returns null for other primitives. * * @param t class to stringify * @return stringifier; null, if not available */ static MethodHandle forMost(Class<?> t) { ! if (!t.isPrimitive()) { ! return StringStringifier.INSTANCE; ! } else if (t == float.class) { ! return FloatStringifiers.FLOAT_INSTANCE; ! } else if (t == double.class) { ! return FloatStringifiers.DOUBLE_INSTANCE; ! } ! return null; } /** * Returns a stringifier for any type. Never returns null. * * @param t class to stringify * @return stringifier */ static MethodHandle forAny(Class<?> t) { ! return StringifierAny.INSTANCE.get(t); } } /* ------------------------------- Common utilities ------------------------------------ */
< prev index next >