/
ExYieldStack.java
executable file
·136 lines (113 loc) · 4.02 KB
/
ExYieldStack.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package kilim.test.ex;
import kilim.Pausable;
import kilim.Task;
public class ExYieldStack extends ExYieldBase {
public ExYieldStack(int test) {
testCase = test;
}
public void execute() throws Pausable {
doPause = false;
test();
doPause = true;
test();
}
private void test() throws Pausable {
switch (testCase) {
case 0: testStackBottom_st(); break;
case 1: testStackBottom_v(); break;
case 2: testStackBottom_av(); break;
case 3: testFactorial_st(); break;
case 4: testFactorial_av(); break;
default: new IllegalStateException("Unknown testCase " + testCase);
}
}
// load stack with a number of types, call a static pausable method
// The call to verify ensures that the stack is loaded with
// a few elements before the call to pausable_x is made.
void testStackBottom_st() throws Pausable {
verify(fd, fs, fl, fa, pausable_st(10, doPause));
}
// load stack with a number of types, call a virtual pausable method
void testStackBottom_v() throws Pausable {
verify(fd, fs, pausable_v(fl), fa, ff);
}
// load stack with a number of types, call a virtual pausable method
// on another object
void testStackBottom_av() throws Pausable {
verify(fd, fs, fl, fa, new ExYieldStack(testCase).pausable_v(10));
}
// test a deep hierarchy that makes the state stack grow, have
// long parameters and return values, and pause in the middle
// of the computation so it is saves longs on the stack
void testFactorial_st() throws Pausable {
long n = fact_st(15L, doPause);
if (n != 1307674368000L) {
throw new RuntimeException("Incorrect factorial, n =" + n);
}
}
// Issue 8 on github
void testLoop() throws Pausable {
// The other tests don't test constant propagation, but not dynamic operands
// on stack.
}
static long fact_st(long n, boolean doPause) throws Pausable {
// System.out.println("n = " + n + ", doPause = " + doPause);
if (n == 1) {
if (doPause) Task.sleep(10);
return 1L;
}
if (n == 10) {
// Initial state stack is 10 elements long, so it is worth
// testing a pause here.
if (doPause) Task.sleep(10);
}
return n * fact_st(n-1, doPause);
}
void testFactorial_av() throws Pausable {
long n = new ExYieldStack(testCase).fact_av(15L, doPause);
if (n != 1307674368000L) {
throw new RuntimeException("Incorrect factorial, n =" + n);
}
}
long fact_av(long n, boolean doPause) throws Pausable {
if (n == 1) {
if (doPause) Task.sleep(50);
return 1L;
}
if (n == 10) {
// Initial state stack is 10 elements long, so it is worth
// testing a pause here.
if (doPause) Task.sleep(50);
}
return n * new ExYieldStack(testCase).fact_av(n-1, doPause);
}
static float pausable_st(int i, boolean doPause) throws Pausable {
if (doPause) {
Task.sleep(50);
}
return 11.0f;
}
long pausable_v(long l) throws Pausable {
if (doPause) {
Task.sleep(50);
}
return l;
}
static void verify(double ad, Object as, long al, Object aa, float aii) {
verify(ad);
verify((String) as);
verify(al);
verify((String[][]) aa);
}
void dummySyncTest() throws Pausable {
// just making sure that the weaver doesn't barf if we call
// call a pausable function from _outside_ a synchronized block.
synchronized(this) {
notify(); // dummy non-pausable method in a sync block
}
pausable_st(0, false);
synchronized(this) {
notify(); // dummy non-pausable method in a sync block
}
}
}