< prev index next >

src/share/vm/gc/shared/space.inline.hpp

Print this page




 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);


< prev index next >