src/share/vm/gc_implementation/g1/satbQueue.cpp

changeset 7831
2e5e058881f4
parent 7476
c2844108a708
child 7832
b5d14ef905b5
     1.1 --- a/src/share/vm/gc_implementation/g1/satbQueue.cpp	Wed Apr 15 12:16:01 2015 -0400
     1.2 +++ b/src/share/vm/gc_implementation/g1/satbQueue.cpp	Wed Apr 15 16:37:57 2015 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -35,30 +35,67 @@
    1.11  PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    1.12  
    1.13  void ObjPtrQueue::flush() {
    1.14 -  // The buffer might contain refs into the CSet. We have to filter it
    1.15 -  // first before we flush it, otherwise we might end up with an
    1.16 -  // enqueued buffer with refs into the CSet which breaks our invariants.
    1.17 +  // Filter now to possibly save work later.  If filtering empties the
    1.18 +  // buffer then flush_impl can deallocate the buffer.
    1.19    filter();
    1.20    flush_impl();
    1.21  }
    1.22  
    1.23 -// This method removes entries from an SATB buffer that will not be
    1.24 -// useful to the concurrent marking threads. An entry is removed if it
    1.25 -// satisfies one of the following conditions:
    1.26 +// Return true if a SATB buffer entry refers to an object that
    1.27 +// requires marking.
    1.28  //
    1.29 -// * it points to an object outside the G1 heap (G1's concurrent
    1.30 -//     marking only visits objects inside the G1 heap),
    1.31 -// * it points to an object that has been allocated since marking
    1.32 -//     started (according to SATB those objects do not need to be
    1.33 -//     visited during marking), or
    1.34 -// * it points to an object that has already been marked (no need to
    1.35 -//     process it again).
    1.36 +// The entry must point into the G1 heap.  In particular, it must not
    1.37 +// be a NULL pointer.  NULL pointers are pre-filtered and never
    1.38 +// inserted into a SATB buffer.
    1.39  //
    1.40 -// The rest of the entries will be retained and are compacted towards
    1.41 -// the top of the buffer. Note that, because we do not allow old
    1.42 -// regions in the CSet during marking, all objects on the CSet regions
    1.43 -// are young (eden or survivors) and therefore implicitly live. So any
    1.44 -// references into the CSet will be removed during filtering.
    1.45 +// An entry that is below the NTAMS pointer for the containing heap
    1.46 +// region requires marking. Such an entry must point to a valid object.
    1.47 +//
    1.48 +// An entry that is at least the NTAMS pointer for the containing heap
    1.49 +// region might be any of the following, none of which should be marked.
    1.50 +//
    1.51 +// * A reference to an object allocated since marking started.
    1.52 +//   According to SATB, such objects are implicitly kept live and do
    1.53 +//   not need to be dealt with via SATB buffer processing.
    1.54 +//
    1.55 +// * A reference to a young generation object. Young objects are
    1.56 +//   handled separately and are not marked by concurrent marking.
    1.57 +//
    1.58 +// * A stale reference to a young generation object. If a young
    1.59 +//   generation object reference is recorded and not filtered out
    1.60 +//   before being moved by a young collection, the reference becomes
    1.61 +//   stale.
    1.62 +//
    1.63 +// * A stale reference to an eagerly reclaimed humongous object.  If a
    1.64 +//   humongous object is recorded and then reclaimed, the reference
    1.65 +//   becomes stale.
    1.66 +//
    1.67 +// The stale reference cases are implicitly handled by the NTAMS
    1.68 +// comparison. Because of the possibility of stale references, buffer
    1.69 +// processing must be somewhat circumspect and not assume entries
    1.70 +// in an unfiltered buffer refer to valid objects.
    1.71 +
    1.72 +inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
    1.73 +  // Includes rejection of NULL pointers.
    1.74 +  assert(heap->is_in_reserved(entry),
    1.75 +         err_msg("Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry)));
    1.76 +
    1.77 +  HeapRegion* region = heap->heap_region_containing_raw(entry);
    1.78 +  assert(region != NULL, err_msg("No region for " PTR_FORMAT, p2i(entry)));
    1.79 +  if (entry >= region->next_top_at_mark_start()) {
    1.80 +    return false;
    1.81 +  }
    1.82 +
    1.83 +  assert(((oop)entry)->is_oop(true /* ignore mark word */),
    1.84 +         err_msg("Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)));
    1.85 +
    1.86 +  return true;
    1.87 +}
    1.88 +
    1.89 +// This method removes entries from a SATB buffer that will not be
    1.90 +// useful to the concurrent marking threads.  Entries are retained if
    1.91 +// they require marking and are not already marked. Retained entries
    1.92 +// are compacted toward the top of the buffer.
    1.93  
    1.94  void ObjPtrQueue::filter() {
    1.95    G1CollectedHeap* g1h = G1CollectedHeap::heap();
    1.96 @@ -80,26 +117,25 @@
    1.97      assert(i > 0, "we should have at least one more entry to process");
    1.98      i -= oopSize;
    1.99      debug_only(entries += 1;)
   1.100 -    oop* p = (oop*) &buf[byte_index_to_index((int) i)];
   1.101 -    oop obj = *p;
   1.102 +    void** p = &buf[byte_index_to_index((int) i)];
   1.103 +    void* entry = *p;
   1.104      // NULL the entry so that unused parts of the buffer contain NULLs
   1.105      // at the end. If we are going to retain it we will copy it to its
   1.106      // final place. If we have retained all entries we have visited so
   1.107      // far, we'll just end up copying it to the same place.
   1.108      *p = NULL;
   1.109  
   1.110 -    bool retain = g1h->is_obj_ill(obj);
   1.111 -    if (retain) {
   1.112 +    if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) {
   1.113        assert(new_index > 0, "we should not have already filled up the buffer");
   1.114        new_index -= oopSize;
   1.115        assert(new_index >= i,
   1.116               "new_index should never be below i, as we alwaysr compact 'up'");
   1.117 -      oop* new_p = (oop*) &buf[byte_index_to_index((int) new_index)];
   1.118 +      void** new_p = &buf[byte_index_to_index((int) new_index)];
   1.119        assert(new_p >= p, "the destination location should never be below "
   1.120               "the source as we always compact 'up'");
   1.121        assert(*new_p == NULL,
   1.122               "we should have already cleared the destination location");
   1.123 -      *new_p = obj;
   1.124 +      *new_p = entry;
   1.125        debug_only(retained += 1;)
   1.126      }
   1.127    }
   1.128 @@ -186,17 +222,6 @@
   1.129  }
   1.130  #endif // PRODUCT
   1.131  
   1.132 -#ifdef ASSERT
   1.133 -void ObjPtrQueue::verify_oops_in_buffer() {
   1.134 -  if (_buf == NULL) return;
   1.135 -  for (size_t i = _index; i < _sz; i += oopSize) {
   1.136 -    oop obj = (oop)_buf[byte_index_to_index((int)i)];
   1.137 -    assert(obj != NULL && obj->is_oop(true /* ignore mark word */),
   1.138 -           "Not an oop");
   1.139 -  }
   1.140 -}
   1.141 -#endif
   1.142 -
   1.143  #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
   1.144  #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
   1.145  #endif // _MSC_VER
   1.146 @@ -216,7 +241,6 @@
   1.147  }
   1.148  
   1.149  void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
   1.150 -  DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();)
   1.151    t->satb_mark_queue().handle_zero_index();
   1.152  }
   1.153  

mercurial