StackOverflowError on Stream primitive iterator

Brian Goetz brian.goetz at oracle.com
Tue May 7 09:50:26 PDT 2013


So, the good news here is that this is an interaction caused by skew 
between two components.  We're moving the repsonsibility for bridge 
methods from the VM to the compiler, and in the lambda repo, currently 
BOTH are active.  In most cases the compiler-generated bridges wins and 
all is good.  Here, there's some bleed-through from the older VM bridge 
implementation.  When the new VM implementation is put back to lambda 
all will be well again.

On 5/7/2013 6:09 AM, Paul Sandoz wrote:
> $ javap java/util/PrimitiveIterator\$OfDouble.class
> Compiled from "PrimitiveIterator.java"
> public interface java.util.PrimitiveIterator$OfDouble extends java.util.PrimitiveIterator<java.lang.Double> {
>    public abstract double nextDouble();
>    public void forEachRemaining(java.util.function.DoubleConsumer);
>    public java.lang.Double next();
>    public void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>);
>    public java.lang.Object next();
> }
>
> A bridge method is generated for "Object next()", the implementation is:
>
>    public java.lang.Object next();
>      descriptor: ()Ljava/lang/Object;
>      flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
>      Code:
>        stack=1, locals=1, args_size=1
>           0: aload_0
>           1: invokeinterface #13,  1           // InterfaceMethod next:()Ljava/lang/Double;
>           6: areturn
>        LineNumberTable:
>          line 208: 0
>        LocalVariableTable:
>          Start  Length  Slot  Name   Signature
>                 0       7     0  this   Ljava/util/PrimitiveIterator$OfDouble;
>
>
> So i think what is happening is method dispatch is always going to the bridge method hence the stack overflow.
>
> The example below can reproduce the problem. However, AFAICT the issue is only triggered when there are 2 or more default methods present. Comment out the default method something() and the example runs without error.
>
> Paul.
>
> import java.util.Iterator;
> import java.util.function.Consumer;
> import java.util.function.DoubleConsumer;
>
> public class A {
>
>      public static interface OfDouble extends Iterator<Double> {
>
>          // This causes the stack overflow
>          default void something() {}
>
>          double nextDouble();
>
>          default Double next() {
>              return nextDouble();
>          }
>      }
>
>      public static void main(String[] args) {
>          class Adapter implements OfDouble {
>              public boolean hasNext() { return true; }
>              public double nextDouble() { return 1.0; }
>          }
>          OfDouble i = new Adapter();
>
>          Double s = i.next();
>      }
> }
>
>
> On May 7, 2013, at 11:11 AM, Paul Sandoz <Paul.Sandoz at oracle.com> wrote:
>
>> I can reproduce. It could either be a compiler error or hotspot method dispatch error or both when invoking default methods. Digging deeper...
>>
>> Paul.
>>
>>
>> On May 7, 2013, at 8:51 AM, Boaz Nahum <boaznahum at gmail.com> wrote:
>>
>>> OK. I pull minutes ago latest from lambda/lambda and perform 'make clean
>>> images'
>>>
>>> I *rebuild** my code*
>>>
>>> Still got same error
>>>
>>> Boaz
>>
>
>


More information about the lambda-dev mailing list