hotspot/src/share/vm/oops/instanceKlass.cpp
changeset 360 21d113ecbf6a
parent 225 6258c2e3adfd
child 670 ddf3e9583f2f
child 1374 4c24294029a9
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Apr 11 09:56:35 2008 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Sun Apr 13 17:43:42 2008 -0400
@@ -1255,218 +1255,298 @@
 #endif //PRODUCT
 
 
+#ifdef ASSERT
+template <class T> void assert_is_in(T *p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in(o), "should be in heap");
+  }
+}
+template <class T> void assert_is_in_closed_subset(T *p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in_closed_subset(o), "should be in closed");
+  }
+}
+template <class T> void assert_is_in_reserved(T *p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
+  }
+}
+template <class T> void assert_nothing(T *p) {}
+
+#else
+template <class T> void assert_is_in(T *p) {}
+template <class T> void assert_is_in_closed_subset(T *p) {}
+template <class T> void assert_is_in_reserved(T *p) {}
+template <class T> void assert_nothing(T *p) {}
+#endif // ASSERT
+
+//
+// Macros that iterate over areas of oops which are specialized on type of
+// oop pointer either narrow or wide, depending on UseCompressedOops
+//
+// Parameters are:
+//   T         - type of oop to point to (either oop or narrowOop)
+//   start_p   - starting pointer for region to iterate over
+//   count     - number of oops or narrowOops to iterate over
+//   do_oop    - action to perform on each oop (it's arbitrary C code which
+//               makes it more efficient to put in a macro rather than making
+//               it a template function)
+//   assert_fn - assert function which is template function because performance
+//               doesn't matter when enabled.
+#define InstanceKlass_SPECIALIZED_OOP_ITERATE( \
+  T, start_p, count, do_oop,                \
+  assert_fn)                                \
+{                                           \
+  T* p         = (T*)(start_p);             \
+  T* const end = p + (count);               \
+  while (p < end) {                         \
+    (assert_fn)(p);                         \
+    do_oop;                                 \
+    ++p;                                    \
+  }                                         \
+}
+
+#define InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE( \
+  T, start_p, count, do_oop,                \
+  assert_fn)                                \
+{                                           \
+  T* const start = (T*)(start_p);           \
+  T*       p     = start + (count);         \
+  while (start < p) {                       \
+    --p;                                    \
+    (assert_fn)(p);                         \
+    do_oop;                                 \
+  }                                         \
+}
+
+#define InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
+  T, start_p, count, low, high,             \
+  do_oop, assert_fn)                        \
+{                                           \
+  T* const l = (T*)(low);                   \
+  T* const h = (T*)(high);                  \
+  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \
+         mask_bits((intptr_t)h, sizeof(T)-1) == 0,   \
+         "bounded region must be properly aligned"); \
+  T* p       = (T*)(start_p);               \
+  T* end     = p + (count);                 \
+  if (p < l) p = l;                         \
+  if (end > h) end = h;                     \
+  while (p < end) {                         \
+    (assert_fn)(p);                         \
+    do_oop;                                 \
+    ++p;                                    \
+  }                                         \
+}
+
+
+// The following macros call specialized macros, passing either oop or
+// narrowOop as the specialization type.  These test the UseCompressedOops
+// flag.
+#define InstanceKlass_OOP_ITERATE(start_p, count,    \
+                                  do_oop, assert_fn) \
+{                                                    \
+  if (UseCompressedOops) {                           \
+    InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
+      start_p, count,                                \
+      do_oop, assert_fn)                             \
+  } else {                                           \
+    InstanceKlass_SPECIALIZED_OOP_ITERATE(oop,       \
+      start_p, count,                                \
+      do_oop, assert_fn)                             \
+  }                                                  \
+}
+
+#define InstanceKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high,    \
+                                          do_oop, assert_fn) \
+{                                                            \
+  if (UseCompressedOops) {                                   \
+    InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
+      start_p, count,                                        \
+      low, high,                                             \
+      do_oop, assert_fn)                                     \
+  } else {                                                   \
+    InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,       \
+      start_p, count,                                        \
+      low, high,                                             \
+      do_oop, assert_fn)                                     \
+  }                                                          \
+}
+
+#define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn)            \
+{                                                                        \
+  /* Compute oopmap block range. The common case                         \
+     is nonstatic_oop_map_size == 1. */                                  \
+  OopMapBlock* map           = start_of_nonstatic_oop_maps();            \
+  OopMapBlock* const end_map = map + nonstatic_oop_map_size();           \
+  if (UseCompressedOops) {                                               \
+    while (map < end_map) {                                              \
+      InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop,                   \
+        obj->obj_field_addr<narrowOop>(map->offset()), map->length(),    \
+        do_oop, assert_fn)                                               \
+      ++map;                                                             \
+    }                                                                    \
+  } else {                                                               \
+    while (map < end_map) {                                              \
+      InstanceKlass_SPECIALIZED_OOP_ITERATE(oop,                         \
+        obj->obj_field_addr<oop>(map->offset()), map->length(),          \
+        do_oop, assert_fn)                                               \
+      ++map;                                                             \
+    }                                                                    \
+  }                                                                      \
+}
+
+#define InstanceKlass_OOP_MAP_REVERSE_ITERATE(obj, do_oop, assert_fn)    \
+{                                                                        \
+  OopMapBlock* const start_map = start_of_nonstatic_oop_maps();          \
+  OopMapBlock* map             = start_map + nonstatic_oop_map_size();   \
+  if (UseCompressedOops) {                                               \
+    while (start_map < map) {                                            \
+      --map;                                                             \
+      InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(narrowOop,           \
+        obj->obj_field_addr<narrowOop>(map->offset()), map->length(),    \
+        do_oop, assert_fn)                                               \
+    }                                                                    \
+  } else {                                                               \
+    while (start_map < map) {                                            \
+      --map;                                                             \
+      InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(oop,                 \
+        obj->obj_field_addr<oop>(map->offset()), map->length(),          \
+        do_oop, assert_fn)                                               \
+    }                                                                    \
+  }                                                                      \
+}
+
+#define InstanceKlass_BOUNDED_OOP_MAP_ITERATE(obj, low, high, do_oop,    \
+                                              assert_fn)                 \
+{                                                                        \
+  /* Compute oopmap block range. The common case is                      \
+     nonstatic_oop_map_size == 1, so we accept the                       \
+     usually non-existent extra overhead of examining                    \
+     all the maps. */                                                    \
+  OopMapBlock* map           = start_of_nonstatic_oop_maps();            \
+  OopMapBlock* const end_map = map + nonstatic_oop_map_size();           \
+  if (UseCompressedOops) {                                               \
+    while (map < end_map) {                                              \
+      InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,           \
+        obj->obj_field_addr<narrowOop>(map->offset()), map->length(),    \
+        low, high,                                                       \
+        do_oop, assert_fn)                                               \
+      ++map;                                                             \
+    }                                                                    \
+  } else {                                                               \
+    while (map < end_map) {                                              \
+      InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,                 \
+        obj->obj_field_addr<oop>(map->offset()), map->length(),          \
+        low, high,                                                       \
+        do_oop, assert_fn)                                               \
+      ++map;                                                             \
+    }                                                                    \
+  }                                                                      \
+}
+
 void instanceKlass::follow_static_fields() {
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  while (start < end) {
-    if (*start != NULL) {
-      assert(Universe::heap()->is_in_closed_subset(*start),
-             "should be in heap");
-      MarkSweep::mark_and_push(start);
-    }
-    start++;
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    MarkSweep::mark_and_push(p), \
+    assert_is_in_closed_subset)
 }
 
 #ifndef SERIALGC
 void instanceKlass::follow_static_fields(ParCompactionManager* cm) {
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  while (start < end) {
-    if (*start != NULL) {
-      assert(Universe::heap()->is_in(*start), "should be in heap");
-      PSParallelCompact::mark_and_push(cm, start);
-    }
-    start++;
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    PSParallelCompact::mark_and_push(cm, p), \
+    assert_is_in)
 }
 #endif // SERIALGC
 
-
 void instanceKlass::adjust_static_fields() {
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  while (start < end) {
-    MarkSweep::adjust_pointer(start);
-    start++;
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    MarkSweep::adjust_pointer(p), \
+    assert_nothing)
 }
 
 #ifndef SERIALGC
 void instanceKlass::update_static_fields() {
-  oop* const start = start_of_static_fields();
-  oop* const beg_oop = start;
-  oop* const end_oop = start + static_oop_field_size();
-  for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
-    PSParallelCompact::adjust_pointer(cur_oop);
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    PSParallelCompact::adjust_pointer(p), \
+    assert_nothing)
 }
 
-void
-instanceKlass::update_static_fields(HeapWord* beg_addr, HeapWord* end_addr) {
-  oop* const start = start_of_static_fields();
-  oop* const beg_oop = MAX2((oop*)beg_addr, start);
-  oop* const end_oop = MIN2((oop*)end_addr, start + static_oop_field_size());
-  for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
-    PSParallelCompact::adjust_pointer(cur_oop);
-  }
+void instanceKlass::update_static_fields(HeapWord* beg_addr, HeapWord* end_addr) {
+  InstanceKlass_BOUNDED_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    beg_addr, end_addr, \
+    PSParallelCompact::adjust_pointer(p), \
+    assert_nothing )
 }
 #endif // SERIALGC
 
 void instanceKlass::oop_follow_contents(oop obj) {
-  assert (obj!=NULL, "can't follow the content of NULL object");
+  assert(obj != NULL, "can't follow the content of NULL object");
   obj->follow_header();
-  OopMapBlock* map     = start_of_nonstatic_oop_maps();
-  OopMapBlock* end_map = map + nonstatic_oop_map_size();
-  while (map < end_map) {
-    oop* start = obj->obj_field_addr(map->offset());
-    oop* end   = start + map->length();
-    while (start < end) {
-      if (*start != NULL) {
-        assert(Universe::heap()->is_in_closed_subset(*start),
-               "should be in heap");
-        MarkSweep::mark_and_push(start);
-      }
-      start++;
-    }
-    map++;
-  }
+  InstanceKlass_OOP_MAP_ITERATE( \
+    obj, \
+    MarkSweep::mark_and_push(p), \
+    assert_is_in_closed_subset)
 }
 
 #ifndef SERIALGC
 void instanceKlass::oop_follow_contents(ParCompactionManager* cm,
                                         oop obj) {
-  assert (obj!=NULL, "can't follow the content of NULL object");
+  assert(obj != NULL, "can't follow the content of NULL object");
   obj->follow_header(cm);
-  OopMapBlock* map     = start_of_nonstatic_oop_maps();
-  OopMapBlock* end_map = map + nonstatic_oop_map_size();
-  while (map < end_map) {
-    oop* start = obj->obj_field_addr(map->offset());
-    oop* end   = start + map->length();
-    while (start < end) {
-      if (*start != NULL) {
-        assert(Universe::heap()->is_in(*start), "should be in heap");
-        PSParallelCompact::mark_and_push(cm, start);
-      }
-      start++;
-    }
-    map++;
-  }
+  InstanceKlass_OOP_MAP_ITERATE( \
+    obj, \
+    PSParallelCompact::mark_and_push(cm, p), \
+    assert_is_in)
 }
 #endif // SERIALGC
 
-#define invoke_closure_on(start, closure, nv_suffix) {                          \
-  oop obj = *(start);                                                           \
-  if (obj != NULL) {                                                            \
-    assert(Universe::heap()->is_in_closed_subset(obj), "should be in heap");    \
-    (closure)->do_oop##nv_suffix(start);                                        \
-  }                                                                             \
-}
-
 // closure's do_header() method dicates whether the given closure should be
 // applied to the klass ptr in the object header.
 
-#define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
-                                                                                \
-int instanceKlass::oop_oop_iterate##nv_suffix(oop obj,                          \
-                                              OopClosureType* closure) {        \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
-  /* header */                                                                  \
-  if (closure->do_header()) {                                                   \
-    obj->oop_iterate_header(closure);                                           \
-  }                                                                             \
-  /* instance variables */                                                      \
-  OopMapBlock* map     = start_of_nonstatic_oop_maps();                         \
-  OopMapBlock* const end_map = map + nonstatic_oop_map_size();                  \
-  const intx field_offset    = PrefetchFieldsAhead;                             \
-  if (field_offset > 0) {                                                       \
-    while (map < end_map) {                                                     \
-      oop* start = obj->obj_field_addr(map->offset());                          \
-      oop* const end   = start + map->length();                                 \
-      while (start < end) {                                                     \
-        prefetch_beyond(start, (oop*)end, field_offset,                         \
-                        closure->prefetch_style());                             \
-        SpecializationStats::                                                   \
-          record_do_oop_call##nv_suffix(SpecializationStats::ik);               \
-        invoke_closure_on(start, closure, nv_suffix);                           \
-        start++;                                                                \
-      }                                                                         \
-      map++;                                                                    \
-    }                                                                           \
-  } else {                                                                      \
-    while (map < end_map) {                                                     \
-      oop* start = obj->obj_field_addr(map->offset());                          \
-      oop* const end   = start + map->length();                                 \
-      while (start < end) {                                                     \
-        SpecializationStats::                                                   \
-          record_do_oop_call##nv_suffix(SpecializationStats::ik);               \
-        invoke_closure_on(start, closure, nv_suffix);                           \
-        start++;                                                                \
-      }                                                                         \
-      map++;                                                                    \
-    }                                                                           \
-  }                                                                             \
-  return size_helper();                                                         \
+#define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)   \
+                                                                        \
+int instanceKlass::oop_oop_iterate##nv_suffix(oop obj,                  \
+                                              OopClosureType* closure) {\
+  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
+  /* header */                                                          \
+  if (closure->do_header()) {                                           \
+    obj->oop_iterate_header(closure);                                   \
+  }                                                                     \
+  InstanceKlass_OOP_MAP_ITERATE(                                        \
+    obj,                                                                \
+    SpecializationStats::                                               \
+      record_do_oop_call##nv_suffix(SpecializationStats::ik);           \
+    (closure)->do_oop##nv_suffix(p),                                    \
+    assert_is_in_closed_subset)                                         \
+  return size_helper();                                                 \
 }
 
-#define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
-                                                                                \
-int instanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj,                      \
-                                                  OopClosureType* closure,      \
-                                                  MemRegion mr) {               \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
-  /* header */                                                                  \
-  if (closure->do_header()) {                                                   \
-    obj->oop_iterate_header(closure, mr);                                       \
-  }                                                                             \
-  /* instance variables */                                                      \
-  OopMapBlock* map     = start_of_nonstatic_oop_maps();                         \
-  OopMapBlock* const end_map = map + nonstatic_oop_map_size();                  \
-  HeapWord* bot = mr.start();                                                   \
-  HeapWord* top = mr.end();                                                     \
-  oop* start = obj->obj_field_addr(map->offset());                              \
-  HeapWord* end = MIN2((HeapWord*)(start + map->length()), top);                \
-  /* Find the first map entry that extends onto mr. */                          \
-  while (map < end_map && end <= bot) {                                         \
-    map++;                                                                      \
-    start = obj->obj_field_addr(map->offset());                                 \
-    end = MIN2((HeapWord*)(start + map->length()), top);                        \
-  }                                                                             \
-  if (map != end_map) {                                                         \
-    /* The current map's end is past the start of "mr".  Skip up to the first   \
-       entry on "mr". */                                                        \
-    while ((HeapWord*)start < bot) {                                            \
-      start++;                                                                  \
-    }                                                                           \
-    const intx field_offset = PrefetchFieldsAhead;                              \
-    for (;;) {                                                                  \
-      if (field_offset > 0) {                                                   \
-        while ((HeapWord*)start < end) {                                        \
-          prefetch_beyond(start, (oop*)end, field_offset,                       \
-                          closure->prefetch_style());                           \
-          invoke_closure_on(start, closure, nv_suffix);                         \
-          start++;                                                              \
-        }                                                                       \
-      } else {                                                                  \
-        while ((HeapWord*)start < end) {                                        \
-          invoke_closure_on(start, closure, nv_suffix);                         \
-          start++;                                                              \
-        }                                                                       \
-      }                                                                         \
-      /* Go to the next map. */                                                 \
-      map++;                                                                    \
-      if (map == end_map) {                                                     \
-        break;                                                                  \
-      }                                                                         \
-      /* Otherwise,  */                                                         \
-      start = obj->obj_field_addr(map->offset());                               \
-      if ((HeapWord*)start >= top) {                                            \
-        break;                                                                  \
-      }                                                                         \
-      end = MIN2((HeapWord*)(start + map->length()), top);                      \
-    }                                                                           \
-  }                                                                             \
-  return size_helper();                                                         \
+#define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
+                                                                        \
+int instanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj,              \
+                                                  OopClosureType* closure, \
+                                                  MemRegion mr) {          \
+  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
+  if (closure->do_header()) {                                            \
+    obj->oop_iterate_header(closure, mr);                                \
+  }                                                                      \
+  InstanceKlass_BOUNDED_OOP_MAP_ITERATE(                                 \
+    obj, mr.start(), mr.end(),                                           \
+    (closure)->do_oop##nv_suffix(p),                                     \
+    assert_is_in_closed_subset)                                          \
+  return size_helper();                                                  \
 }
 
 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN)
@@ -1474,56 +1554,28 @@
 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
 ALL_OOP_OOP_ITERATE_CLOSURES_3(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
 
-
 void instanceKlass::iterate_static_fields(OopClosure* closure) {
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  while (start < end) {
-    assert(Universe::heap()->is_in_reserved_or_null(*start), "should be in heap");
-    closure->do_oop(start);
-    start++;
-  }
+    InstanceKlass_OOP_ITERATE( \
+      start_of_static_fields(), static_oop_field_size(), \
+      closure->do_oop(p), \
+      assert_is_in_reserved)
 }
 
 void instanceKlass::iterate_static_fields(OopClosure* closure,
                                           MemRegion mr) {
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  // I gather that the the static fields of reference types come first,
-  // hence the name of "oop_field_size", and that is what makes this safe.
-  assert((intptr_t)mr.start() ==
-         align_size_up((intptr_t)mr.start(), sizeof(oop)) &&
-         (intptr_t)mr.end() == align_size_up((intptr_t)mr.end(), sizeof(oop)),
-         "Memregion must be oop-aligned.");
-  if ((HeapWord*)start < mr.start()) start = (oop*)mr.start();
-  if ((HeapWord*)end   > mr.end())   end   = (oop*)mr.end();
-  while (start < end) {
-    invoke_closure_on(start, closure,_v);
-    start++;
-  }
+  InstanceKlass_BOUNDED_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    mr.start(), mr.end(), \
+    (closure)->do_oop_v(p), \
+    assert_is_in_closed_subset)
 }
 
-
 int instanceKlass::oop_adjust_pointers(oop obj) {
   int size = size_helper();
-
-  // Compute oopmap block range. The common case is nonstatic_oop_map_size == 1.
-  OopMapBlock* map     = start_of_nonstatic_oop_maps();
-  OopMapBlock* const end_map = map + nonstatic_oop_map_size();
-  // Iterate over oopmap blocks
-  while (map < end_map) {
-    // Compute oop range for this block
-    oop* start = obj->obj_field_addr(map->offset());
-    oop* end   = start + map->length();
-    // Iterate over oops
-    while (start < end) {
-      assert(Universe::heap()->is_in_or_null(*start), "should be in heap");
-      MarkSweep::adjust_pointer(start);
-      start++;
-    }
-    map++;
-  }
-
+  InstanceKlass_OOP_MAP_ITERATE( \
+    obj, \
+    MarkSweep::adjust_pointer(p), \
+    assert_is_in)
   obj->adjust_header();
   return size;
 }
@@ -1531,132 +1583,66 @@
 #ifndef SERIALGC
 void instanceKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
   assert(!pm->depth_first(), "invariant");
-  // Compute oopmap block range. The common case is nonstatic_oop_map_size == 1.
-  OopMapBlock* start_map = start_of_nonstatic_oop_maps();
-  OopMapBlock* map       = start_map + nonstatic_oop_map_size();
-
-  // Iterate over oopmap blocks
-  while (start_map < map) {
-    --map;
-    // Compute oop range for this block
-    oop* start = obj->obj_field_addr(map->offset());
-    oop* curr  = start + map->length();
-    // Iterate over oops
-    while (start < curr) {
-      --curr;
-      if (PSScavenge::should_scavenge(*curr)) {
-        assert(Universe::heap()->is_in(*curr), "should be in heap");
-        pm->claim_or_forward_breadth(curr);
-      }
-    }
-  }
+  InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
+    obj, \
+    if (PSScavenge::should_scavenge(p)) { \
+      pm->claim_or_forward_breadth(p); \
+    }, \
+    assert_nothing )
 }
 
 void instanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   assert(pm->depth_first(), "invariant");
-  // Compute oopmap block range. The common case is nonstatic_oop_map_size == 1.
-  OopMapBlock* start_map = start_of_nonstatic_oop_maps();
-  OopMapBlock* map       = start_map + nonstatic_oop_map_size();
-
-  // Iterate over oopmap blocks
-  while (start_map < map) {
-    --map;
-    // Compute oop range for this block
-    oop* start = obj->obj_field_addr(map->offset());
-    oop* curr  = start + map->length();
-    // Iterate over oops
-    while (start < curr) {
-      --curr;
-      if (PSScavenge::should_scavenge(*curr)) {
-        assert(Universe::heap()->is_in(*curr), "should be in heap");
-        pm->claim_or_forward_depth(curr);
-      }
-    }
-  }
+  InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
+    obj, \
+    if (PSScavenge::should_scavenge(p)) { \
+      pm->claim_or_forward_depth(p); \
+    }, \
+    assert_nothing )
 }
 
 int instanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
-  // Compute oopmap block range.  The common case is nonstatic_oop_map_size==1.
-  OopMapBlock* map           = start_of_nonstatic_oop_maps();
-  OopMapBlock* const end_map = map + nonstatic_oop_map_size();
-  // Iterate over oopmap blocks
-  while (map < end_map) {
-    // Compute oop range for this oopmap block.
-    oop* const map_start = obj->obj_field_addr(map->offset());
-    oop* const beg_oop = map_start;
-    oop* const end_oop = map_start + map->length();
-    for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
-      PSParallelCompact::adjust_pointer(cur_oop);
-    }
-    ++map;
-  }
-
+  InstanceKlass_OOP_MAP_ITERATE( \
+    obj, \
+    PSParallelCompact::adjust_pointer(p), \
+    assert_nothing)
   return size_helper();
 }
 
 int instanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
                                        HeapWord* beg_addr, HeapWord* end_addr) {
-  // Compute oopmap block range.  The common case is nonstatic_oop_map_size==1.
-  OopMapBlock* map           = start_of_nonstatic_oop_maps();
-  OopMapBlock* const end_map = map + nonstatic_oop_map_size();
-  // Iterate over oopmap blocks
-  while (map < end_map) {
-    // Compute oop range for this oopmap block.
-    oop* const map_start = obj->obj_field_addr(map->offset());
-    oop* const beg_oop = MAX2((oop*)beg_addr, map_start);
-    oop* const end_oop = MIN2((oop*)end_addr, map_start + map->length());
-    for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
-      PSParallelCompact::adjust_pointer(cur_oop);
-    }
-    ++map;
-  }
-
+  InstanceKlass_BOUNDED_OOP_MAP_ITERATE( \
+    obj, beg_addr, end_addr, \
+    PSParallelCompact::adjust_pointer(p), \
+    assert_nothing)
   return size_helper();
 }
 
 void instanceKlass::copy_static_fields(PSPromotionManager* pm) {
   assert(!pm->depth_first(), "invariant");
-  // Compute oop range
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  // Iterate over oops
-  while (start < end) {
-    if (PSScavenge::should_scavenge(*start)) {
-      assert(Universe::heap()->is_in(*start), "should be in heap");
-      pm->claim_or_forward_breadth(start);
-    }
-    start++;
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    if (PSScavenge::should_scavenge(p)) { \
+      pm->claim_or_forward_breadth(p); \
+    }, \
+    assert_nothing )
 }
 
 void instanceKlass::push_static_fields(PSPromotionManager* pm) {
   assert(pm->depth_first(), "invariant");
-  // Compute oop range
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  // Iterate over oops
-  while (start < end) {
-    if (PSScavenge::should_scavenge(*start)) {
-      assert(Universe::heap()->is_in(*start), "should be in heap");
-      pm->claim_or_forward_depth(start);
-    }
-    start++;
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    if (PSScavenge::should_scavenge(p)) { \
+      pm->claim_or_forward_depth(p); \
+    }, \
+    assert_nothing )
 }
 
 void instanceKlass::copy_static_fields(ParCompactionManager* cm) {
-  // Compute oop range
-  oop* start = start_of_static_fields();
-  oop* end   = start + static_oop_field_size();
-  // Iterate over oops
-  while (start < end) {
-    if (*start != NULL) {
-      assert(Universe::heap()->is_in(*start), "should be in heap");
-      // *start = (oop) cm->summary_data()->calc_new_pointer(*start);
-      PSParallelCompact::adjust_pointer(start);
-    }
-    start++;
-  }
+  InstanceKlass_OOP_ITERATE( \
+    start_of_static_fields(), static_oop_field_size(), \
+    PSParallelCompact::adjust_pointer(p), \
+    assert_is_in)
 }
 #endif // SERIALGC
 
@@ -1687,18 +1673,15 @@
   Klass::follow_weak_klass_links(is_alive, keep_alive);
 }
 
-
 void instanceKlass::remove_unshareable_info() {
   Klass::remove_unshareable_info();
   init_implementor();
 }
 
-
 static void clear_all_breakpoints(methodOop m) {
   m->clear_all_breakpoints();
 }
 
-
 void instanceKlass::release_C_heap_structures() {
   // Deallocate oop map cache
   if (_oop_map_cache != NULL) {
@@ -2047,29 +2030,30 @@
   obj->print_address_on(st);
 }
 
-#endif
+#endif // ndef PRODUCT
 
 const char* instanceKlass::internal_name() const {
   return external_name();
 }
 
-
-
 // Verification
 
 class VerifyFieldClosure: public OopClosure {
- public:
-  void do_oop(oop* p) {
+ protected:
+  template <class T> void do_oop_work(T* p) {
     guarantee(Universe::heap()->is_in_closed_subset(p), "should be in heap");
-    if (!(*p)->is_oop_or_null()) {
-      tty->print_cr("Failed: %p -> %p",p,(address)*p);
+    oop obj = oopDesc::load_decode_heap_oop(p);
+    if (!obj->is_oop_or_null()) {
+      tty->print_cr("Failed: " PTR_FORMAT " -> " PTR_FORMAT, p, (address)obj);
       Universe::print();
       guarantee(false, "boom");
     }
   }
+ public:
+  virtual void do_oop(oop* p)       { VerifyFieldClosure::do_oop_work(p); }
+  virtual void do_oop(narrowOop* p) { VerifyFieldClosure::do_oop_work(p); }
 };
 
-
 void instanceKlass::oop_verify_on(oop obj, outputStream* st) {
   Klass::oop_verify_on(obj, st);
   VerifyFieldClosure blk;
@@ -2110,26 +2094,28 @@
   }
 }
 
-#endif
+#endif // ndef PRODUCT
+
+// JNIid class for jfieldIDs only
+// Note to reviewers:
+// These JNI functions are just moved over to column 1 and not changed
+// in the compressed oops workspace.
+JNIid::JNIid(klassOop holder, int offset, JNIid* next) {
+  _holder = holder;
+  _offset = offset;
+  _next = next;
+  debug_only(_is_static_field_id = false;)
+}
 
 
-/* JNIid class for jfieldIDs only */
- JNIid::JNIid(klassOop holder, int offset, JNIid* next) {
-   _holder = holder;
-   _offset = offset;
-   _next = next;
-   debug_only(_is_static_field_id = false;)
- }
-
-
- JNIid* JNIid::find(int offset) {
-   JNIid* current = this;
-   while (current != NULL) {
-     if (current->offset() == offset) return current;
-     current = current->next();
-   }
-   return NULL;
- }
+JNIid* JNIid::find(int offset) {
+  JNIid* current = this;
+  while (current != NULL) {
+    if (current->offset() == offset) return current;
+    current = current->next();
+  }
+  return NULL;
+}
 
 void JNIid::oops_do(OopClosure* f) {
   for (JNIid* cur = this; cur != NULL; cur = cur->next()) {
@@ -2138,40 +2124,40 @@
 }
 
 void JNIid::deallocate(JNIid* current) {
-   while (current != NULL) {
-     JNIid* next = current->next();
-     delete current;
-     current = next;
-   }
- }
+  while (current != NULL) {
+    JNIid* next = current->next();
+    delete current;
+    current = next;
+  }
+}
 
 
- void JNIid::verify(klassOop holder) {
-   int first_field_offset  = instanceKlass::cast(holder)->offset_of_static_fields();
-   int end_field_offset;
-   end_field_offset = first_field_offset + (instanceKlass::cast(holder)->static_field_size() * wordSize);
+void JNIid::verify(klassOop holder) {
+  int first_field_offset  = instanceKlass::cast(holder)->offset_of_static_fields();
+  int end_field_offset;
+  end_field_offset = first_field_offset + (instanceKlass::cast(holder)->static_field_size() * wordSize);
 
-   JNIid* current = this;
-   while (current != NULL) {
-     guarantee(current->holder() == holder, "Invalid klass in JNIid");
- #ifdef ASSERT
-     int o = current->offset();
-     if (current->is_static_field_id()) {
-       guarantee(o >= first_field_offset  && o < end_field_offset,  "Invalid static field offset in JNIid");
-     }
- #endif
-     current = current->next();
-   }
- }
+  JNIid* current = this;
+  while (current != NULL) {
+    guarantee(current->holder() == holder, "Invalid klass in JNIid");
+#ifdef ASSERT
+    int o = current->offset();
+    if (current->is_static_field_id()) {
+      guarantee(o >= first_field_offset  && o < end_field_offset,  "Invalid static field offset in JNIid");
+    }
+#endif
+    current = current->next();
+  }
+}
 
 
 #ifdef ASSERT
-  void instanceKlass::set_init_state(ClassState state) {
-    bool good_state = as_klassOop()->is_shared() ? (_init_state <= state)
-                                                 : (_init_state < state);
-    assert(good_state || state == allocated, "illegal state transition");
-    _init_state = state;
-  }
+void instanceKlass::set_init_state(ClassState state) {
+  bool good_state = as_klassOop()->is_shared() ? (_init_state <= state)
+                                               : (_init_state < state);
+  assert(good_state || state == allocated, "illegal state transition");
+  _init_state = state;
+}
 #endif
 
 
@@ -2180,9 +2166,9 @@
 // Add an information node that contains weak references to the
 // interesting parts of the previous version of the_class.
 void instanceKlass::add_previous_version(instanceKlassHandle ikh,
-       BitMap * emcp_methods, int emcp_method_count) {
+       BitMap* emcp_methods, int emcp_method_count) {
   assert(Thread::current()->is_VM_thread(),
-    "only VMThread can add previous versions");
+         "only VMThread can add previous versions");
 
   if (_previous_versions == NULL) {
     // This is the first previous version so make some space.