hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
author tonyp
Wed, 25 Jan 2012 12:58:23 -0500
changeset 11584 e1df4d08a1f4
parent 7904 e90e097fced4
child 13195 be27e1b6a4b9
permissions -rw-r--r--
7127706: G1: re-enable survivors during the initial-mark pause Summary: Re-enable survivors during the initial-mark pause. Afterwards, the concurrent marking threads have to scan them and mark everything reachable from them. The next GC will have to wait for the survivors to be scanned. Reviewed-by: brutisso, johnc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     1
/*
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
     2
 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     4
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     7
 * published by the Free Software Foundation.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     8
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    13
 * accompanied this code).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    14
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5402
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5402
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: 5402
diff changeset
    21
 * questions.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    22
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    23
 */
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6983
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6983
diff changeset
    26
#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6983
diff changeset
    27
#include "memory/space.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6983
diff changeset
    28
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6983
diff changeset
    29
#include "runtime/java.hpp"
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    30
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    31
//////////////////////////////////////////////////////////////////////
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    32
// G1BlockOffsetSharedArray
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    33
//////////////////////////////////////////////////////////////////////
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    34
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    35
G1BlockOffsetSharedArray::G1BlockOffsetSharedArray(MemRegion reserved,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    36
                                                   size_t init_word_size) :
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    37
  _reserved(reserved), _end(NULL)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    38
{
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    39
  size_t size = compute_size(reserved.word_size());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    40
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(size));
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    41
  if (!rs.is_reserved()) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    42
    vm_exit_during_initialization("Could not reserve enough space for heap offset array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    43
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    44
  if (!_vs.initialize(rs, 0)) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    45
    vm_exit_during_initialization("Could not reserve enough space for heap offset array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    46
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    47
  _offset_array = (u_char*)_vs.low_boundary();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    48
  resize(init_word_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    49
  if (TraceBlockOffsetTable) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    50
    gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    51
    gclog_or_tty->print_cr("  "
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    52
                  "  rs.base(): " INTPTR_FORMAT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    53
                  "  rs.size(): " INTPTR_FORMAT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    54
                  "  rs end(): " INTPTR_FORMAT,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    55
                  rs.base(), rs.size(), rs.base() + rs.size());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    56
    gclog_or_tty->print_cr("  "
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    57
                  "  _vs.low_boundary(): " INTPTR_FORMAT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    58
                  "  _vs.high_boundary(): " INTPTR_FORMAT,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    59
                  _vs.low_boundary(),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    60
                  _vs.high_boundary());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    61
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    62
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    63
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    64
void G1BlockOffsetSharedArray::resize(size_t new_word_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    65
  assert(new_word_size <= _reserved.word_size(), "Resize larger than reserved");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    66
  size_t new_size = compute_size(new_word_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    67
  size_t old_size = _vs.committed_size();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    68
  size_t delta;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    69
  char* high = _vs.high();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    70
  _end = _reserved.start() + new_word_size;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    71
  if (new_size > old_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    72
    delta = ReservedSpace::page_align_size_up(new_size - old_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    73
    assert(delta > 0, "just checking");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    74
    if (!_vs.expand_by(delta)) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    75
      // Do better than this for Merlin
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    76
      vm_exit_out_of_memory(delta, "offset table expansion");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    77
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    78
    assert(_vs.high() == high + delta, "invalid expansion");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    79
    // Initialization of the contents is left to the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    80
    // G1BlockOffsetArray that uses it.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    81
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    82
    delta = ReservedSpace::page_align_size_down(old_size - new_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    83
    if (delta == 0) return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    84
    _vs.shrink_by(delta);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    85
    assert(_vs.high() == high - delta, "invalid expansion");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    86
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    87
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    88
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    89
bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    90
  assert(p >= _reserved.start(), "just checking");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    91
  size_t delta = pointer_delta(p, _reserved.start());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    92
  return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    93
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    94
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    95
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    96
//////////////////////////////////////////////////////////////////////
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    97
// G1BlockOffsetArray
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    98
//////////////////////////////////////////////////////////////////////
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    99
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   100
G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   101
                                       MemRegion mr, bool init_to_zero) :
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   102
  G1BlockOffsetTable(mr.start(), mr.end()),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   103
  _unallocated_block(_bottom),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   104
  _array(array), _csp(NULL),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   105
  _init_to_zero(init_to_zero) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   106
  assert(_bottom <= _end, "arguments out of order");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   107
  if (!_init_to_zero) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   108
    // initialize cards to point back to mr.start()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   109
    set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   110
    _array->set_offset_array(0, 0);  // set first card to 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   111
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   112
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   113
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   114
void G1BlockOffsetArray::set_space(Space* sp) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   115
  _sp = sp;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   116
  _csp = sp->toContiguousSpace();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   117
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   118
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   119
// The arguments follow the normal convention of denoting
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   120
// a right-open interval: [start, end)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   121
void
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   122
G1BlockOffsetArray:: set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   123
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   124
  if (start >= end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   125
    // The start address is equal to the end address (or to
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   126
    // the right of the end address) so there are not cards
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   127
    // that need to be updated..
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   128
    return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   129
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   130
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   131
  // Write the backskip value for each region.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   132
  //
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   133
  //    offset
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   134
  //    card             2nd                       3rd
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   135
  //     | +- 1st        |                         |
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   136
  //     v v             v                         v
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   137
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   138
  //    |x|0|0|0|0|0|0|0|1|1|1|1|1|1| ... |1|1|1|1|2|2|2|2|2|2| ...
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   139
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   140
  //    11              19                        75
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   141
  //      12
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   142
  //
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   143
  //    offset card is the card that points to the start of an object
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   144
  //      x - offset value of offset card
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   145
  //    1st - start of first logarithmic region
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   146
  //      0 corresponds to logarithmic value N_words + 0 and 2**(3 * 0) = 1
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   147
  //    2nd - start of second logarithmic region
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   148
  //      1 corresponds to logarithmic value N_words + 1 and 2**(3 * 1) = 8
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   149
  //    3rd - start of third logarithmic region
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   150
  //      2 corresponds to logarithmic value N_words + 2 and 2**(3 * 2) = 64
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   151
  //
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   152
  //    integer below the block offset entry is an example of
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   153
  //    the index of the entry
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   154
  //
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   155
  //    Given an address,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   156
  //      Find the index for the address
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   157
  //      Find the block offset table entry
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   158
  //      Convert the entry to a back slide
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   159
  //        (e.g., with today's, offset = 0x81 =>
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   160
  //          back slip = 2**(3*(0x81 - N_words)) = 2**3) = 8
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   161
  //      Move back N (e.g., 8) entries and repeat with the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   162
  //        value of the new entry
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   163
  //
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   164
  size_t start_card = _array->index_for(start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   165
  size_t end_card = _array->index_for(end-1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   166
  assert(start ==_array->address_for_index(start_card), "Precondition");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   167
  assert(end ==_array->address_for_index(end_card)+N_words, "Precondition");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   168
  set_remainder_to_point_to_start_incl(start_card, end_card); // closed interval
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   169
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   170
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   171
// Unlike the normal convention in this code, the argument here denotes
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   172
// a closed, inclusive interval: [start_card, end_card], cf set_remainder_to_point_to_start()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   173
// above.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   174
void
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   175
G1BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t end_card) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   176
  if (start_card > end_card) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   177
    return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   178
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   179
  assert(start_card > _array->index_for(_bottom), "Cannot be first card");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   180
  assert(_array->offset_array(start_card-1) <= N_words,
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   181
         "Offset card has an unexpected value");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   182
  size_t start_card_for_region = start_card;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   183
  u_char offset = max_jubyte;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   184
  for (int i = 0; i < BlockOffsetArray::N_powers; i++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   185
    // -1 so that the the card with the actual offset is counted.  Another -1
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   186
    // so that the reach ends in this region and not at the start
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   187
    // of the next.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   188
    size_t reach = start_card - 1 + (BlockOffsetArray::power_to_cards_back(i+1) - 1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   189
    offset = N_words + i;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   190
    if (reach >= end_card) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   191
      _array->set_offset_array(start_card_for_region, end_card, offset);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   192
      start_card_for_region = reach + 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   193
      break;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   194
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   195
    _array->set_offset_array(start_card_for_region, reach, offset);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   196
    start_card_for_region = reach + 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   197
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   198
  assert(start_card_for_region > end_card, "Sanity check");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   199
  DEBUG_ONLY(check_all_cards(start_card, end_card);)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   200
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   201
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   202
// The block [blk_start, blk_end) has been allocated;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   203
// adjust the block offset table to represent this information;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   204
// right-open interval: [blk_start, blk_end)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   205
void
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   206
G1BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   207
  mark_block(blk_start, blk_end);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   208
  allocated(blk_start, blk_end);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   209
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   210
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   211
// Adjust BOT to show that a previously whole block has been split
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   212
// into two.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   213
void G1BlockOffsetArray::split_block(HeapWord* blk, size_t blk_size,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   214
                                     size_t left_blk_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   215
  // Verify that the BOT shows [blk, blk + blk_size) to be one block.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   216
  verify_single_block(blk, blk_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   217
  // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   218
  // is one single block.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   219
  mark_block(blk + left_blk_size, blk + blk_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   220
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   221
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   222
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   223
// Action_mark - update the BOT for the block [blk_start, blk_end).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   224
//               Current typical use is for splitting a block.
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   225
// Action_single - update the BOT for an allocation.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   226
// Action_verify - BOT verification.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   227
void G1BlockOffsetArray::do_block_internal(HeapWord* blk_start,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   228
                                           HeapWord* blk_end,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   229
                                           Action action) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   230
  assert(Universe::heap()->is_in_reserved(blk_start),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   231
         "reference must be into the heap");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   232
  assert(Universe::heap()->is_in_reserved(blk_end-1),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   233
         "limit must be within the heap");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   234
  // This is optimized to make the test fast, assuming we only rarely
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   235
  // cross boundaries.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   236
  uintptr_t end_ui = (uintptr_t)(blk_end - 1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   237
  uintptr_t start_ui = (uintptr_t)blk_start;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   238
  // Calculate the last card boundary preceding end of blk
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   239
  intptr_t boundary_before_end = (intptr_t)end_ui;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   240
  clear_bits(boundary_before_end, right_n_bits(LogN));
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   241
  if (start_ui <= (uintptr_t)boundary_before_end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   242
    // blk starts at or crosses a boundary
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   243
    // Calculate index of card on which blk begins
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   244
    size_t    start_index = _array->index_for(blk_start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   245
    // Index of card on which blk ends
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   246
    size_t    end_index   = _array->index_for(blk_end - 1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   247
    // Start address of card on which blk begins
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   248
    HeapWord* boundary    = _array->address_for_index(start_index);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   249
    assert(boundary <= blk_start, "blk should start at or after boundary");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   250
    if (blk_start != boundary) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   251
      // blk starts strictly after boundary
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   252
      // adjust card boundary and start_index forward to next card
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   253
      boundary += N_words;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   254
      start_index++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   255
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   256
    assert(start_index <= end_index, "monotonicity of index_for()");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   257
    assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   258
    switch (action) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   259
      case Action_mark: {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   260
        if (init_to_zero()) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   261
          _array->set_offset_array(start_index, boundary, blk_start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   262
          break;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   263
        } // Else fall through to the next case
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   264
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   265
      case Action_single: {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   266
        _array->set_offset_array(start_index, boundary, blk_start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   267
        // We have finished marking the "offset card". We need to now
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   268
        // mark the subsequent cards that this blk spans.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   269
        if (start_index < end_index) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   270
          HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   271
          HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   272
          set_remainder_to_point_to_start(rem_st, rem_end);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   273
        }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   274
        break;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   275
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   276
      case Action_check: {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   277
        _array->check_offset_array(start_index, boundary, blk_start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   278
        // We have finished checking the "offset card". We need to now
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   279
        // check the subsequent cards that this blk spans.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   280
        check_all_cards(start_index + 1, end_index);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   281
        break;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   282
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   283
      default:
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   284
        ShouldNotReachHere();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   285
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   286
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   287
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   288
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   289
// The card-interval [start_card, end_card] is a closed interval; this
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   290
// is an expensive check -- use with care and only under protection of
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   291
// suitable flag.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   292
void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   293
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   294
  if (end_card < start_card) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   295
    return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   296
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   297
  guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   298
  for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   299
    u_char entry = _array->offset_array(c);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   300
    if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   301
      guarantee(entry > N_words, "Should be in logarithmic region");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   302
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   303
    size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   304
    size_t landing_card = c - backskip;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   305
    guarantee(landing_card >= (start_card - 1), "Inv");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   306
    if (landing_card >= start_card) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   307
      guarantee(_array->offset_array(landing_card) <= entry, "monotonicity");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   308
    } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   309
      guarantee(landing_card == start_card - 1, "Tautology");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   310
      guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   311
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   312
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   313
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   314
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   315
// The range [blk_start, blk_end) represents a single contiguous block
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   316
// of storage; modify the block offset table to represent this
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   317
// information; Right-open interval: [blk_start, blk_end)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   318
// NOTE: this method does _not_ adjust _unallocated_block.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   319
void
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   320
G1BlockOffsetArray::single_block(HeapWord* blk_start, HeapWord* blk_end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   321
  do_block_internal(blk_start, blk_end, Action_single);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   322
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   323
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   324
// Mark the BOT such that if [blk_start, blk_end) straddles a card
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   325
// boundary, the card following the first such boundary is marked
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   326
// with the appropriate offset.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   327
// NOTE: this method does _not_ adjust _unallocated_block or
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   328
// any cards subsequent to the first one.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   329
void
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   330
G1BlockOffsetArray::mark_block(HeapWord* blk_start, HeapWord* blk_end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   331
  do_block_internal(blk_start, blk_end, Action_mark);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   332
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   333
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   334
HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   335
  assert(_bottom <= addr && addr < _end,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   336
         "addr must be covered by this Array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   337
  // Must read this exactly once because it can be modified by parallel
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   338
  // allocation.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   339
  HeapWord* ub = _unallocated_block;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   340
  if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   341
    assert(ub < _end, "tautology (see above)");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   342
    return ub;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   343
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   344
  // Otherwise, find the block start using the table.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   345
  HeapWord* q = block_at_or_preceding(addr, false, 0);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   346
  return forward_to_block_containing_addr(q, addr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   347
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   348
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   349
// This duplicates a little code from the above: unavoidable.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   350
HeapWord*
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   351
G1BlockOffsetArray::block_start_unsafe_const(const void* addr) const {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   352
  assert(_bottom <= addr && addr < _end,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   353
         "addr must be covered by this Array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   354
  // Must read this exactly once because it can be modified by parallel
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   355
  // allocation.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   356
  HeapWord* ub = _unallocated_block;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   357
  if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   358
    assert(ub < _end, "tautology (see above)");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   359
    return ub;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   360
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   361
  // Otherwise, find the block start using the table.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   362
  HeapWord* q = block_at_or_preceding(addr, false, 0);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   363
  HeapWord* n = q + _sp->block_size(q);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   364
  return forward_to_block_containing_addr_const(q, n, addr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   365
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   366
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   367
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   368
HeapWord*
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   369
G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   370
                                                          HeapWord* n,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   371
                                                          const void* addr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   372
  // We're not in the normal case.  We need to handle an important subcase
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   373
  // here: LAB allocation.  An allocation previously recorded in the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   374
  // offset table was actually a lab allocation, and was divided into
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   375
  // several objects subsequently.  Fix this situation as we answer the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   376
  // query, by updating entries as we cross them.
1384
163a4d4fa951 6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents: 1374
diff changeset
   377
163a4d4fa951 6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents: 1374
diff changeset
   378
  // If the fist object's end q is at the card boundary. Start refining
163a4d4fa951 6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents: 1374
diff changeset
   379
  // with the corresponding card (the value of the entry will be basically
163a4d4fa951 6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents: 1374
diff changeset
   380
  // set to 0). If the object crosses the boundary -- start from the next card.
163a4d4fa951 6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents: 1374
diff changeset
   381
  size_t next_index = _array->index_for(n) + !_array->is_card_boundary(n);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   382
  HeapWord* next_boundary = _array->address_for_index(next_index);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   383
  if (csp() != NULL) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   384
    if (addr >= csp()->top()) return csp()->top();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   385
    while (next_boundary < addr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   386
      while (n <= next_boundary) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   387
        q = n;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   388
        oop obj = oop(q);
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 1623
diff changeset
   389
        if (obj->klass_or_null() == NULL) return q;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   390
        n += obj->size();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   391
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   392
      assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   393
      // [q, n) is the block that crosses the boundary.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   394
      alloc_block_work2(&next_boundary, &next_index, q, n);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   395
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   396
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   397
    while (next_boundary < addr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   398
      while (n <= next_boundary) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   399
        q = n;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   400
        oop obj = oop(q);
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 1623
diff changeset
   401
        if (obj->klass_or_null() == NULL) return q;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   402
        n += _sp->block_size(q);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   403
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   404
      assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   405
      // [q, n) is the block that crosses the boundary.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   406
      alloc_block_work2(&next_boundary, &next_index, q, n);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   407
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   408
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   409
  return forward_to_block_containing_addr_const(q, n, addr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   410
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   411
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   412
HeapWord* G1BlockOffsetArray::block_start_careful(const void* addr) const {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   413
  assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   414
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   415
  assert(_bottom <= addr && addr < _end,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   416
         "addr must be covered by this Array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   417
  // Must read this exactly once because it can be modified by parallel
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   418
  // allocation.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   419
  HeapWord* ub = _unallocated_block;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   420
  if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   421
    assert(ub < _end, "tautology (see above)");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   422
    return ub;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   423
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   424
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   425
  // Otherwise, find the block start using the table, but taking
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   426
  // care (cf block_start_unsafe() above) not to parse any objects/blocks
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   427
  // on the cards themsleves.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   428
  size_t index = _array->index_for(addr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   429
  assert(_array->address_for_index(index) == addr,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   430
         "arg should be start of card");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   431
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   432
  HeapWord* q = (HeapWord*)addr;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   433
  uint offset;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   434
  do {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   435
    offset = _array->offset_array(index--);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   436
    q -= offset;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   437
  } while (offset == N_words);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   438
  assert(q <= addr, "block start should be to left of arg");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   439
  return q;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   440
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   441
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   442
// Note that the committed size of the covered space may have changed,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   443
// so the table size might also wish to change.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   444
void G1BlockOffsetArray::resize(size_t new_word_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   445
  HeapWord* new_end = _bottom + new_word_size;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   446
  if (_end < new_end && !init_to_zero()) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   447
    // verify that the old and new boundaries are also card boundaries
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   448
    assert(_array->is_card_boundary(_end),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   449
           "_end not a card boundary");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   450
    assert(_array->is_card_boundary(new_end),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   451
           "new _end would not be a card boundary");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   452
    // set all the newly added cards
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   453
    _array->set_offset_array(_end, new_end, N_words);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   454
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   455
  _end = new_end;  // update _end
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   456
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   457
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   458
void G1BlockOffsetArray::set_region(MemRegion mr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   459
  _bottom = mr.start();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   460
  _end = mr.end();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   461
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   462
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   463
//
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   464
//              threshold_
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   465
//              |   _index_
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   466
//              v   v
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   467
//      +-------+-------+-------+-------+-------+
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   468
//      | i-1   |   i   | i+1   | i+2   | i+3   |
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   469
//      +-------+-------+-------+-------+-------+
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   470
//       ( ^    ]
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   471
//         block-start
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   472
//
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   473
void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   474
                                           HeapWord* blk_start, HeapWord* blk_end) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   475
  // For efficiency, do copy-in/copy-out.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   476
  HeapWord* threshold = *threshold_;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   477
  size_t    index = *index_;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   478
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   479
  assert(blk_start != NULL && blk_end > blk_start,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   480
         "phantom block");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   481
  assert(blk_end > threshold, "should be past threshold");
5402
c51fd0c1d005 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 3262
diff changeset
   482
  assert(blk_start <= threshold, "blk_start should be at or before threshold");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   483
  assert(pointer_delta(threshold, blk_start) <= N_words,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   484
         "offset should be <= BlockOffsetSharedArray::N");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   485
  assert(Universe::heap()->is_in_reserved(blk_start),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   486
         "reference must be into the heap");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   487
  assert(Universe::heap()->is_in_reserved(blk_end-1),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   488
         "limit must be within the heap");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   489
  assert(threshold == _array->_reserved.start() + index*N_words,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   490
         "index must agree with threshold");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   491
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   492
  DEBUG_ONLY(size_t orig_index = index;)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   493
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   494
  // Mark the card that holds the offset into the block.  Note
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   495
  // that _next_offset_index and _next_offset_threshold are not
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   496
  // updated until the end of this method.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   497
  _array->set_offset_array(index, threshold, blk_start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   498
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   499
  // We need to now mark the subsequent cards that this blk spans.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   500
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   501
  // Index of card on which blk ends.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   502
  size_t end_index   = _array->index_for(blk_end - 1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   503
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   504
  // Are there more cards left to be updated?
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   505
  if (index + 1 <= end_index) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   506
    HeapWord* rem_st  = _array->address_for_index(index + 1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   507
    // Calculate rem_end this way because end_index
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   508
    // may be the last valid index in the covered region.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   509
    HeapWord* rem_end = _array->address_for_index(end_index) +  N_words;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   510
    set_remainder_to_point_to_start(rem_st, rem_end);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   511
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   512
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   513
  index = end_index + 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   514
  // Calculate threshold_ this way because end_index
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   515
  // may be the last valid index in the covered region.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   516
  threshold = _array->address_for_index(end_index) + N_words;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   517
  assert(threshold >= blk_end, "Incorrect offset threshold");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   518
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   519
  // index_ and threshold_ updated here.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   520
  *threshold_ = threshold;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   521
  *index_ = index;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   522
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   523
#ifdef ASSERT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   524
  // The offset can be 0 if the block starts on a boundary.  That
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   525
  // is checked by an assertion above.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   526
  size_t start_index = _array->index_for(blk_start);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   527
  HeapWord* boundary    = _array->address_for_index(start_index);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   528
  assert((_array->offset_array(orig_index) == 0 &&
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   529
          blk_start == boundary) ||
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   530
          (_array->offset_array(orig_index) > 0 &&
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   531
         _array->offset_array(orig_index) <= N_words),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   532
         "offset array should have been set");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   533
  for (size_t j = orig_index + 1; j <= end_index; j++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   534
    assert(_array->offset_array(j) > 0 &&
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   535
           _array->offset_array(j) <=
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   536
             (u_char) (N_words+BlockOffsetArray::N_powers-1),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   537
           "offset array should have been set");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   538
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   539
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   540
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   541
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   542
bool
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   543
G1BlockOffsetArray::verify_for_object(HeapWord* obj_start,
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   544
                                      size_t word_size) const {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   545
  size_t first_card = _array->index_for(obj_start);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   546
  size_t last_card = _array->index_for(obj_start + word_size - 1);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   547
  if (!_array->is_card_boundary(obj_start)) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   548
    // If the object is not on a card boundary the BOT entry of the
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   549
    // first card should point to another object so we should not
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   550
    // check that one.
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   551
    first_card += 1;
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   552
  }
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   553
  for (size_t card = first_card; card <= last_card; card += 1) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   554
    HeapWord* card_addr = _array->address_for_index(card);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   555
    HeapWord* block_start = block_start_const(card_addr);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   556
    if (block_start != obj_start) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   557
      gclog_or_tty->print_cr("block start: "PTR_FORMAT" is incorrect - "
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   558
                             "card index: "SIZE_FORMAT" "
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   559
                             "card addr: "PTR_FORMAT" BOT entry: %u "
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   560
                             "obj: "PTR_FORMAT" word size: "SIZE_FORMAT" "
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   561
                             "cards: ["SIZE_FORMAT","SIZE_FORMAT"]",
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   562
                             block_start, card, card_addr,
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   563
                             _array->offset_array(card),
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   564
                             obj_start, word_size, first_card, last_card);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   565
      return false;
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   566
    }
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   567
  }
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   568
  return true;
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   569
}
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   570
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   571
#ifndef PRODUCT
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   572
void
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   573
G1BlockOffsetArray::print_on(outputStream* out) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   574
  size_t from_index = _array->index_for(_bottom);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   575
  size_t to_index = _array->index_for(_end);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   576
  out->print_cr(">> BOT for area ["PTR_FORMAT","PTR_FORMAT") "
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   577
                "cards ["SIZE_FORMAT","SIZE_FORMAT")",
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   578
                _bottom, _end, from_index, to_index);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   579
  for (size_t i = from_index; i < to_index; ++i) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   580
    out->print_cr("  entry "SIZE_FORMAT_W(8)" | "PTR_FORMAT" : %3u",
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   581
                  i, _array->address_for_index(i),
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   582
                  (uint) _array->offset_array(i));
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   583
  }
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   584
}
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   585
#endif // !PRODUCT
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   586
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   587
//////////////////////////////////////////////////////////////////////
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   588
// G1BlockOffsetArrayContigSpace
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   589
//////////////////////////////////////////////////////////////////////
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   590
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   591
HeapWord*
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   592
G1BlockOffsetArrayContigSpace::block_start_unsafe(const void* addr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   593
  assert(_bottom <= addr && addr < _end,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   594
         "addr must be covered by this Array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   595
  HeapWord* q = block_at_or_preceding(addr, true, _next_offset_index-1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   596
  return forward_to_block_containing_addr(q, addr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   597
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   598
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   599
HeapWord*
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   600
G1BlockOffsetArrayContigSpace::
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   601
block_start_unsafe_const(const void* addr) const {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   602
  assert(_bottom <= addr && addr < _end,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   603
         "addr must be covered by this Array");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   604
  HeapWord* q = block_at_or_preceding(addr, true, _next_offset_index-1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   605
  HeapWord* n = q + _sp->block_size(q);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   606
  return forward_to_block_containing_addr_const(q, n, addr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   607
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   608
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   609
G1BlockOffsetArrayContigSpace::
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   610
G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   611
                              MemRegion mr) :
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   612
  G1BlockOffsetArray(array, mr, true)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   613
{
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   614
  _next_offset_threshold = NULL;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   615
  _next_offset_index = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   616
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   617
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   618
HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   619
  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   620
         "just checking");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   621
  _next_offset_index = _array->index_for(_bottom);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   622
  _next_offset_index++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   623
  _next_offset_threshold =
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   624
    _array->address_for_index(_next_offset_index);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   625
  return _next_offset_threshold;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   626
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   627
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   628
void G1BlockOffsetArrayContigSpace::zero_bottom_entry() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   629
  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   630
         "just checking");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   631
  size_t bottom_index = _array->index_for(_bottom);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   632
  assert(_array->address_for_index(bottom_index) == _bottom,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   633
         "Precondition of call");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   634
  _array->set_offset_array(bottom_index, 0);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   635
}
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   636
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   637
void
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   638
G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   639
  assert(new_top <= _end, "_end should have already been updated");
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   640
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   641
  // The first BOT entry should have offset 0.
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   642
  zero_bottom_entry();
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   643
  initialize_threshold();
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   644
  alloc_block(_bottom, new_top);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   645
 }
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   646
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   647
#ifndef PRODUCT
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   648
void
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   649
G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   650
  G1BlockOffsetArray::print_on(out);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   651
  out->print_cr("  next offset threshold: "PTR_FORMAT, _next_offset_threshold);
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   652
  out->print_cr("  next offset index:     "SIZE_FORMAT, _next_offset_index);
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 5547
diff changeset
   653
}
7904
e90e097fced4 7007068: G1: refine the BOT during evac failure handling
tonyp
parents: 7397
diff changeset
   654
#endif // !PRODUCT