166 q = end; 167 } 168 } 169 170 assert(q == t, "just checking"); 171 space->_end_of_live = end_of_live; 172 if (end_of_live < first_dead) { 173 first_dead = end_of_live; 174 } 175 space->_first_dead = first_dead; 176 177 // save the compaction_top of the compaction space. 178 cp->space->set_compaction_top(compact_top); 179 } 180 181 template <class SpaceType> 182 inline void CompactibleSpace::scan_and_adjust_pointers(SpaceType* space) { 183 // adjust all the interior pointers to point at the new locations of objects 184 // Used by MarkSweep::mark_sweep_phase3() 185 186 HeapWord* q = space->bottom(); 187 HeapWord* t = space->_end_of_live; // Established by "prepare_for_compaction". 188 189 assert(space->_first_dead <= space->_end_of_live, "Stands to reason, no?"); 190 191 if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) { 192 // we have a chunk of the space which hasn't moved and we've 193 // reinitialized the mark word during the previous pass, so we can't 194 // use is_gc_marked for the traversal. 195 HeapWord* end = space->_first_dead; 196 197 while (q < end) { 198 // I originally tried to conjoin "block_start(q) == q" to the 199 // assertion below, but that doesn't work, because you can't 200 // accurately traverse previous objects to get to the current one 201 // after their pointers have been 202 // updated, until the actual compaction is done. dld, 4/00 203 assert(space->block_is_obj(q), "should be at block boundaries, and should be looking at objs"); 204 205 // point all the oops to the new location 206 size_t size = MarkSweep::adjust_pointers(oop(q)); 207 size = space->adjust_obj_size(size); 208 209 q += size; 210 } 211 212 if (space->_first_dead == t) { 213 q = t; 214 } else { 215 // The first dead object is no longer an object. At that memory address, 216 // there is a pointer to the first live object that the previous phase found. 217 q = *((HeapWord**)(space->_first_dead)); 218 } 219 } 220 221 const intx interval = PrefetchScanIntervalInBytes; 222 223 debug_only(HeapWord* prev_q = NULL); 224 while (q < t) { 225 // prefetch beyond q 226 Prefetch::write(q, interval); 227 if (oop(q)->is_gc_marked()) { 228 // q is alive 229 // point all the oops to the new location 230 size_t size = MarkSweep::adjust_pointers(oop(q)); 231 size = space->adjust_obj_size(size); 232 debug_only(prev_q = q); 233 q += size; 234 } else { 235 debug_only(prev_q = q); 236 // q is not a live object, instead it points at the next live object 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)); 239 } 240 } 241 242 assert(q == t, "just checking"); 243 } 244 245 template <class SpaceType> 246 inline void CompactibleSpace::scan_and_compact(SpaceType* space) { 247 // Copy all live objects to their new location 248 // Used by MarkSweep::mark_sweep_phase4() 249 250 HeapWord* q = space->bottom(); 251 HeapWord* const t = space->_end_of_live; 252 debug_only(HeapWord* prev_q = NULL); 253 254 if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) { 255 #ifdef ASSERT // Debug only 256 // we have a chunk of the space which hasn't moved and we've reinitialized 257 // the mark word during the previous pass, so we can't use is_gc_marked for 258 // the traversal. 259 HeapWord* const end = space->_first_dead; 260 261 while (q < end) { 262 size_t size = space->obj_size(q); | 166 q = end; 167 } 168 } 169 170 assert(q == t, "just checking"); 171 space->_end_of_live = end_of_live; 172 if (end_of_live < first_dead) { 173 first_dead = end_of_live; 174 } 175 space->_first_dead = first_dead; 176 177 // save the compaction_top of the compaction space. 178 cp->space->set_compaction_top(compact_top); 179 } 180 181 template <class SpaceType> 182 inline void CompactibleSpace::scan_and_adjust_pointers(SpaceType* space) { 183 // adjust all the interior pointers to point at the new locations of objects 184 // Used by MarkSweep::mark_sweep_phase3() 185 186 HeapWord* cur_obj = space->bottom(); 187 HeapWord* const end_of_live = space->_end_of_live; // Established by "scan_and_forward". 188 HeapWord* const first_dead = space->_first_dead; // Established by "scan_and_forward". 189 190 assert(first_dead <= end_of_live, "Stands to reason, no?"); 191 192 if (cur_obj < end_of_live && first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) { 193 // we have a chunk of the space which hasn't moved and we've 194 // reinitialized the mark word during the previous pass, so we can't 195 // use is_gc_marked for the traversal. 196 197 while (cur_obj < first_dead) { 198 // I originally tried to conjoin "block_start(cur_obj) == cur_obj" to the 199 // assertion below, but that doesn't work, because you can't 200 // accurately traverse previous objects to get to the current one 201 // after their pointers have been 202 // updated, until the actual compaction is done. dld, 4/00 203 assert(space->block_is_obj(cur_obj), "should be at block boundaries, and should be looking at objs"); 204 205 // point all the oops to the new location 206 size_t size = MarkSweep::adjust_pointers(oop(cur_obj)); 207 size = space->adjust_obj_size(size); 208 209 cur_obj += size; 210 } 211 212 if (first_dead == end_of_live) { 213 cur_obj = end_of_live; 214 } else { 215 // The first dead object is no longer an object. At that memory address, 216 // there is a pointer to the first live object that the previous phase found. 217 cur_obj = *(HeapWord**)first_dead; 218 } 219 } 220 221 const intx interval = PrefetchScanIntervalInBytes; 222 223 debug_only(HeapWord* prev_obj = NULL); 224 while (cur_obj < end_of_live) { 225 Prefetch::write(cur_obj, interval); 226 if (oop(cur_obj)->is_gc_marked()) { 227 // cur_obj is alive 228 // point all the oops to the new location 229 size_t size = MarkSweep::adjust_pointers(oop(cur_obj)); 230 size = space->adjust_obj_size(size); 231 debug_only(prev_obj = cur_obj); 232 cur_obj += size; 233 } else { 234 debug_only(prev_obj = cur_obj); 235 // cur_obj is not a live object, instead it points at the next live object 236 cur_obj = *(HeapWord**)cur_obj; 237 assert(cur_obj > prev_obj, "we should be moving forward through memory, cur_obj: " PTR_FORMAT ", prev_obj: " PTR_FORMAT, p2i(cur_obj), p2i(prev_obj)); 238 } 239 } 240 241 assert(cur_obj == end_of_live, "just checking"); 242 } 243 244 template <class SpaceType> 245 inline void CompactibleSpace::scan_and_compact(SpaceType* space) { 246 // Copy all live objects to their new location 247 // Used by MarkSweep::mark_sweep_phase4() 248 249 HeapWord* q = space->bottom(); 250 HeapWord* const t = space->_end_of_live; 251 debug_only(HeapWord* prev_q = NULL); 252 253 if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) { 254 #ifdef ASSERT // Debug only 255 // we have a chunk of the space which hasn't moved and we've reinitialized 256 // the mark word during the previous pass, so we can't use is_gc_marked for 257 // the traversal. 258 HeapWord* const end = space->_first_dead; 259 260 while (q < end) { 261 size_t size = space->obj_size(q); |