Lukas Stadler is my hero,  at last JVM summit,  he just explain how coroutine and friends can be  implemented in the VM  and guess what, it now works (currently only with C1).  
Let's try to implement something with it.

Generator

I have always wanted to have generator   in Java. After all, Python have this feature, Ruby and C#(*) too.  
A generator is a way to define an iterator but instead of implementing hasNext()/next(),   you just implement a method (here generate) and use the keyword yield (or here a method yield)   to send value that will be returned by next().   This is really useful because writing complex iterator is really like to write a state machine (not that fun),   it's far easier to define the iterator as a method and use the stack of that method to store the state of the iterator.

The implementation is based on continuation, yield stops the current execution and saves the stack frames as an object,   the value passed as argument to yield is received by the method next of the iterator. When next next is called,   the continuation is resumed, so the execution is restarted just after the yield. 
The current implementation of the continuation in the VM imposes that the methods corresponding to stack frames   stored in a continuation must be marked with annotation @Continuable.

(*) There is some weird limitations in C# but a friend of mine says to me that C# 4 doesn't have them anymore.

By example, this generator specifies an iterator that will return the Fibonacci's numbers:

  public class FibonacciGenerator extends AbstractGenerator {
    @Override
    @Continuable     protected void generate() {       int last = 1;       int current = 1;              for(int i=0; i<5; i++) {         yield(current);
       
        int tmp = current;
        current = current + last;
        last = tmp;
      }
    }
 
    public static void main(String[] args) {
      for(int value : new FibonacciGenerator()) {
        System.out.println("value "+value);
      }
    }
  }

If you want to test it, there is two solutions:

       
  1. Build the Da Vinci VM with only        callcc patch enabled (comment all other patches).        Don't forget that only C1 works.
  2.    
  3. If you use a Linux (I use a Fedora 11), I've already compiled a VM        with callcc patch. So download jdk7-b75 binaries, and unzip        coroutine-VM.zip        in directory jre/lib/i386. You also need to download        coroutine.jar        that contains Java classes to play with the different kinds of continuations.

And to run it:

 

  $ /usr/jdk/jdk1.7.0b75/bin/java -coroutine -Xbootclasspath/p:coroutine.jar -cp classes FibonacciGeneratorTest
  value 1
  value 2
  value 3
  value 5
  value 8

The code of the abstract generator is here:

public abstract class AbstractGenerator implements Iterator, Iterable {
  final class GeneratorFiber extends Fiber {
    @Override
    @Continuable
    protected Object generate(Object arg) {
      AbstractGenerator.this.generate();
      return END;
    }
   
    @Continuable
    void doYield(Object o) {
      yield(o);
    }
  }
 
  @SuppressWarnings("unchecked")
  private E element = (E)NONE;
  private final GeneratorFiber fiber = new GeneratorFiber();
 
  private static final Object NONE = new Object();
  static final Object END = new Object();
 
  protected abstract void generate();
 
  @Continuable
  protected final void yield(E element) {
    fiber.doYield(element);
  }
 
  @Override
  @Continuable
  @SuppressWarnings("unchecked")
  public final boolean hasNext() {
    E element = this.element;
    if (element != NONE && element != END)
      return true;
   
    element = (E)fiber.resume(null);
    this.element = element;
    return element != END;
  }
 
  @Override
  @Continuable
  @SuppressWarnings("unchecked")
  public final E next() {
    if (!hasNext())
      throw new NoSuchElementException();
    E element = this.element;
    this.element = (E)NONE;
    return element;
  }
 
  @Override
  public final void remove() {
    throw new UnsupportedOperationException();
  }
 
  @Override
  public final Iterator iterator() {
    return this;
  }
}

Cheers,
Rémi