hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp
author tschatzl
Thu, 28 Jan 2016 13:30:12 +0100
changeset 35877 a2a62511d0f8
parent 35862 411842d0c882
child 37462 58bb9394a98b
permissions -rw-r--r--
8146987: Improve Parallel GC Full GC by caching results of live_words_in_range() Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value. Reviewed-by: tschatzl, mgerdin, jmasa Contributed-by: ray alex <sky1young@gmail.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
35862
411842d0c882 8146395: Add inline qualifier in oop.hpp and fix inlining in gc files
goetz
parents: 30764
diff changeset
     2
 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 823
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 823
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 823
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 28631
diff changeset
    26
#include "gc/parallel/parMarkBitMap.hpp"
35877
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
    27
#include "gc/parallel/psCompactionManager.inline.hpp"
35862
411842d0c882 8146395: Add inline qualifier in oop.hpp and fix inlining in gc files
goetz
parents: 30764
diff changeset
    28
#include "gc/parallel/psParallelCompact.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "oops/oop.inline.hpp"
25351
7c198a690050 8044775: Improve usage of umbrella header atomic.inline.hpp.
goetz
parents: 25073
diff changeset
    30
#include "runtime/atomic.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "runtime/os.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 28631
diff changeset
    32
#include "services/memTracker.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "utilities/bitMap.inline.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
ParMarkBitMap::initialize(MemRegion covered_region)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  const idx_t bits = bits_required(covered_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  // The bits will be divided evenly between two bitmaps; each of them should be
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  // an integral number of words.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  assert(bits % (BitsPerWord * 2) == 0, "region size unaligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  const size_t words = bits / BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  const size_t raw_bytes = words * sizeof(idx_t);
28631
a56cae1b428d 8066875: VirtualSpace does not use large pages
ehelin
parents: 26700
diff changeset
    45
  const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  const size_t granularity = os::vm_allocation_granularity();
17627
325871034f2c 7186737: Unable to allocate bit maps or card tables for parallel gc for the requested heap
tamao
parents: 17390
diff changeset
    47
  _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    MAX2(page_sz, granularity);
17627
325871034f2c 7186737: Unable to allocate bit maps or card tables for parallel gc for the requested heap
tamao
parents: 17390
diff changeset
    51
  ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
                       rs.base(), rs.size());
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 10565
diff changeset
    54
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 10565
diff changeset
    55
  MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 10565
diff changeset
    56
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  _virtual_space = new PSVirtualSpace(rs, page_sz);
17627
325871034f2c 7186737: Unable to allocate bit maps or card tables for parallel gc for the requested heap
tamao
parents: 17390
diff changeset
    58
  if (_virtual_space != NULL && _virtual_space->expand_by(_reserved_byte_size)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    _region_start = covered_region.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    _region_size = covered_region.word_size();
25073
e4654a279064 8043722: Swapped usage of idx_t and bm_word_t types in parMarkBitMap.cpp
tschatzl
parents: 22827
diff changeset
    61
    BitMap::bm_word_t* map = (BitMap::bm_word_t*)_virtual_space->reserved_low_addr();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    _beg_bits.set_map(map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    _beg_bits.set_size(bits / 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    _end_bits.set_map(map + words / 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    _end_bits.set_size(bits / 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  _region_start = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  _region_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  if (_virtual_space != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    delete _virtual_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    _virtual_space = NULL;
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 670
diff changeset
    74
    // Release memory reserved in the space.
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 670
diff changeset
    75
    rs.release();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
extern size_t mark_bitmap_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
extern size_t mark_bitmap_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  const idx_t beg_bit = addr_to_bit(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  if (_beg_bits.par_set_bit(beg_bit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    const idx_t end_bit = addr_to_bit(addr + size - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    bool end_bit_ok = _end_bits.par_set_bit(end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    assert(end_bit_ok, "concurrency problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    DEBUG_ONLY(Atomic::inc_ptr(&mark_bitmap_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    DEBUG_ONLY(Atomic::add_ptr(size, &mark_bitmap_size));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
35877
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   100
inline bool
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   101
ParMarkBitMap::is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   102
  return cm->last_query_begin() == beg_addr;
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   103
}
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   104
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   105
inline void
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   106
ParMarkBitMap::update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   107
  cm->set_last_query_begin(beg_addr);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   108
  cm->set_last_query_object(end_obj);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   109
  cm->set_last_query_return(result);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   110
}
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   111
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   112
size_t
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   113
ParMarkBitMap::live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  assert(beg_addr <= (HeapWord*)end_obj, "bad range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  assert(is_marked(end_obj), "end_obj must be live");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  idx_t live_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  // The bitmap routines require the right boundary to be word-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  const idx_t end_bit = addr_to_bit((HeapWord*)end_obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  const idx_t range_end = BitMap::word_align_up(end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  while (beg_bit < end_bit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    idx_t tmp_end = find_obj_end(beg_bit, range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    assert(tmp_end < end_bit, "missing end bit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    live_bits += tmp_end - beg_bit + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    beg_bit = find_obj_beg(tmp_end + 1, range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  return bits_to_words(live_bits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
35877
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   134
size_t
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   135
ParMarkBitMap::live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   136
{
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   137
  HeapWord* last_beg = cm->last_query_begin();
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   138
  oop last_obj = cm->last_query_object();
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   139
  size_t last_ret = cm->last_query_return();
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   140
  if (end_obj > last_obj) {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   141
    last_ret = last_ret + live_words_in_range_helper((HeapWord*)last_obj, end_obj);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   142
    last_obj = end_obj;
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   143
  } else if (end_obj < last_obj) {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   144
    // The cached value is for an object that is to the left (lower address) of the current
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   145
    // end_obj. Calculate back from that cached value.
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   146
    if (pointer_delta((HeapWord*)end_obj, (HeapWord*)beg_addr) > pointer_delta((HeapWord*)last_obj, (HeapWord*)end_obj)) {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   147
      last_ret = last_ret - live_words_in_range_helper((HeapWord*)end_obj, last_obj);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   148
    } else {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   149
      last_ret = live_words_in_range_helper(beg_addr, end_obj);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   150
    }
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   151
    last_obj = end_obj;
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   152
  }
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   153
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   154
  update_live_words_in_range_cache(cm, last_beg, last_obj, last_ret);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   155
  return last_ret;
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   156
}
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   157
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   158
size_t
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   159
ParMarkBitMap::live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   160
{
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   161
  // Try to reuse result from ParCompactionManager cache first.
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   162
  if (is_live_words_in_range_in_cache(cm, beg_addr)) {
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   163
    return live_words_in_range_use_cache(cm, beg_addr, end_obj);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   164
  }
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   165
  size_t ret = live_words_in_range_helper(beg_addr, end_obj);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   166
  update_live_words_in_range_cache(cm, beg_addr, end_obj, ret);
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   167
  return ret;
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   168
}
a2a62511d0f8 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
tschatzl
parents: 35862
diff changeset
   169
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
ParMarkBitMap::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
                       idx_t range_beg, idx_t range_end) const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  DEBUG_ONLY(verify_bit(range_beg);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  DEBUG_ONLY(verify_bit(range_end);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  assert(range_beg <= range_end, "live range invalid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // The bitmap routines require the right boundary to be word-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  const idx_t search_end = BitMap::word_align_up(range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  idx_t cur_beg = find_obj_beg(range_beg, search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  while (cur_beg < range_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    const idx_t cur_end = find_obj_end(cur_beg, search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    if (cur_end >= range_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
      // The obj ends outside the range.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
      live_closure->set_source(bit_to_addr(cur_beg));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      return incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    const size_t size = obj_size(cur_beg, cur_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    if (status != incomplete) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
      assert(status == would_overflow || status == full, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
      return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    // Successfully processed the object; look for the next object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    cur_beg = find_obj_beg(cur_end + 1, search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  live_closure->set_source(bit_to_addr(range_end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  return complete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
ParMarkBitMap::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
                       ParMarkBitMapClosure* dead_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
                       idx_t range_beg, idx_t range_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
                       idx_t dead_range_end) const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  DEBUG_ONLY(verify_bit(range_beg);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  DEBUG_ONLY(verify_bit(range_end);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  DEBUG_ONLY(verify_bit(dead_range_end);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  assert(range_beg <= range_end, "live range invalid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  assert(range_end <= dead_range_end, "dead range invalid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  // The bitmap routines require the right boundary to be word-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  const idx_t live_search_end = BitMap::word_align_up(range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  const idx_t dead_search_end = BitMap::word_align_up(dead_range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  idx_t cur_beg = range_beg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  if (range_beg < range_end && is_unmarked(range_beg)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    // The range starts with dead space.  Look for the next object, then fill.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    cur_beg = find_obj_beg(range_beg + 1, dead_search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    const size_t size = obj_size(range_beg, dead_space_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    dead_closure->do_addr(bit_to_addr(range_beg), size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  while (cur_beg < range_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    const idx_t cur_end = find_obj_end(cur_beg, live_search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
    if (cur_end >= range_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
      // The obj ends outside the range.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
      live_closure->set_source(bit_to_addr(cur_beg));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
      return incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    const size_t size = obj_size(cur_beg, cur_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
    IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    if (status != incomplete) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
      assert(status == would_overflow || status == full, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    // Look for the start of the next object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    const idx_t dead_space_beg = cur_end + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
    cur_beg = find_obj_beg(dead_space_beg, dead_search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
    if (cur_beg > dead_space_beg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
      // Found dead space; compute the size and invoke the dead closure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
      const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
      const size_t size = obj_size(dead_space_beg, dead_space_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
      dead_closure->do_addr(bit_to_addr(dead_space_beg), size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  live_closure->set_source(bit_to_addr(range_end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  return complete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
void ParMarkBitMap::verify_clear() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  const idx_t* const beg = (const idx_t*)_virtual_space->committed_low_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  const idx_t* const end = (const idx_t*)_virtual_space->committed_high_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  for (const idx_t* p = beg; p < end; ++p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    assert(*p == 0, "bitmap not clear");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
#endif  // #ifdef ASSERT