equal
deleted
inserted
replaced
26 #define SHARE_VM_GC_SHARED_SPACE_INLINE_HPP |
26 #define SHARE_VM_GC_SHARED_SPACE_INLINE_HPP |
27 |
27 |
28 #include "gc/serial/markSweep.inline.hpp" |
28 #include "gc/serial/markSweep.inline.hpp" |
29 #include "gc/shared/collectedHeap.hpp" |
29 #include "gc/shared/collectedHeap.hpp" |
30 #include "gc/shared/generation.hpp" |
30 #include "gc/shared/generation.hpp" |
31 #include "gc/shared/liveRange.hpp" |
|
32 #include "gc/shared/space.hpp" |
31 #include "gc/shared/space.hpp" |
33 #include "gc/shared/spaceDecorator.hpp" |
32 #include "gc/shared/spaceDecorator.hpp" |
34 #include "memory/universe.hpp" |
33 #include "memory/universe.hpp" |
35 #include "runtime/prefetch.inline.hpp" |
34 #include "runtime/prefetch.inline.hpp" |
36 #include "runtime/safepoint.hpp" |
35 #include "runtime/safepoint.hpp" |
115 HeapWord* t = space->scan_limit(); |
114 HeapWord* t = space->scan_limit(); |
116 |
115 |
117 HeapWord* end_of_live= q; // One byte beyond the last byte of the last |
116 HeapWord* end_of_live= q; // One byte beyond the last byte of the last |
118 // live object. |
117 // live object. |
119 HeapWord* first_dead = space->end(); // The first dead object. |
118 HeapWord* first_dead = space->end(); // The first dead object. |
120 LiveRange* liveRange = NULL; // The current live range, recorded in the |
|
121 // first header of preceding free area. |
|
122 space->_first_dead = first_dead; |
|
123 |
119 |
124 const intx interval = PrefetchScanIntervalInBytes; |
120 const intx interval = PrefetchScanIntervalInBytes; |
125 |
121 |
126 while (q < t) { |
122 while (q < t) { |
127 assert(!space->scanned_block_is_obj(q) || |
123 assert(!space->scanned_block_is_obj(q) || |
156 } |
152 } |
157 } |
153 } |
158 |
154 |
159 // otherwise, it really is a free region. |
155 // otherwise, it really is a free region. |
160 |
156 |
161 // for the previous LiveRange, record the end of the live objects. |
157 // q is a pointer to a dead object. Use this dead memory to store a pointer to the next live object. |
162 if (liveRange) { |
158 (*(HeapWord**)q) = end; |
163 liveRange->set_end(q); |
|
164 } |
|
165 |
|
166 // record the current LiveRange object. |
|
167 // liveRange->start() is overlaid on the mark word. |
|
168 liveRange = (LiveRange*)q; |
|
169 liveRange->set_start(end); |
|
170 liveRange->set_end(end); |
|
171 |
159 |
172 // see if this is the first dead region. |
160 // see if this is the first dead region. |
173 if (q < first_dead) { |
161 if (q < first_dead) { |
174 first_dead = q; |
162 first_dead = q; |
175 } |
163 } |
178 q = end; |
166 q = end; |
179 } |
167 } |
180 } |
168 } |
181 |
169 |
182 assert(q == t, "just checking"); |
170 assert(q == t, "just checking"); |
183 if (liveRange != NULL) { |
|
184 liveRange->set_end(q); |
|
185 } |
|
186 space->_end_of_live = end_of_live; |
171 space->_end_of_live = end_of_live; |
187 if (end_of_live < first_dead) { |
172 if (end_of_live < first_dead) { |
188 first_dead = end_of_live; |
173 first_dead = end_of_live; |
189 } |
174 } |
190 space->_first_dead = first_dead; |
175 space->_first_dead = first_dead; |
225 } |
210 } |
226 |
211 |
227 if (space->_first_dead == t) { |
212 if (space->_first_dead == t) { |
228 q = t; |
213 q = t; |
229 } else { |
214 } else { |
230 // $$$ This is funky. Using this to read the previously written |
215 // The first dead object is no longer an object. At that memory address, |
231 // LiveRange. See also use below. |
216 // there is a pointer to the first live object that the previous phase found. |
232 q = (HeapWord*)oop(space->_first_dead)->mark()->decode_pointer(); |
217 q = *((HeapWord**)(space->_first_dead)); |
233 } |
218 } |
234 } |
219 } |
235 |
220 |
236 const intx interval = PrefetchScanIntervalInBytes; |
221 const intx interval = PrefetchScanIntervalInBytes; |
237 |
222 |
245 size_t size = MarkSweep::adjust_pointers(oop(q)); |
230 size_t size = MarkSweep::adjust_pointers(oop(q)); |
246 size = space->adjust_obj_size(size); |
231 size = space->adjust_obj_size(size); |
247 debug_only(prev_q = q); |
232 debug_only(prev_q = q); |
248 q += size; |
233 q += size; |
249 } else { |
234 } else { |
250 // q is not a live object, so its mark should point at the next |
|
251 // live object |
|
252 debug_only(prev_q = q); |
235 debug_only(prev_q = q); |
253 q = (HeapWord*) oop(q)->mark()->decode_pointer(); |
236 // q is not a live object, instead it points at the next live object |
254 assert(q > prev_q, "we should be moving forward through memory"); |
237 q = *(HeapWord**)q; |
|
238 assert(q > prev_q, "we should be moving forward through memory, q: " PTR_FORMAT ", prev_q: " PTR_FORMAT, p2i(q), p2i(prev_q)); |
255 } |
239 } |
256 } |
240 } |
257 |
241 |
258 assert(q == t, "just checking"); |
242 assert(q == t, "just checking"); |
259 } |
243 } |