Question on layer/peeling

Peter Levart peter.levart at gmail.com
Tue Jan 6 09:41:27 UTC 2015


Hi,

Here's another one:


public final class Box<any T> {

     private T value;

     public Box(T value) {
         this.value = value;
     }

     public Box() {
         // leave default value
     }

     public T get() {
         return value;
     }

     @SuppressWarnings("unchecked")
     @Override
     public boolean equals(Object obj) {
         return (this == obj) ||
             (obj != null &&
                 this.getClass() == obj.getClass() && // same 
specialization, right?
                 this.get() == ((Box<T>)obj).get());
                 // I think the bytecode to compare two references is 
not specialized here to compare two integers
     }
}


public class Test {
     public static void main(String[] args) {
         System.out.println(new Box<int>(1).equals(new Box<int>(1)));
     }
}


I get the following at run time:


Specializing util.Box${0=I}; searching for util/Box.class (not found)
Specializing util.Box${0=I}; searching for util/Box.class (found)
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
   Location:
     util/Box${0=I}.equals(Ljava/lang/Object;)Z @31: if_acmpne
   Reason:
     Type integer (current frame, stack[1]) is not assignable to 
reference type
   Current Frame:
     bci: @31
     flags: { }
     locals: { 'util/Box${0=I}', 'java/lang/Object' }
     stack: { integer, integer }
   Bytecode:
     0000000: 2a2b a500 202b c600 202a b600 172b b600
     0000010: 17a6 0015 2ab6 0019 2bc0 0002 b600 19a6
     0000020: 0007 04a7 0004 03ac
   Stackmap Table:
     same_frame(@34)
     same_frame(@38)
     same_locals_1_stack_item_frame(@39,Integer)

         at util.Test.main(Test.java:8)


Regards, Peter

On 01/06/2015 09:21 AM, 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