diff src/share/vm/memory/space.hpp @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents a61af66fc99e
children d1605aabd0a1 12eea04c8b06 37f87013dfd8
line wrap: on
line diff
--- a/src/share/vm/memory/space.hpp	Fri Apr 11 09:56:35 2008 -0400
+++ b/src/share/vm/memory/space.hpp	Sun Apr 13 17:43:42 2008 -0400
@@ -52,21 +52,24 @@
 class CardTableRS;
 class DirtyCardToOopClosure;
 
-
 // An oop closure that is circumscribed by a filtering memory region.
-class SpaceMemRegionOopsIterClosure: public virtual OopClosure {
-  OopClosure* cl;
-  MemRegion mr;
-public:
-  void do_oop(oop* p) {
-    if (mr.contains(p)) {
-      cl->do_oop(p);
+class SpaceMemRegionOopsIterClosure: public OopClosure {
+ private:
+  OopClosure* _cl;
+  MemRegion   _mr;
+ protected:
+  template <class T> void do_oop_work(T* p) {
+    if (_mr.contains(p)) {
+      _cl->do_oop(p);
     }
   }
-  SpaceMemRegionOopsIterClosure(OopClosure* _cl, MemRegion _mr): cl(_cl), mr(_mr) {}
+ public:
+  SpaceMemRegionOopsIterClosure(OopClosure* cl, MemRegion mr):
+    _cl(cl), _mr(mr) {}
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
 };
 
-
 // A Space describes a heap area. Class Space is an abstract
 // base class.
 //
@@ -279,7 +282,7 @@
   CardTableModRefBS::PrecisionStyle _precision;
   HeapWord* _boundary;          // If non-NULL, process only non-NULL oops
                                 // pointing below boundary.
-  HeapWord* _min_done;          // ObjHeadPreciseArray precision requires
+  HeapWord* _min_done;                // ObjHeadPreciseArray precision requires
                                 // a downwards traversal; this is the
                                 // lowest location already done (or,
                                 // alternatively, the lowest address that
@@ -508,7 +511,7 @@
       /* prefetch beyond q */                                                \
       Prefetch::write(q, interval);                                          \
       /* size_t size = oop(q)->size();  changing this for cms for perm gen */\
-      size_t size = block_size(q);                                           \
+      size_t size = block_size(q);                                             \
       compact_top = cp->space->forward(oop(q), size, cp, compact_top);       \
       q += size;                                                             \
       end_of_live = q;                                                       \
@@ -572,147 +575,149 @@
   cp->space->set_compaction_top(compact_top);                                \
 }
 
-#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) {                             \
-  /* adjust all the interior pointers to point at the new locations of objects  \
-   * Used by MarkSweep::mark_sweep_phase3() */                                  \
+#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) {                                \
+  /* adjust all the interior pointers to point at the new locations of objects        \
+   * Used by MarkSweep::mark_sweep_phase3() */                                        \
                                                                                 \
-  HeapWord* q = bottom();                                                       \
-  HeapWord* t = _end_of_live;  /* Established by "prepare_for_compaction". */   \
+  HeapWord* q = bottom();                                                        \
+  HeapWord* t = _end_of_live;  /* Established by "prepare_for_compaction". */        \
                                                                                 \
-  assert(_first_dead <= _end_of_live, "Stands to reason, no?");                 \
+  assert(_first_dead <= _end_of_live, "Stands to reason, no?");                        \
                                                                                 \
-  if (q < t && _first_dead > q &&                                               \
+  if (q < t && _first_dead > q &&                                                \
       !oop(q)->is_gc_marked()) {                                                \
     /* we have a chunk of the space which hasn't moved and we've                \
      * reinitialized the mark word during the previous pass, so we can't        \
-     * use is_gc_marked for the traversal. */                                   \
+     * use is_gc_marked for the traversal. */                                        \
     HeapWord* end = _first_dead;                                                \
                                                                                 \
-    while (q < end) {                                                           \
-      /* I originally tried to conjoin "block_start(q) == q" to the             \
-       * assertion below, but that doesn't work, because you can't              \
-       * accurately traverse previous objects to get to the current one         \
-       * after their pointers (including pointers into permGen) have been       \
-       * updated, until the actual compaction is done.  dld, 4/00 */            \
-      assert(block_is_obj(q),                                                   \
-             "should be at block boundaries, and should be looking at objs");   \
+    while (q < end) {                                                                \
+      /* I originally tried to conjoin "block_start(q) == q" to the                \
+       * assertion below, but that doesn't work, because you can't                \
+       * accurately traverse previous objects to get to the current one                \
+       * after their pointers (including pointers into permGen) have been        \
+       * updated, until the actual compaction is done.  dld, 4/00 */                \
+      assert(block_is_obj(q),                                                        \
+             "should be at block boundaries, and should be looking at objs");        \
                                                                                 \
-      debug_only(MarkSweep::track_interior_pointers(oop(q)));                   \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));     \
                                                                                 \
-      /* point all the oops to the new location */                              \
-      size_t size = oop(q)->adjust_pointers();                                  \
-      size = adjust_obj_size(size);                                             \
+      /* point all the oops to the new location */                                \
+      size_t size = oop(q)->adjust_pointers();                                        \
+      size = adjust_obj_size(size);                                                \
                                                                                 \
-      debug_only(MarkSweep::check_interior_pointers());                         \
-                                                                                \
-      debug_only(MarkSweep::validate_live_oop(oop(q), size));                   \
-                                                                                \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());           \
+                                                                                      \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));     \
+                                                                                      \
       q += size;                                                                \
-    }                                                                           \
+    }                                                                                \
                                                                                 \
-    if (_first_dead == t) {                                                     \
-      q = t;                                                                    \
-    } else {                                                                    \
-      /* $$$ This is funky.  Using this to read the previously written          \
-       * LiveRange.  See also use below. */                                     \
+    if (_first_dead == t) {                                                        \
+      q = t;                                                                        \
+    } else {                                                                        \
+      /* $$$ This is funky.  Using this to read the previously written                \
+       * LiveRange.  See also use below. */                                        \
       q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();                \
-    }                                                                           \
-  }                                                                             \
+    }                                                                                \
+  }                                                                                \
                                                                                 \
   const intx interval = PrefetchScanIntervalInBytes;                            \
                                                                                 \
-  debug_only(HeapWord* prev_q = NULL);                                          \
-  while (q < t) {                                                               \
-    /* prefetch beyond q */                                                     \
+  debug_only(HeapWord* prev_q = NULL);                                                \
+  while (q < t) {                                                                \
+    /* prefetch beyond q */                                                        \
     Prefetch::write(q, interval);                                               \
-    if (oop(q)->is_gc_marked()) {                                               \
-      /* q is alive */                                                          \
-      debug_only(MarkSweep::track_interior_pointers(oop(q)));                   \
-      /* point all the oops to the new location */                              \
-      size_t size = oop(q)->adjust_pointers();                                  \
-      size = adjust_obj_size(size);                                             \
-      debug_only(MarkSweep::check_interior_pointers());                         \
-      debug_only(MarkSweep::validate_live_oop(oop(q), size));                   \
-      debug_only(prev_q = q);                                                   \
+    if (oop(q)->is_gc_marked()) {                                                \
+      /* q is alive */                                                                \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));     \
+      /* point all the oops to the new location */                                \
+      size_t size = oop(q)->adjust_pointers();                                        \
+      size = adjust_obj_size(size);                                                \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());                \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));     \
+      debug_only(prev_q = q);                                                        \
       q += size;                                                                \
-    } else {                                                                    \
-      /* q is not a live object, so its mark should point at the next           \
-       * live object */                                                         \
-      debug_only(prev_q = q);                                                   \
-      q = (HeapWord*) oop(q)->mark()->decode_pointer();                         \
-      assert(q > prev_q, "we should be moving forward through memory");         \
-    }                                                                           \
-  }                                                                             \
+    } else {                                                                        \
+      /* q is not a live object, so its mark should point at the next                \
+       * live object */                                                                \
+      debug_only(prev_q = q);                                                        \
+      q = (HeapWord*) oop(q)->mark()->decode_pointer();                                \
+      assert(q > prev_q, "we should be moving forward through memory");                \
+    }                                                                                \
+  }                                                                                \
                                                                                 \
-  assert(q == t, "just checking");                                              \
+  assert(q == t, "just checking");                                                \
 }
 
-#define SCAN_AND_COMPACT(obj_size) {                                            \
+#define SCAN_AND_COMPACT(obj_size) {                                                \
   /* Copy all live objects to their new location                                \
-   * Used by MarkSweep::mark_sweep_phase4() */                                  \
+   * Used by MarkSweep::mark_sweep_phase4() */                                        \
                                                                                 \
-  HeapWord*       q = bottom();                                                 \
-  HeapWord* const t = _end_of_live;                                             \
-  debug_only(HeapWord* prev_q = NULL);                                          \
+  HeapWord*       q = bottom();                                                        \
+  HeapWord* const t = _end_of_live;                                                \
+  debug_only(HeapWord* prev_q = NULL);                                                \
                                                                                 \
-  if (q < t && _first_dead > q &&                                               \
+  if (q < t && _first_dead > q &&                                                \
       !oop(q)->is_gc_marked()) {                                                \
-    debug_only(                                                                 \
-    /* we have a chunk of the space which hasn't moved and we've reinitialized the              \
-     * mark word during the previous pass, so we can't use is_gc_marked for the \
-     * traversal. */                                                            \
-    HeapWord* const end = _first_dead;                                          \
-                                                                                \
-    while (q < end) {                                                           \
+    debug_only(                                                                        \
+    /* we have a chunk of the space which hasn't moved and we've reinitialized  \
+     * the mark word during the previous pass, so we can't use is_gc_marked for \
+     * the traversal. */                                                        \
+    HeapWord* const end = _first_dead;                                                \
+                                                                                      \
+    while (q < end) {                                                                \
       size_t size = obj_size(q);                                                \
-      assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)"); \
-      debug_only(MarkSweep::live_oop_moved_to(q, size, q));                     \
-      debug_only(prev_q = q);                                                   \
+      assert(!oop(q)->is_gc_marked(),                                           \
+             "should be unmarked (special dense prefix handling)");             \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q));        \
+      debug_only(prev_q = q);                                                        \
       q += size;                                                                \
-    }                                                                           \
-    )  /* debug_only */                                                         \
-                                                                                \
-    if (_first_dead == t) {                                                     \
-      q = t;                                                                    \
-    } else {                                                                    \
-      /* $$$ Funky */                                                           \
-      q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();               \
-    }                                                                           \
-  }                                                                             \
+    }                                                                                \
+    )  /* debug_only */                                                                \
+                                                                                      \
+    if (_first_dead == t) {                                                        \
+      q = t;                                                                        \
+    } else {                                                                        \
+      /* $$$ Funky */                                                                 \
+      q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();                \
+    }                                                                                \
+  }                                                                                \
                                                                                 \
-  const intx scan_interval = PrefetchScanIntervalInBytes;                       \
-  const intx copy_interval = PrefetchCopyIntervalInBytes;                       \
-  while (q < t) {                                                               \
-    if (!oop(q)->is_gc_marked()) {                                              \
-      /* mark is pointer to next marked oop */                                  \
-      debug_only(prev_q = q);                                                   \
-      q = (HeapWord*) oop(q)->mark()->decode_pointer();                         \
-      assert(q > prev_q, "we should be moving forward through memory");         \
-    } else {                                                                    \
-      /* prefetch beyond q */                                                   \
+  const intx scan_interval = PrefetchScanIntervalInBytes;                        \
+  const intx copy_interval = PrefetchCopyIntervalInBytes;                        \
+  while (q < t) {                                                                \
+    if (!oop(q)->is_gc_marked()) {                                                \
+      /* mark is pointer to next marked oop */                                        \
+      debug_only(prev_q = q);                                                        \
+      q = (HeapWord*) oop(q)->mark()->decode_pointer();                                \
+      assert(q > prev_q, "we should be moving forward through memory");                \
+    } else {                                                                        \
+      /* prefetch beyond q */                                                        \
       Prefetch::read(q, scan_interval);                                         \
                                                                                 \
       /* size and destination */                                                \
       size_t size = obj_size(q);                                                \
       HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();                \
                                                                                 \
-      /* prefetch beyond compaction_top */                                      \
+      /* prefetch beyond compaction_top */                                        \
       Prefetch::write(compaction_top, copy_interval);                           \
                                                                                 \
-      /* copy object and reinit its mark */                                     \
-      debug_only(MarkSweep::live_oop_moved_to(q, size, compaction_top));        \
-      assert(q != compaction_top, "everything in this pass should be moving");  \
-      Copy::aligned_conjoint_words(q, compaction_top, size);                    \
-      oop(compaction_top)->init_mark();                                         \
-      assert(oop(compaction_top)->klass() != NULL, "should have a class");      \
+      /* copy object and reinit its mark */                                        \
+      VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size,            \
+                                                            compaction_top));   \
+      assert(q != compaction_top, "everything in this pass should be moving");        \
+      Copy::aligned_conjoint_words(q, compaction_top, size);                        \
+      oop(compaction_top)->init_mark();                                                \
+      assert(oop(compaction_top)->klass() != NULL, "should have a class");        \
                                                                                 \
-      debug_only(prev_q = q);                                                   \
+      debug_only(prev_q = q);                                                        \
       q += size;                                                                \
-    }                                                                           \
-  }                                                                             \
+    }                                                                                \
+  }                                                                                \
                                                                                 \
   /* Reset space after compaction is complete */                                \
-  reset_after_compaction();                                                     \
+  reset_after_compaction();                                                        \
   /* We do this clear, below, since it has overloaded meanings for some */      \
   /* space subtypes.  For example, OffsetTableContigSpace's that were   */      \
   /* compacted into will have had their offset table thresholds updated */      \