/
Scanning.java
175 lines (160 loc) · 6.15 KB
/
Scanning.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
* 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.vm;
import org.mmtk.harness.Mutator;
import org.mmtk.plan.TraceLocal;
import org.mmtk.plan.TransitiveClosure;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.*;
@Uninterruptible
public class Scanning extends org.mmtk.vm.Scanning {
/**
* Delegated scanning of a object, processing each pointer field
* encountered.
*
* @param object The object to be scanned.
*/
public void scanObject(TransitiveClosure trace, ObjectReference object) {
int refs = ObjectModel.getRefs(object);
Address first = object.toAddress().plus(ObjectModel.REFS_OFFSET);
for (int i=0; i < refs; i++) {
trace.processEdge(object, first.plus(i << LOG_BYTES_IN_ADDRESS));
}
}
/**
* Invoke a specialized scan method. Note that these methods must have been allocated
* explicitly through Plan and PlanConstraints.
*
* @param id The specialized method id
* @param trace The trace the method has been specialized for
* @param object The object to be scanned
*/
public void specializedScanObject(int id, TransitiveClosure trace, ObjectReference object) {
scanObject(trace, object);
}
/**
* Delegated precopying of a object's children, processing each pointer field
* encountered.
*
* @param trace The trace object to use for precopying.
* @param object The object to be scanned.
*/
public void precopyChildren(TraceLocal trace, ObjectReference object) {
scanObject(trace, object);
}
/** Counter for computeThreadRoots **/
private int threadCounter;
/**
* Prepares for using the <code>computeAllRoots</code> method. The
* thread counter allows multiple GC threads to co-operatively
* iterate through the thread data structure (if load balancing
* parallel GC threads were not important, the thread counter could
* simply be replaced by a for loop).
*/
public synchronized void resetThreadCounter() {
threadCounter = 0;
}
/**
* Pre-copy all potentially movable instances used in the course of
* GC. This includes the thread objects representing the GC threads
* themselves. It is crucial that these instances are forwarded
* <i>prior</i> to the GC proper. Since these instances <i>are
* not</i> enqueued for scanning, it is important that when roots
* are computed the same instances are explicitly scanned and
* included in the set of roots. The existence of this method
* allows the actions of calculating roots and forwarding GC
* instances to be decoupled.
*/
public void preCopyGCInstances(TraceLocal trace) {
/* None */
}
/**
* Computes static roots. This method establishes all such roots for
* collection and places them in the root locations queue. This method
* should not have side effects (such as copying or forwarding of
* objects). There are a number of important preconditions:
*
* <ul>
* <li> All objects used in the course of GC (such as the GC thread
* objects) need to be "pre-copied" prior to calling this method.
* <li> The <code>threadCounter</code> must be reset so that load
* balancing parallel GC can share the work of scanning threads.
* </ul>
*
* @param trace The trace to use for computing roots.
*/
public void computeStaticRoots(TraceLocal trace) {
/* None */
}
/**
* Computes global roots. This method establishes all such roots for
* collection and places them in the root locations queue. This method
* should not have side effects (such as copying or forwarding of
* objects). There are a number of important preconditions:
*
* <ul>
* <li> All objects used in the course of GC (such as the GC thread
* objects) need to be "pre-copied" prior to calling this method.
* <li> The <code>threadCounter</code> must be reset so that load
* balancing parallel GC can share the work of scanning threads.
* </ul>
*
* @param trace The trace to use for computing roots.
*/
public void computeGlobalRoots(TraceLocal trace) {
/* None */
}
/**
* Computes roots pointed to by threads, their associated registers
* and stacks. This method places these roots in the root values,
* root locations and interior root locations queues. This method
* should not have side effects (such as copying or forwarding of
* objects). There are a number of important preconditions:
*
* <ul>
* <li> All objects used in the course of GC (such as the GC thread
* objects) need to be "pre-copied" prior to calling this method.
* <li> The <code>threadCounter</code> must be reset so that load
* balancing parallel GC can share the work of scanning threads.
* </ul>
*
* @param trace The trace to use for computing roots.
*/
public void computeThreadRoots(TraceLocal trace) {
while(true) {
int myIndex;
synchronized(this) {
myIndex = threadCounter++;
}
if (myIndex >= Mutator.count()) {
break;
}
Mutator.get(myIndex).computeThreadRoots(trace);
}
}
/**
* Compute all roots out of the VM's boot image (if any). This method is a no-op
* in the case where the VM does not maintain an MMTk-visible Java space. However,
* when the VM does maintain a space (such as a boot image) which is visible to MMTk,
* that space could either be scanned by MMTk as part of its transitive closure over
* the whole heap, or as a (considerable) performance optimization, MMTk could avoid
* scanning the space if it is aware of all pointers out of that space. This method
* is used to establish the root set out of the scannable space in the case where
* such a space exists.
*
* @param trace The trace object to use to report root locations.
*/
public void computeBootImageRoots(TraceLocal trace) {
/* None */
}
}