< 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 >