< prev index next >

src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp

Print this page
rev 7994 : [mq]: filter

@@ -295,20 +295,34 @@
         if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
           // No OrderAccess:store_load() is needed. It is implicit in the
           // CAS done in CMBitMap::parMark() call in the routine above.
           HeapWord* global_finger = _cm->finger();
 
-#if _CHECK_BOTH_FINGERS_
-          // we will check both the local and global fingers
-
-          if (_finger != NULL && objAddr < _finger) {
+          if (_CHECK_BOTH_FINGERS_ && _finger != NULL && objAddr < _finger) {
+            if (obj->is_typeArray()) {
+              // Immediately process arrays of binary data, rather
+              // than pushing on the mark stack.  This keeps us from
+              // adding humongous objects to the mark stack that might
+              // be reclaimed before the entry is processed - see
+              // G1EagerReclaimHumongousPreSnapshotTypeArrays.  The
+              // cost of the additional type test is mitigated by
+              // avoiding a trip through the mark stack, and by only
+              // doing bookkeeping update and avoiding the actual scan
+              // of the object - a typeArray contains no references,
+              // and the metadata is built-in.
+              process_grey_object<false>(obj);
+            } else {
             if (_cm->verbose_high()) {
-              gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), "
-                                     "pushing it", _worker_id, p2i(_finger));
+                gclog_or_tty->print_cr(
+                  "[%u] below the local finger (" PTR_FORMAT "), pushing " PTR_FORMAT,
+                  _worker_id, p2i(_finger), p2i(objAddr));
             }
             push(obj);
-          } else if (_curr_region != NULL && objAddr < _region_limit) {
+            }
+          } else if (_CHECK_BOTH_FINGERS_ &&
+                     _curr_region != NULL &&
+                     objAddr < _region_limit) {
             // do nothing
           } else if (objAddr < global_finger) {
             // Notice that the global finger might be moving forward
             // concurrently. This is not a problem. In the worst case, we
             // mark the object while it is above the global finger and, by

@@ -316,33 +330,24 @@
             // passed this object. In this case, the object will probably
             // be visited when a task is scanning the region and will also
             // be pushed on the stack. So, some duplicate work, but no
             // correctness problems.
 
+            if (obj->is_typeArray()) {
+              // As above, immediately scan arrays of binary data.
+              process_grey_object<false>(obj);
+            } else {
             if (_cm->verbose_high()) {
-              gclog_or_tty->print_cr("[%u] below the global finger "
-                                     "("PTR_FORMAT"), pushing it",
-                                     _worker_id, p2i(global_finger));
+                gclog_or_tty->print_cr(
+                  "[%u] below the global finger (" PTR_FORMAT "), pushing " PTR_FORMAT,
+                  _worker_id, p2i(global_finger), p2i(objAddr));
             }
             push(obj);
+            }
           } else {
             // do nothing
           }
-#else // _CHECK_BOTH_FINGERS_
-          // we will only check the global finger
-
-          if (objAddr < global_finger) {
-            // see long comment above
-
-            if (_cm->verbose_high()) {
-              gclog_or_tty->print_cr("[%u] below the global finger "
-                                     "("PTR_FORMAT"), pushing it",
-                                     _worker_id, p2i(global_finger));
-            }
-            push(obj);
-          }
-#endif // _CHECK_BOTH_FINGERS_
         }
       }
     }
   }
 }
< prev index next >