/
Env.java
123 lines (105 loc) · 2.66 KB
/
Env.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
/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.mmtk.harness.lang;
import java.util.Random;
import java.util.Stack;
import org.mmtk.harness.Mutator;
import org.mmtk.harness.lang.Trace.Item;
import org.mmtk.harness.lang.runtime.StackFrame;
import org.mmtk.plan.TraceLocal;
import org.vmmagic.unboxed.ObjectReference;
/**
* An execution environment
*/
public class Env extends Mutator {
private static boolean gcEverySafepoint = false;
/**
* The stack
*/
private UnsyncStack<StackFrame> stack = new UnsyncStack<StackFrame>();
/**
* A source of random numbers (we have one per thread so that we can write
* deterministic scripts).
*/
private Random rng = new Random();
public static void setGcEverySafepoint() {
gcEverySafepoint = true;
}
/**
* Enter a new procedure, pushing a new stack frame.
* @param frame
*/
public void push(StackFrame frame) {
stack.push(frame);
Trace.trace(Item.ENV,"push()");
}
/**
* Exit from a procedure, popping the top stack frame.
*/
public void pop() {
stack.pop();
Trace.trace(Item.ENV,"pop()");
}
/**
* The frame at the top of the stack.
*/
public StackFrame top() {
return stack.peek();
}
/**
*
*/
public Iterable<StackFrame> stack() {
return stack;
}
/**
* Compute the thread roots for this mutator.
*/
@Override
public void computeThreadRoots(TraceLocal trace) {
int localCount = 0;
for (StackFrame frame : stack) {
localCount += frame.computeRoots(trace);
}
Trace.trace(Item.ROOTS, "Locals: %d", localCount);
}
/**
* Print the thread roots and add them to a stack for processing.
*/
@Override
public void dumpThreadRoots(int width, Stack<ObjectReference> roots) {
int frameId = 0;
for (StackFrame frame : stack) {
System.err.printf(" Frame %5d [", frameId++);
frame.dumpRoots(width, roots);
System.err.println(" ]");
}
System.err.println();
}
@Override
public boolean gcSafePoint() {
if (gcEverySafepoint) {
gc();
}
return super.gcSafePoint();
}
/*******************************************************************
* Utility methods
*/
/**
* @return The per-thread random number generator
*/
public Random random() {
return rng;
}
}