1 diff --git a/src/share/classes/javax/stack/Continuable.java b/src/share/classes/javax/stack/Continuable.java
4 +++ b/src/share/classes/javax/stack/Continuable.java
8 +import java.lang.annotation.*;
11 +@Retention(RetentionPolicy.RUNTIME)
12 +@Target(ElementType.METHOD)
13 +public @interface Continuable{
14 + ContinuableAccess value();
16 diff --git a/src/share/classes/javax/stack/ContinuableAccess.java b/src/share/classes/javax/stack/ContinuableAccess.java
19 +++ b/src/share/classes/javax/stack/ContinuableAccess.java
23 +public enum ContinuableAccess {
24 + HIDDEN, READONLY, READWRITE
26 diff --git a/src/share/classes/javax/stack/Continuation.java b/src/share/classes/javax/stack/Continuation.java
29 +++ b/src/share/classes/javax/stack/Continuation.java
32 + * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
33 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35 + * This code is free software; you can redistribute it and/or modify it
36 + * under the terms of the GNU General Public License version 2 only, as
37 + * published by the Free Software Foundation.
39 + * This code is distributed in the hope that it will be useful, but WITHOUT
40 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42 + * version 2 for more details (a copy is included in the LICENSE file that
43 + * accompanied this code).
45 + * You should have received a copy of the GNU General Public License version
46 + * 2 along with this work; if not, write to the Free Software Foundation,
47 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
49 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
50 + * CA 95054 USA or visit www.sun.com if you need additional information or
51 + * have any questions.
58 +@SuppressWarnings("unused")
59 +public class Continuation {
60 + private static class CONTINUATION_CAPTURED {
63 + public static final Object CAPTURED = CONTINUATION_CAPTURED.class;
64 + private Object data;
65 + private Thread thread;
67 + private static native void registerNatives();
74 + * Saves the current thread state into the continuation object
75 + * @return null if the continuation was saved or the value given to resume if it was resumed
77 + public final native Object save();
80 + * Restores the stack to the state that it had when the continuation was saved.
81 + * @param retValue the value that the save method should return
83 + public final native void resume(Object retValue);
86 + * Yields to the given target continuation, passing along the current continuation
87 + * @param target the continuation that will be reinstated
89 + @Continuable(ContinuableAccess.HIDDEN)
90 + public static final void yield(Continuation target) {
91 + Continuation c = new Continuation();
92 + if (c.save() == null)
97 + * This method will be called by startDelimited
99 + @Continuable(ContinuableAccess.HIDDEN)
100 + private static final Object startDelimitedInternal(DelimitedRunnable runnable, Object firstValue) {
101 + Continuation cont = new Continuation();
102 + Object ret = cont.save();
103 + if (ret == CAPTURED)
104 + runnable.run(cont, firstValue);
108 + public static final native Object startDelimited(DelimitedRunnable runnable, Object firstValue);
111 + * This method will be called by continueDelimited
113 + @Continuable(ContinuableAccess.HIDDEN)
114 + private static final Object continueDelimitedInternal(Continuation cont, Object value) {
115 + cont.resume(value);
119 + public static final native Object continueDelimited(Continuation continuation, Object value);
121 + public final native Object dump();
123 + private static final native Object storeFrameObject(Object retValue);
125 + private static final native void storeFrameVoid();
127 + private static final native boolean storeFrameBoolean(boolean retValue);
129 + private static final native byte storeFrameByte(byte retValue);
131 + private static final native char storeFrameChar(char retValue);
133 + private static final native short storeFrameShort(short retValue);
135 + private static final native int storeFrameInt(int retValue);
137 + private static final native long storeFrameLong(long retValue);
139 + private static final native float storeFrameFloat(float retValue);
141 + private static final native double storeFrameDouble(double retValue);
144 diff --git a/src/share/classes/javax/stack/ContinuationPermission.java b/src/share/classes/javax/stack/ContinuationPermission.java
147 +++ b/src/share/classes/javax/stack/ContinuationPermission.java
149 +package javax.stack;
151 +import java.security.BasicPermission;
153 +/* name is either "resumeSecure" or "resumeUnsecure" */
154 +public class ContinuationPermission extends BasicPermission {
155 + private static final long serialVersionUID = -3608714945512368738L;
157 + public ContinuationPermission(String name) {
161 \ No newline at end of file
162 diff --git a/src/share/classes/javax/stack/DelimitedRunnable.java b/src/share/classes/javax/stack/DelimitedRunnable.java
165 +++ b/src/share/classes/javax/stack/DelimitedRunnable.java
167 +package javax.stack;
169 +public interface DelimitedRunnable {
170 + public void run(Continuation start, Object firstValue);
172 diff --git a/src/share/classes/javax/stack/Fiber.java b/src/share/classes/javax/stack/Fiber.java
175 +++ b/src/share/classes/javax/stack/Fiber.java
177 +package javax.stack;
179 +public abstract class Fiber {
180 + private Continuation returnContinuation;
181 + private Continuation continuation = new Continuation();
183 + private class FiberRunnable implements DelimitedRunnable {
184 + @Continuable(ContinuableAccess.HIDDEN)
185 + public final void run(Continuation start, Object firstValue) {
186 + returnContinuation = start;
187 + Object lastRetValue;
189 + lastRetValue = generate(firstValue);
191 + catch (RuntimeException e) {
192 + e.printStackTrace();
193 + lastRetValue = null;
195 + returnContinuation = null;
196 + start.resume(lastRetValue);
200 + @Continuable(ContinuableAccess.HIDDEN)
201 + protected abstract Object generate(Object firstIn);
203 + @Continuable(ContinuableAccess.HIDDEN)
204 + protected Object yield(Object returnValue) {
205 + Object o = continuation.save();
206 + if (o == Continuation.CAPTURED)
207 + returnContinuation.resume(returnValue);
211 + @Continuable(ContinuableAccess.HIDDEN)
212 + public Object resume(Object value) {
213 + if (returnContinuation == null)
214 + return Continuation.startDelimited(new FiberRunnable(), value);
216 + return Continuation.continueDelimited(continuation, value);
219 + public void dump() {
220 + continuation.dump();
224 diff --git a/test/javax/stack/ContinuationTest1.java b/test/javax/stack/ContinuationTest1.java
227 +++ b/test/javax/stack/ContinuationTest1.java
229 +package javax.stack;
231 +import static org.junit.Assert.assertEquals;
233 +import org.junit.Before;
234 +import org.junit.Test;
236 +public class ContinuationTest1 extends ContinuationTestTools {
238 + public ContinuationTest1() {
239 + interpreted = this;
240 + if (compiled == null)
241 + compiled = new ContinuationTest1Compiled();
245 + public void setUp() throws Exception {
249 + @Continuable(ContinuableAccess.HIDDEN)
250 + public Object subSave(Continuation cont, int a, int b, int c, int d, int e) {
259 + assertEquals(15, i);
260 + assertEquals(ContinuationTest1.class, this.getClass());
261 + assertEquals(Continuation.class, cont.getClass());
265 + private int cnt = 0;
268 + @Continuable(ContinuableAccess.HIDDEN)
269 + public void testRec() {
270 + Integer i = 100000;
271 + Continuation cont = new Continuation();
272 + assertEquals(10102, compiled.subSave(cont, 1, 2, 3, 4, 5));
273 + assertEquals(ContinuationTest1.class, this.getClass());
277 + assertEquals(100000, i);
281 + @Continuable(ContinuableAccess.HIDDEN)
282 + public void testSimple() {
283 + Continuation cont = new Continuation();
285 + if (cont.save() == Continuation.CAPTURED) {
294 + assertActions(new int[] { 1, 2, 3, 4 });
297 + @Continuable(ContinuableAccess.HIDDEN)
298 + int intSub(Continuation c, int code1, Integer code2, int depth) {
304 + lastSaveReturn = c.save();
306 + assertEquals(thisTemp, this);
307 + assertEquals(intTemp, code1);
308 + assertEquals(objTemp, code2);
311 + if ((depth & 3) == 0)
312 + compiled.intSub(c, code1, code2, depth - 1);
314 + intSub(c, code1, code2, depth - 1);
319 + @Continuable(ContinuableAccess.HIDDEN)
320 + Integer objSub(Continuation c, int code1, Integer code2, int depth) {
326 + lastSaveReturn = c.save();
327 + assertEquals(thisTemp, this);
328 + assertEquals(intTemp, code1);
329 + assertEquals(objTemp, code2);
333 + if ((depth & 3) == 0)
334 + compiled.objSub(c, code1, code2, depth - 1);
336 + objSub(c, code1, code2, depth - 1);
341 + @Continuable(ContinuableAccess.HIDDEN)
342 + void resumeRec(Continuation c, Object retValue, int depth) {
347 + if ((depth & 3) == 0)
348 + compiled.resumeRec(c, retValue, depth - 1);
350 + resumeRec(c, retValue, depth - 1);
354 + @Continuable(ContinuableAccess.HIDDEN)
355 + public void testParamsReturnInternal(int resumeDepth, int saveDepth) {
356 + Continuation c = new Continuation();
358 + action(intSub(c, 2, 3, saveDepth));
359 + if (lastSaveReturn == Continuation.CAPTURED) {
361 + if (resumeDepth == 0)
364 + resumeRec(c, null, resumeDepth);
368 + action(compiled.intSub(c, 6, 7, saveDepth));
369 + if (lastSaveReturn == Continuation.CAPTURED) {
371 + if (resumeDepth == 0)
374 + resumeRec(c, null, resumeDepth);
378 + action(objSub(c, 10, 11, saveDepth));
379 + if (lastSaveReturn == Continuation.CAPTURED) {
381 + if (resumeDepth == 0)
384 + resumeRec(c, null, resumeDepth);
388 + action(compiled.objSub(c, 14, 15, saveDepth));
389 + if (lastSaveReturn == Continuation.CAPTURED) {
391 + if (resumeDepth == 0)
394 + resumeRec(c, null, resumeDepth);
398 + assertActions(new int[] { 1, 2, 3, 101, 4, 3, 101, 5, 6, 7, 102, 8, 7, 102, 9, 10, 11, 201, 12, 11, 201, 13, 14, 15, 202,
399 + 16, 15, 202, 17 });
403 + public void testParamsReturn() {
404 + for (int i2 = 1; i2 < 50; i2++) {
405 + for (int i = 0; i < 50; i++) {
406 +// System.out.println("resume: " + i + ", save: " + i2);
408 + testParamsReturnInternal(i, i2);
415 + @Continuable(ContinuableAccess.HIDDEN)
416 + public void testManyParams() {
417 + Continuation cont = new Continuation();
418 + if (manyParamsSub(cont, 5, true, false, 1, (short) 2, (byte) 3, (char) 4, (long) 5, 6, (short) 7, (byte) 8, (char) 9,
419 + (long) 10, (float) 11, (double) 12, (float) 13, (double) 14, 15, 16, 17, 18, 19, 20) == Continuation.CAPTURED)
423 + @Continuable(ContinuableAccess.HIDDEN)
424 + private Object manyParamsSub(Continuation cont, int depth, boolean a, boolean b, int c, short d, byte e, char f,
425 + long g, Integer h, Short i, Byte j, Character k, Long l, float m, double n, Float o, Double p, Integer q, int r,
426 + int s, int t, int u, int v) {
429 + ret = manyParamsSub(cont, depth - 1, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v);
432 + assertEquals(cont.getClass(), Continuation.class);
433 + assertEquals(a, true);
434 + assertEquals(b, false);
435 + assertEquals(c, 1);
436 + assertEquals(d, (short) 2);
437 + assertEquals(e, (byte) 3);
438 + assertEquals(f, (char) 4);
439 + assertEquals(g, (long) 5);
440 + assertEquals(h, 6);
441 + assertEquals(i, (short) 7);
442 + assertEquals(j, (byte) 8);
443 + assertEquals(k, (char) 9);
444 + assertEquals(l, (long) 10);
445 + assertEquals(m, (float) 11);
446 + assertEquals(n, (double) 12);
447 + assertEquals(o, (float) 13);
448 + assertEquals(p, (double) 14);
449 + assertEquals(q, 15);
450 + assertEquals(r, 16);
451 + assertEquals(s, 17);
452 + assertEquals(t, 18);
453 + assertEquals(u, 19);
454 + assertEquals(v, 20);
458 diff --git a/test/javax/stack/ContinuationTest1Compiled.java b/test/javax/stack/ContinuationTest1Compiled.java
461 +++ b/test/javax/stack/ContinuationTest1Compiled.java
463 +package javax.stack;
465 +import static org.junit.Assert.assertEquals;
467 +import org.junit.Before;
468 +import org.junit.Test;
470 +public class ContinuationTest1Compiled extends ContinuationTestTools {
472 + public ContinuationTest1Compiled() {
474 + if (interpreted == null)
475 + interpreted = new ContinuationTest1();
479 + public void setUp() throws Exception {
483 + @Continuable(ContinuableAccess.HIDDEN)
484 + public Object subSave(Continuation cont, int a, int b, int c, int d, int e) {
493 + assertEquals(15, i);
494 + assertEquals(ContinuationTest1Compiled.class, this.getClass());
495 + assertEquals(Continuation.class, cont.getClass());
499 + private int cnt = 0;
502 + @Continuable(ContinuableAccess.HIDDEN)
503 + public void testRec() {
504 + Integer i = 100000;
505 + Continuation cont = new Continuation();
506 + assertEquals(10102, interpreted.subSave(cont, 1, 2, 3, 4, 5));
507 + assertEquals(ContinuationTest1Compiled.class, this.getClass());
510 + assertEquals(100000, i);
514 + @Continuable(ContinuableAccess.HIDDEN)
515 + public void testSimple() {
516 + Continuation cont = new Continuation();
518 + if (cont.save() == Continuation.CAPTURED) {
527 + assertActions(new int[] { 1, 2, 3, 4 });
530 + @Continuable(ContinuableAccess.HIDDEN)
531 + int intSub(Continuation c, int code1, Integer code2, int depth) {
536 + lastSaveReturn = c.save();
537 + assertEquals(intTemp, code1);
538 + assertEquals(objTemp, code2);
542 + if ((depth & 3) == 0)
543 + interpreted.intSub(c, code1, code2, depth - 1);
545 + intSub(c, code1, code2, depth - 1);
550 + @Continuable(ContinuableAccess.HIDDEN)
551 + Integer objSub(Continuation c, int code1, Integer code2, int depth) {
556 + lastSaveReturn = c.save();
557 + assertEquals(intTemp, code1);
558 + assertEquals(objTemp, code2);
562 + if ((depth & 3) == 0)
563 + interpreted.objSub(c, code1, code2, depth - 1);
565 + objSub(c, code1, code2, depth - 1);
570 + @Continuable(ContinuableAccess.HIDDEN)
571 + void resumeRec(Continuation c, Object retValue, int depth) {
576 + if ((depth & 3) == 0)
577 + interpreted.resumeRec(c, retValue, depth - 1);
579 + resumeRec(c, retValue, depth - 1);
583 + @Continuable(ContinuableAccess.HIDDEN)
584 + public void testParamsReturnInternal(int resumeDepth, int saveDepth) {
585 + Continuation c = new Continuation();
587 + action(interpreted.intSub(c, 2, 3, saveDepth));
588 + if (lastSaveReturn == Continuation.CAPTURED) {
590 + if (resumeDepth == 0)
593 + resumeRec(c, null, resumeDepth);
597 + action(intSub(c, 6, 7, saveDepth));
598 + if (lastSaveReturn == Continuation.CAPTURED) {
600 + if (resumeDepth == 0)
603 + resumeRec(c, null, resumeDepth);
607 + action(interpreted.objSub(c, 10, 11, saveDepth));
608 + if (lastSaveReturn == Continuation.CAPTURED) {
610 + if (resumeDepth == 0)
613 + resumeRec(c, null, resumeDepth);
617 + action(objSub(c, 14, 15, saveDepth));
618 + if (lastSaveReturn == Continuation.CAPTURED) {
620 + if (resumeDepth == 0)
623 + resumeRec(c, null, resumeDepth);
627 + assertActions(new int[] { 1, 2, 3, 101, 4, 3, 101, 5, 6, 7, 102, 8, 7, 102, 9, 10, 11, 201, 12, 11, 201, 13, 14, 15, 202,
628 + 16, 15, 202, 17 });
632 + public void testParamsReturn() {
633 + for (int i2 = 0; i2 < 50; i2++) {
634 + for (int i = 0; i < 50; i++) {
635 + // System.out.println("resume: " + i + ", save: " + i2);
637 + testParamsReturnInternal(i, i2);
644 + @Continuable(ContinuableAccess.HIDDEN)
645 + public void testManyParams() {
646 + Continuation cont = new Continuation();
647 + if (manyParamsSub(cont, 5, true, false, 1, (short) 2, (byte) 3, (char) 4, (long) 5, 6, (short) 7, (byte) 8, (char) 9,
648 + (long) 10, (float) 11, (double) 12, (float) 13, (double) 14, 15, 16, 17, 18, 19, 20) == Continuation.CAPTURED)
652 + @Continuable(ContinuableAccess.HIDDEN)
653 + private Object manyParamsSub(Continuation cont, int depth, boolean a, boolean b, int c, short d, byte e, char f, long g,
654 + Integer h, Short i, Byte j, Character k, Long l, float m, double n, Float o, Double p, Integer q, int r, int s,
655 + int t, int u, int v) {
658 + ret = manyParamsSub(cont, depth - 1, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v);
661 + assertEquals(cont.getClass(), Continuation.class);
662 + assertEquals(a, true);
663 + assertEquals(b, false);
664 + assertEquals(c, 1);
665 + assertEquals(d, (short) 2);
666 + assertEquals(e, (byte) 3);
667 + assertEquals(f, (char) 4);
668 + assertEquals(g, (long) 5);
669 + assertEquals(h, 6);
670 + assertEquals(i, (short) 7);
671 + assertEquals(j, (byte) 8);
672 + assertEquals(k, (char) 9);
673 + assertEquals(l, (long) 10);
674 + assertEquals(m, (float) 11);
675 + assertEquals(n, (double) 12);
676 + assertEquals(o, (float) 13);
677 + assertEquals(p, (double) 14);
678 + assertEquals(q, 15);
679 + assertEquals(r, 16);
680 + assertEquals(s, 17);
681 + assertEquals(t, 18);
682 + assertEquals(u, 19);
683 + assertEquals(v, 20);
688 diff --git a/test/javax/stack/ContinuationTestTools.java b/test/javax/stack/ContinuationTestTools.java
691 +++ b/test/javax/stack/ContinuationTestTools.java
693 +package javax.stack;
695 +import static org.junit.Assert.assertEquals;
697 +import java.util.ArrayList;
698 +import java.util.Stack;
700 +public class ContinuationTestTools {
701 + private static Stack<ArrayList<Integer>> actions = new Stack<ArrayList<Integer>>();
703 + protected static Object thisTemp;
704 + protected static Object objTemp;
705 + protected static int intTemp;
706 + protected static Object lastSaveReturn = null;
708 + protected static ContinuationTest1Compiled compiled;
709 + protected static ContinuationTest1 interpreted;
711 + protected static void clearActions() {
713 + actions.add(new ArrayList<Integer>());
716 + protected static void pushActions() {
717 + actions.push(new ArrayList<Integer>());
720 + protected static void popActions() {
724 + protected static void action(int code) {
725 + actions.peek().add(code);
728 + protected static void assertActions(int[] expectedActions) {
729 + if (expectedActions.length == actions.peek().size()) {
730 + for (int i = 0; i < expectedActions.length; i++)
731 + assertEquals(expectedActions[i], actions.peek().get(i));
734 + System.out.print("expected: ");
735 + for (int i = 0; i < expectedActions.length; i++)
736 + System.out.print(expectedActions[i] + " ");
737 + System.out.print("\nactual: ");
738 + for (int i = 0; i < actions.peek().size(); i++)
739 + System.out.print(actions.peek().get(i) + " ");
741 + assertEquals(expectedActions.length, actions.peek().size());
746 diff --git a/test/javax/stack/DelimitedTest.java b/test/javax/stack/DelimitedTest.java
749 +++ b/test/javax/stack/DelimitedTest.java
751 +package javax.stack;
753 +import java.io.IOException;
755 +import org.junit.Test;
757 +public class DelimitedTest {
759 + class TestFiber extends Fiber {
760 + @Continuable(ContinuableAccess.HIDDEN)
761 + protected Object generate(Object value) {
762 + int i = (Integer) value;
764 + i += (Integer) yield(i);
769 + private static final long COUNT = 5000;
770 + private static final long COUNT2 = 100;
773 + @Continuable(ContinuableAccess.HIDDEN)
774 + public void testRec() throws IOException {
776 + Continuation cont = new Continuation();
779 + long time = System.nanoTime();
780 + for (int i2 = 0; i2 < COUNT2; i2++) {
781 + TestFiber test = new TestFiber();
782 + for (int i = 0; i < COUNT; i++) {
783 + Object ret = test.resume(i);
784 + int result = (Integer) ret;
787 + long tps = (long) (COUNT * COUNT2 * 1000000000d / (System.nanoTime() - time));
788 + System.out.println(tps);
792 + catch (Throwable e) {
793 + e.printStackTrace();
798 \ No newline at end of file