RFR: 8141678: sun.invoke.util.Wrapper eagerly initializes all integral type caches
Claes Redestad
claes.redestad at oracle.com
Mon Nov 9 23:37:11 UTC 2015
Hi,
so we should add some test cases that guards against Wrapper.zero
references leaking through the public API and add stronger wording to
Wrapper.zero documentation?
I turned your test case below into a jtreg test, included added variants
for the other integral primitive types:
http://cr.openjdk.java.net/~redestad/scratch/wrapperTest.01/
1. int, short and long cases behave as expected: Wrapper.zero doesn't escape
2. void -> byte -> Object and void -> char -> Object box to null (test
passes with 8141678 applied); bug or intended?
I've pushed 8141678 already, perhaps breaking some rules in the
process.. I'll file a follow-up tomorrow.
/Claes
On 2015-11-09 22:18, John Rose wrote:
> 1. If the Wrapper.zero "leaks" as a reference into any of the public 292 API, that would be a bug, since the API specifies that the conversion from a zero to a box-reference is the same as mandated by the JLS for boxing conversion. (This is like Integer.valueOf(x), not new Integer(x).)
>
> 2. Since Wrapper is private, perhaps it is used in such a way that all the references are hidden appropriately. This is hard to prove and maintain, since some of the conversion functions used by asType are associated with Wrapper, and may (on occasion) call Wrapper.zero to provide a user-visible converted reference value. That would be a bug.
>
> 3. If there are no such bugs, at least the access function Wrapper.zero should prominently and carefully document the fact that it is returning an uninterned zero value, which may be incompatible with the intended use (if the use is to emulate JLS boxing conversation, like asType or explicitCastArguments.)
>
> For example:
> * <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
> * a zero value is introduced.
>
> Test case:
> MH h1 = MHs.constant(42);
> MH h2 = h1.asType(methodType(void.class)); // drop 42
> MH h3 = h2.asType(methodType(int.class)); // add 0
> MH h4 = h4.asType(methodType(Object.class)); // box
> Object x = h4.invokeExact();
> assert(x.equals(0));
> assert(x == Integer.valueOf(0));
>
> — John
>
> On Nov 9, 2015, at 4:13 AM, Vladimir Ivanov <vladimir.x.ivanov at oracle.com> wrote:
>> Claes,
>>
>> I don't think Wrapper.zero identity matters (e.g. see MethodHandles.constant [1] or InvokerBytecodeGenerator.emitConst).
>>
>> So, you can considerably simplify your code by allocating fresh wrapper instances.
>>
>> Best regards,
>> Vladimir Ivanov
>>
>> [1] public static
>> MethodHandle constant(Class<?> type, Object value) {
>> ...
>> if (w.zero().equals(value))
>> return zero(w, type);
>>
>>
>> On 11/8/15 4:43 PM, Claes Redestad wrote:
>>> Hi,
>>>
>>> indy eagerly creates and initializes all integral type caches
>>> (Byte$ByteCache, Short$ShortCache) which has a small, measurable
>>> impact to jake startup and footprint. Exposing ZERO constants from Byte,
>>> Character, etc which are guaranteed to be identical to what's
>>> returned from each respective valueOf(0) enables j.l.i. to initialize
>>> without eagerly creating these caches:
>>>
>>> webrev: http://cr.openjdk.java.net/~redestad/8141678/webrev.01
>>> bug: https://bugs.openjdk.java.net/browse/JDK-8141678
>>>
>>> Making these constants public would allow us to not fetch them via
>>> reflection for a tiny, incremental startup improvement, but I don't
>>> think the constants carry their own weight to motivate them becoming
>>> part of public API.
>>>
>>> Testing: verified startup/footprint improvement, various jtreg tests
>>>
>>> /Claes
More information about the core-libs-dev
mailing list