/
GenImmixCollector.java
183 lines (163 loc) · 6.21 KB
/
GenImmixCollector.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
176
177
178
179
180
181
182
183
/*
* 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.plan.generational.immix;
import org.mmtk.plan.Plan;
import org.mmtk.plan.TraceLocal;
import org.mmtk.plan.generational.*;
import org.mmtk.policy.Space;
import org.mmtk.utility.alloc.Allocator;
import org.mmtk.utility.alloc.ImmixAllocator;
import org.mmtk.utility.statistics.Stats;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.*;
import org.vmmagic.unboxed.*;
/**
* This class implements <i>per-collector thread</i> behavior and state for
* the <code>GenImmix</code> two-generational copying collector.<p>
*
* Specifically, this class defines semantics specific to the collection of
* the copy generation (<code>GenCollector</code> defines nursery semantics).
* In particular the copy space allocator is defined (for collection-time
* allocation into the copy space), and the copy space per-collector thread
* collection time semantics are defined.<p>
*
* @see GenImmix for a description of the <code>GenImmix</code> algorithm.
*
* @see GenImmix
* @see GenImmixMutator
* @see GenCollector
* @see org.mmtk.plan.StopTheWorldCollector
* @see org.mmtk.plan.CollectorContext
*/
@Uninterruptible
public class GenImmixCollector extends GenCollector {
/*****************************************************************************
*
* Instance fields
*/
private final GenImmixMatureTraceLocal matureTrace = new GenImmixMatureTraceLocal(global().matureTrace, this);
private final GenImmixMatureDefragTraceLocal defragTrace = new GenImmixMatureDefragTraceLocal(global().matureTrace, this);
private final org.mmtk.policy.immix.CollectorLocal immix = new org.mmtk.policy.immix.CollectorLocal(GenImmix.immixSpace);
private final ImmixAllocator copy = new ImmixAllocator(GenImmix.immixSpace, true, false);
private final ImmixAllocator defragCopy = new ImmixAllocator(GenImmix.immixSpace, true, true);
/****************************************************************************
*
* Collection-time allocation
*/
/**
* Allocate space for copying an object (this method <i>does not</i>
* copy the object, it only allocates space)
*
* @param original A reference to the original object
* @param bytes The size of the space to be allocated (in bytes)
* @param align The requested alignment.
* @param offset The alignment offset.
* @param allocator The allocator to use.
* @return The address of the first byte of the allocated region
*/
@Inline
public final Address allocCopy(ObjectReference original, int bytes,
int align, int offset, int allocator) {
if (Stats.GATHER_MARK_CONS_STATS) {
if (Space.isInSpace(GenImmix.NURSERY, original)) GenImmix.nurseryMark.inc(bytes);
}
if (allocator == Plan.ALLOC_LOS) {
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.LOS_SIZE_THRESHOLD);
return los.alloc(bytes, align, offset);
} else {
if (VM.VERIFY_ASSERTIONS) {
VM.assertions._assert(bytes <= Plan.LOS_SIZE_THRESHOLD);
VM.assertions._assert((!GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MINORGC) ||
(GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MAJORGC));
}
if (GenImmix.immixSpace.inImmixDefragCollection()) {
return defragCopy.alloc(bytes, align, offset);
} else
return copy.alloc(bytes, align, offset);
}
}
/**
* Perform any post-copy actions.
*
* @param object The newly allocated object
* @param typeRef the type reference for the instance being created
* @param bytes The size of the space to be allocated (in bytes)
*/
@Inline
public final void postCopy(ObjectReference object, ObjectReference typeRef,
int bytes, int allocator) {
if (allocator == Plan.ALLOC_LOS)
Plan.loSpace.initializeHeader(object, false);
else {
if (VM.VERIFY_ASSERTIONS) {
VM.assertions._assert((!GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MINORGC) ||
(GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MAJORGC));
}
GenImmix.immixSpace.postCopy(object, bytes, allocator == GenImmix.ALLOC_MATURE_MAJORGC);
}
if (Gen.USE_OBJECT_BARRIER)
Plan.markAsUnlogged(object);
}
/*****************************************************************************
*
* Collection
*/
/**
* Perform a (local) collection phase.
*
* @param phaseId Collection phase to perform
* @param primary Is this thread to do the one-off thread-local tasks
*/
@NoInline
public void collectionPhase(short phaseId, boolean primary) {
TraceLocal trace = GenImmix.immixSpace.inImmixDefragCollection() ? defragTrace : matureTrace;
if (global().traceFullHeap()) {
if (phaseId == GenImmix.PREPARE) {
super.collectionPhase(phaseId, primary);
trace.prepare();
copy.reset();
if (global().gcFullHeap) {
immix.prepare(true);
defragCopy.reset();
}
return;
}
if (phaseId == GenImmix.CLOSURE) {
trace.completeTrace();
return;
}
if (phaseId == GenImmix.RELEASE) {
trace.release();
if (global().gcFullHeap) {
immix.release(true);
}
super.collectionPhase(phaseId, primary);
return;
}
}
super.collectionPhase(phaseId, primary);
}
@Inline
public final TraceLocal getFullHeapTrace() {
return GenImmix.immixSpace.inImmixDefragCollection() ? defragTrace : matureTrace;
}
/****************************************************************************
*
* Miscellaneous
*/
/** @return The active global plan as a <code>GenImmix</code> instance. */
@Inline
private static GenImmix global() {
return (GenImmix) VM.activePlan.global();
}
}