Question on layer/peeling
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Jan 6 11:05:18 UTC 2015
Looks like another compiler issue; here's the bytecode for Default.value:
public static <T extends java.lang.Object> T value();
Code:
stack=2, locals=0, args_size=0
0: new #2 // class Default
3: dup
4: invokespecial #3 // Method "<init>":()V
7: getfield #4 // Field
value:Ljava/lang/Object;
10: areturn
BytecodeMapping:
Code_idx Signature
0: LDefault<TT;>;
4: LDefault<TT;>;::()V
10: TT;
As you can see, the GETFIELD is missing the BytecodeMapping entry. I
suspect the 'dup' is causing javac to lose the type info associated with
the stack operand. I'll look into this.
Maurizio
On 06/01/15 08:21, Peter Levart wrote:
> This could be a temporary library trick:
>
> public class Default<any T> {
>
> private T value;
>
> private Default() {}
>
> public static <any T> T value() {
> return new Default<T>().value;
> }
> }
>
>
> with use like:
>
>
> public class Test {
> public static void main(String[] args) {
> int i = Default.value();
> long l = Default.value();
> Object o = Default.value();
> }
> }
>
>
>
> ...but unfortunately the above Test produces the following runtime
> exception:
>
>
> Specializing method util/Default$value${0=I}.value()Ljava/lang/Object;
> with class=[] and method=[I]
> Specializing util.Default${0=I}; searching for util/Default.class (not
> found)
> Specializing util.Default${0=I}; searching for util/Default.class (found)
> Exception in thread "main" java.lang.BootstrapMethodError: call site
> initialization exception
> at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
> at
> java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
> at
> java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
> at util.Test.main(Test.java:8)
> Caused by: java.lang.VerifyError: Bad type on operand stack
> Exception Details:
> Location:
> util/Default$value${0=I}.value()I @7: getfield
> Reason:
> Type 'util/Default${0=I}' (current frame, stack[0]) is not
> assignable to 'util/Default'
> Current Frame:
> bci: @7
> flags: { }
> locals: { }
> stack: { 'util/Default${0=I}' }
> Bytecode:
> 0000000: bb00 0959 b700 0db4 0012 ac
>
> at sun.misc.Unsafe.defineAnonymousClass(Native Method)
> at
> java.lang.invoke.GenericMethodSpecializer.metafactory(GenericMethodSpecializer.java:98)
> at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
> ... 3 more
>
>
> Seems like the specialization of static method is not entirely correct
> here.
>
> Regards, Peter
>
> On 01/06/2015 03:23 AM, Brian Goetz wrote:
>> Yes, this is pretty straightforward. In the bucket of "things that
>> are easy and small, so we'll ignore them until we solve the ones that
>> are big and difficult.")
>>
>> The hardest part is picking a syntax (please, no suggestions!)
>>
>>
>> On 1/5/2015 9:19 PM, Vitaly Davidovich wrote:
>>> C# has a default (T) keyword to allow generic code to obtain the "zero"
>>> value for a type param. Something like that for java would be nice.
>>>
>>> Sent from my phone
>>> On Jan 5, 2015 9:15 PM, "Michael Barker" <mikeb01 at gmail.com> wrote:
>>>
>>>> Hi,
>>>>
>>>> The SotS talks about the use of 'layer' to create an alternative
>>>> implementation of methods when the type of an <any T> is known to be a
>>>> reference type. However, the examples only show the use of the layer
>>>> keyword on an interface definition, where as I've encountered at
>>>> least one
>>>> case where the internal implementation needs to differentiate
>>>> between a
>>>> reference-type and value-type based collection. The example I'm
>>>> thinking
>>>> about is the null-ing out of array elements in a collection (which is
>>>> obviously a no-op with a value type, but necessity with reference
>>>> types). Is an interface required in order to define a 'layer' or
>>>> could it
>>>> be done within a concrete class?
>>>>
>>>> E.g. is the following or something similar possible? If not, how
>>>> would it
>>>> be achieved with current spec?
>>>>
>>>> class ArrayList<any T> {
>>>> T[] values;
>>>> int position;
>>>>
>>>> void removeLast() {
>>>> if (position <= 0) {
>>>> return;
>>>> }
>>>>
>>>> --position;
>>>> clear(position);
>>>> }
>>>>
>>>> private void clear(int index) {
>>>> }
>>>>
>>>> layer<ref T> {
>>>> private void clear(int index) {
>>>> values[index] = null;
>>>> }
>>>> }
>>>> }
>>>>
>>>> Mike.
>>>>
>
More information about the valhalla-dev
mailing list