Merge

Thu, 20 Aug 2020 04:10:59 +0100

author
andrew
date
Thu, 20 Aug 2020 04:10:59 +0100
changeset 9983
776722456213
parent 9981
636cc78f0f74
parent 9982
72053ed6f8d4
child 9984
63dafc005680

Merge

     1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Aug 18 03:41:25 2020 +0100
     1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Aug 20 04:10:59 2020 +0100
     1.3 @@ -3096,7 +3096,10 @@
     1.4    }
     1.5  
     1.6    void do_object_work(oop obj) {
     1.7 -    guarantee(!_g1h->obj_in_cs(obj),
     1.8 +    guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || obj->is_oop(),
     1.9 +              err_msg("Non-oop " PTR_FORMAT ", phase: %s, info: %d",
    1.10 +                      p2i((void*) obj), phase_str(), _info));
    1.11 +    guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->obj_in_cs(obj),
    1.12                err_msg("obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
    1.13                        p2i((void*) obj), phase_str(), _info));
    1.14    }
    1.15 @@ -3506,18 +3509,25 @@
    1.16  template<bool scan>
    1.17  inline void CMTask::process_grey_object(oop obj) {
    1.18    assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
    1.19 -  assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
    1.20  
    1.21    if (_cm->verbose_high()) {
    1.22      gclog_or_tty->print_cr("[%u] processing grey object " PTR_FORMAT,
    1.23                             _worker_id, p2i((void*) obj));
    1.24    }
    1.25  
    1.26 -  size_t obj_size = obj->size();
    1.27 -  _words_scanned += obj_size;
    1.28 +  assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked((HeapWord*) obj),
    1.29 +         "Any stolen object should be a slice or marked");
    1.30  
    1.31    if (scan) {
    1.32 -    obj->oop_iterate(_cm_oop_closure);
    1.33 +    if (G1CMObjArrayProcessor::is_array_slice(obj)) {
    1.34 +      _words_scanned += _objArray_processor.process_slice(obj);
    1.35 +    } else if (G1CMObjArrayProcessor::should_be_sliced(obj)) {
    1.36 +      _words_scanned += _objArray_processor.process_obj(obj);
    1.37 +    } else {
    1.38 +      size_t obj_size = obj->size();
    1.39 +      _words_scanned += obj_size;
    1.40 +      obj->oop_iterate(_cm_oop_closure);;
    1.41 +    }
    1.42    }
    1.43    statsOnly( ++_objs_scanned );
    1.44    check_limits();
    1.45 @@ -3877,6 +3887,8 @@
    1.46                               _worker_id, n);
    1.47      }
    1.48      for (int i = 0; i < n; ++i) {
    1.49 +      assert(G1CMObjArrayProcessor::is_array_slice(buffer[i]) || buffer[i]->is_oop(),
    1.50 +             err_msg("Element " PTR_FORMAT " must be an array slice or oop", p2i(buffer[i])));
    1.51        bool success = _task_queue->push(buffer[i]);
    1.52        // We only call this when the local queue is empty or under a
    1.53        // given target limit. So, we do not expect this push to fail.
    1.54 @@ -3895,7 +3907,9 @@
    1.55  }
    1.56  
    1.57  void CMTask::drain_local_queue(bool partially) {
    1.58 -  if (has_aborted()) return;
    1.59 +  if (has_aborted()) {
    1.60 +    return;
    1.61 +  }
    1.62  
    1.63    // Decide what the target size is, depending whether we're going to
    1.64    // drain it partially (so that other tasks can steal if they run out
    1.65 @@ -3923,10 +3937,6 @@
    1.66                                 p2i((void*) obj));
    1.67        }
    1.68  
    1.69 -      assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
    1.70 -      assert(!_g1h->is_on_master_free_list(
    1.71 -                  _g1h->heap_region_containing((HeapWord*) obj)), "invariant");
    1.72 -
    1.73        scan_object(obj);
    1.74  
    1.75        if (_task_queue->size() <= target_size || has_aborted()) {
    1.76 @@ -4427,8 +4437,6 @@
    1.77  
    1.78          statsOnly( ++_steals );
    1.79  
    1.80 -        assert(_nextMarkBitMap->isMarked((HeapWord*) obj),
    1.81 -               "any stolen object should be marked");
    1.82          scan_object(obj);
    1.83  
    1.84          // And since we're towards the end, let's totally drain the
    1.85 @@ -4602,6 +4610,7 @@
    1.86                 CMTaskQueueSet* task_queues)
    1.87    : _g1h(G1CollectedHeap::heap()),
    1.88      _worker_id(worker_id), _cm(cm),
    1.89 +    _objArray_processor(this),
    1.90      _claimed(false),
    1.91      _nextMarkBitMap(NULL), _hash_seed(17),
    1.92      _task_queue(task_queue),
     2.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Aug 18 03:41:25 2020 +0100
     2.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Aug 20 04:10:59 2020 +0100
     2.3 @@ -26,6 +26,7 @@
     2.4  #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP
     2.5  
     2.6  #include "classfile/javaClasses.hpp"
     2.7 +#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.hpp"
     2.8  #include "gc_implementation/g1/heapRegionSet.hpp"
     2.9  #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
    2.10  #include "gc_implementation/shared/gcId.hpp"
    2.11 @@ -942,7 +943,7 @@
    2.12      words_scanned_period          = 12*1024,
    2.13      // the regular clock call is called once the number of visited
    2.14      // references reaches this limit
    2.15 -    refs_reached_period           = 384,
    2.16 +    refs_reached_period           = 1024,
    2.17      // initial value for the hash seed, used in the work stealing code
    2.18      init_hash_seed                = 17,
    2.19      // how many entries will be transferred between global stack and
    2.20 @@ -950,6 +951,8 @@
    2.21      global_stack_transfer_size    = 16
    2.22    };
    2.23  
    2.24 +  G1CMObjArrayProcessor       _objArray_processor;
    2.25 +
    2.26    uint                        _worker_id;
    2.27    G1CollectedHeap*            _g1h;
    2.28    ConcurrentMark*             _cm;
    2.29 @@ -1110,6 +1113,9 @@
    2.30    template<bool scan> void process_grey_object(oop obj);
    2.31  
    2.32  public:
    2.33 +  // Apply the closure on the given area of the objArray. Return the number of words
    2.34 +  // scanned.
    2.35 +  inline size_t scan_objArray(objArrayOop obj, MemRegion mr);
    2.36    // It resets the task; it should be called right at the beginning of
    2.37    // a marking phase.
    2.38    void reset(CMBitMap* _nextMarkBitMap);
     3.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Tue Aug 18 03:41:25 2020 +0100
     3.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Thu Aug 20 04:10:59 2020 +0100
     3.3 @@ -27,6 +27,7 @@
     3.4  
     3.5  #include "gc_implementation/g1/concurrentMark.hpp"
     3.6  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
     3.7 +#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp"
     3.8  
     3.9  // Utility routine to set an exclusive range of cards on the given
    3.10  // card liveness bitmap
    3.11 @@ -224,11 +225,11 @@
    3.12  
    3.13  inline void CMTask::push(oop obj) {
    3.14    HeapWord* objAddr = (HeapWord*) obj;
    3.15 -  assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
    3.16 -  assert(!_g1h->is_on_master_free_list(
    3.17 +  assert(G1CMObjArrayProcessor::is_array_slice(obj) || _g1h->is_in_g1_reserved(objAddr), "invariant");
    3.18 +  assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_on_master_free_list(
    3.19                _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
    3.20 -  assert(!_g1h->is_obj_ill(obj), "invariant");
    3.21 -  assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
    3.22 +  assert(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_obj_ill(obj), "invariant");
    3.23 +  assert(G1CMObjArrayProcessor::is_array_slice(obj) || _nextMarkBitMap->isMarked(objAddr), "invariant");
    3.24  
    3.25    if (_cm->verbose_high()) {
    3.26      gclog_or_tty->print_cr("[%u] pushing " PTR_FORMAT, _worker_id, p2i((void*) obj));
    3.27 @@ -365,6 +366,11 @@
    3.28    }
    3.29  }
    3.30  
    3.31 +inline size_t CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
    3.32 +  obj->oop_iterate(_cm_oop_closure, mr);
    3.33 +  return mr.word_size();
    3.34 +}
    3.35 +
    3.36  inline void ConcurrentMark::markPrev(oop p) {
    3.37    assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
    3.38    // Note we are overriding the read-only view of the prev map here, via
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.cpp	Thu Aug 20 04:10:59 2020 +0100
     4.3 @@ -0,0 +1,87 @@
     4.4 +/*
     4.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 + * or visit www.oracle.com if you need additional information or have any
    4.24 + * questions.
    4.25 + *
    4.26 + */
    4.27 +
    4.28 +#include "precompiled.hpp"
    4.29 +#include "gc_implementation/g1/concurrentMark.inline.hpp"
    4.30 +#include "gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp"
    4.31 +
    4.32 +oop G1CMObjArrayProcessor::encode_array_slice(HeapWord* addr) {
    4.33 +  return oop((void*)((uintptr_t)addr | ArraySliceBit));
    4.34 +}
    4.35 +
    4.36 +HeapWord* G1CMObjArrayProcessor::decode_array_slice(oop value) {
    4.37 +  assert(is_array_slice(value), err_msg("Given value " PTR_FORMAT " is not an array slice", p2i(value)));
    4.38 +  return (HeapWord*)((uintptr_t)(void*)value & ~ArraySliceBit);
    4.39 +}
    4.40 +
    4.41 +void G1CMObjArrayProcessor::push_array_slice(HeapWord* what) {
    4.42 +  oop obj = encode_array_slice(what);
    4.43 +  _task->push(obj);
    4.44 +}
    4.45 +
    4.46 +size_t G1CMObjArrayProcessor::process_array_slice(objArrayOop obj, HeapWord* start_from, size_t remaining) {
    4.47 +  size_t words_to_scan = MIN2(remaining, ObjArrayMarkingStride);
    4.48 +
    4.49 +  if (remaining > ObjArrayMarkingStride) {
    4.50 +    push_array_slice(start_from + ObjArrayMarkingStride);
    4.51 +  }
    4.52 +
    4.53 +  // Then process current area.
    4.54 +  MemRegion mr(start_from, words_to_scan);
    4.55 +  return _task->scan_objArray(obj, mr);
    4.56 +}
    4.57 +
    4.58 +size_t G1CMObjArrayProcessor::process_obj(oop obj) {
    4.59 +  assert(should_be_sliced(obj), err_msg("Must be an array object %d and large " SIZE_FORMAT, obj->is_objArray(), (size_t)obj->size()));
    4.60 +
    4.61 +  return process_array_slice(objArrayOop(obj), (HeapWord*)obj, (size_t)objArrayOop(obj)->size());
    4.62 +}
    4.63 +
    4.64 +size_t G1CMObjArrayProcessor::process_slice(oop obj) {
    4.65 +  HeapWord* const decoded_address = decode_array_slice(obj);
    4.66 +
    4.67 +  // Find the start address of the objArrayOop.
    4.68 +  // Shortcut the BOT access if the given address is from a humongous object. The BOT
    4.69 +  // slide is fast enough for "smaller" objects in non-humongous regions, but is slower
    4.70 +  // than directly using heap region table.
    4.71 +  G1CollectedHeap* g1h = G1CollectedHeap::heap();
    4.72 +  HeapRegion* r = g1h->heap_region_containing(decoded_address);
    4.73 +
    4.74 +  HeapWord* const start_address = r->isHumongous() ?
    4.75 +                                  r->humongous_start_region()->bottom() :
    4.76 +                                  g1h->block_start(decoded_address);
    4.77 +
    4.78 +  assert(oop(start_address)->is_objArray(), err_msg("Address " PTR_FORMAT " does not refer to an object array ", p2i(start_address)));
    4.79 +  assert(start_address < decoded_address,
    4.80 +         err_msg("Object start address " PTR_FORMAT " must be smaller than decoded address " PTR_FORMAT,
    4.81 +         p2i(start_address),
    4.82 +         p2i(decoded_address)));
    4.83 +
    4.84 +  objArrayOop objArray = objArrayOop(start_address);
    4.85 +
    4.86 +  size_t already_scanned = decoded_address - start_address;
    4.87 +  size_t remaining = objArray->size() - already_scanned;
    4.88 +
    4.89 +  return process_array_slice(objArray, decoded_address, remaining);
    4.90 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.hpp	Thu Aug 20 04:10:59 2020 +0100
     5.3 @@ -0,0 +1,70 @@
     5.4 +/*
     5.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + *
    5.26 + */
    5.27 +
    5.28 +#ifndef SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP
    5.29 +#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP
    5.30 +
    5.31 +#include "oops/oopsHierarchy.hpp"
    5.32 +#include "memory/allocation.hpp"
    5.33 +
    5.34 +class CMTask;
    5.35 +
    5.36 +// Helper class to mark through large objArrays during marking in an efficient way.
    5.37 +// Instead of pushing large object arrays, we push continuations onto the
    5.38 +// mark stack. These continuations are identified by having their LSB set.
    5.39 +// This allows incremental processing of large objects.
    5.40 +class G1CMObjArrayProcessor VALUE_OBJ_CLASS_SPEC {
    5.41 +private:
    5.42 +  // The bit mask for the continuation indicator of elements on the mark stack.
    5.43 +  static const size_t ArraySliceBit = 1;
    5.44 +
    5.45 +  // Reference to the task for doing the actual work.
    5.46 +  CMTask* _task;
    5.47 +
    5.48 +  // Encodes the given address as a continuation "oop".
    5.49 +  oop encode_array_slice(HeapWord* addr);
    5.50 +  // Remove the continuation marker from the given oop from the mark stack.
    5.51 +  HeapWord* decode_array_slice(oop value);
    5.52 +
    5.53 +  // Push the continuation at the given address onto the mark stack.
    5.54 +  void push_array_slice(HeapWord* addr);
    5.55 +
    5.56 +  // Process (apply the closure) on the given continuation of the given objArray.
    5.57 +  size_t process_array_slice(objArrayOop const obj, HeapWord* start_from, size_t remaining);
    5.58 +public:
    5.59 +  static bool is_array_slice(void* obj) { return ((uintptr_t)obj & ArraySliceBit) != 0; }
    5.60 +
    5.61 +  static bool should_be_sliced(oop obj);
    5.62 +
    5.63 +  G1CMObjArrayProcessor(CMTask* task) : _task(task) {
    5.64 +  }
    5.65 +
    5.66 +  // Process the given continuation "oop". Returns the number of words scanned.
    5.67 +  size_t process_slice(oop obj);
    5.68 +  // Start processing the given objArrayOop by scanning the header and pushing its
    5.69 +  // continuation.
    5.70 +  size_t process_obj(oop obj);
    5.71 +};
    5.72 +
    5.73 +#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_HPP */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/share/vm/gc_implementation/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp	Thu Aug 20 04:10:59 2020 +0100
     6.3 @@ -0,0 +1,36 @@
     6.4 +/*
     6.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.23 + * or visit www.oracle.com if you need additional information or have any
    6.24 + * questions.
    6.25 + *
    6.26 + */
    6.27 +
    6.28 +#ifndef SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP
    6.29 +#define SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP
    6.30 +
    6.31 +#include "oops/oop.inline.hpp"
    6.32 +#include "oops/oopsHierarchy.hpp"
    6.33 +#include "runtime/globals.hpp"
    6.34 +
    6.35 +inline bool G1CMObjArrayProcessor::should_be_sliced(oop obj) {
    6.36 +  return obj->is_objArray() && ((size_t)((objArrayOop)obj)->size()) >= 2 * ObjArrayMarkingStride;
    6.37 +}
    6.38 +
    6.39 +#endif /* SHARE_VM_GC_G1_G1CONCURRENTMARKOBJARRAYPROCESSOR_INLINE_HPP */
     7.1 --- a/src/share/vm/runtime/globals.hpp	Tue Aug 18 03:41:25 2020 +0100
     7.2 +++ b/src/share/vm/runtime/globals.hpp	Thu Aug 20 04:10:59 2020 +0100
     7.3 @@ -2019,7 +2019,7 @@
     7.4    experimental(uintx, WorkStealingSpinToYieldRatio, 10,                     \
     7.5            "Ratio of hard spins to calls to yield")                          \
     7.6                                                                              \
     7.7 -  develop(uintx, ObjArrayMarkingStride, 512,                                \
     7.8 +  develop(uintx, ObjArrayMarkingStride, 2048,                               \
     7.9            "Number of object array elements to push onto the marking stack " \
    7.10            "before pushing a continuation entry")                            \
    7.11                                                                              \
     8.1 --- a/src/share/vm/utilities/taskqueue.hpp	Tue Aug 18 03:41:25 2020 +0100
     8.2 +++ b/src/share/vm/utilities/taskqueue.hpp	Thu Aug 20 04:10:59 2020 +0100
     8.3 @@ -332,7 +332,8 @@
     8.4      //            index, &_elems[index], _elems[index]);
     8.5      E* t = (E*)&_elems[index];      // cast away volatility
     8.6      oop* p = (oop*)t;
     8.7 -    assert((*t)->is_oop_or_null(), "Not an oop or null");
     8.8 +    // G1 does its own checking
     8.9 +    assert(UseG1GC || (*t)->is_oop_or_null(), "Not an oop or null");
    8.10      f->do_oop(p);
    8.11    }
    8.12    // tty->print_cr("END OopTaskQueue::oops_do");

mercurial