hotspot/src/share/vm/memory/blockOffsetTable.cpp
author ysr
Mon, 16 Aug 2010 15:58:42 -0700
changeset 6258 68f252c6e825
parent 5547 f4b087cbb361
child 7397 5b173b4ca846
permissions -rw-r--r--
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
     2
 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 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.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_blockOffsetTable.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
// BlockOffsetSharedArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
BlockOffsetSharedArray::BlockOffsetSharedArray(MemRegion reserved,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
                                               size_t init_word_size):
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
  _reserved(reserved), _end(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  size_t size = compute_size(reserved.word_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  ReservedSpace rs(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  if (!rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
    vm_exit_during_initialization("Could not reserve enough space for heap offset array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  if (!_vs.initialize(rs, 0)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    vm_exit_during_initialization("Could not reserve enough space for heap offset array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  _offset_array = (u_char*)_vs.low_boundary();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  resize(init_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  if (TraceBlockOffsetTable) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    gclog_or_tty->print_cr("BlockOffsetSharedArray::BlockOffsetSharedArray: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    gclog_or_tty->print_cr("  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
                  "  rs.base(): " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
                  "  rs.size(): " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
                  "  rs end(): " INTPTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
                  rs.base(), rs.size(), rs.base() + rs.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    gclog_or_tty->print_cr("  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
                  "  _vs.low_boundary(): " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
                  "  _vs.high_boundary(): " INTPTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
                  _vs.low_boundary(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
                  _vs.high_boundary());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
void BlockOffsetSharedArray::resize(size_t new_word_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  assert(new_word_size <= _reserved.word_size(), "Resize larger than reserved");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  size_t new_size = compute_size(new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  size_t old_size = _vs.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  size_t delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  char* high = _vs.high();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  _end = _reserved.start() + new_word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  if (new_size > old_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    delta = ReservedSpace::page_align_size_up(new_size - old_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    assert(delta > 0, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    if (!_vs.expand_by(delta)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
      // Do better than this for Merlin
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
      vm_exit_out_of_memory(delta, "offset table expansion");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    assert(_vs.high() == high + delta, "invalid expansion");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    delta = ReservedSpace::page_align_size_down(old_size - new_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    if (delta == 0) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    _vs.shrink_by(delta);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    assert(_vs.high() == high - delta, "invalid expansion");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
bool BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  assert(p >= _reserved.start(), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  size_t delta = pointer_delta(p, _reserved.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
void BlockOffsetSharedArray::serialize(SerializeOopClosure* soc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
                                       HeapWord* start, HeapWord* end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  assert(_offset_array[0] == 0, "objects can't cross covered areas");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  assert(start <= end, "bad address range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  size_t start_index = index_for(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  size_t end_index = index_for(end-1)+1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  soc->do_region(&_offset_array[start_index],
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
                 (end_index - start_index) * sizeof(_offset_array[0]));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
// BlockOffsetArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
BlockOffsetArray::BlockOffsetArray(BlockOffsetSharedArray* array,
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   106
                                   MemRegion mr, bool init_to_zero_) :
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  BlockOffsetTable(mr.start(), mr.end()),
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   108
  _array(array)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  assert(_bottom <= _end, "arguments out of order");
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   111
  set_init_to_zero(init_to_zero_);
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   112
  if (!init_to_zero_) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    // initialize cards to point back to mr.start()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    _array->set_offset_array(0, 0);  // set first card to 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
// The arguments follow the normal convention of denoting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
// a right-open interval: [start, end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
BlockOffsetArray::
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   124
set_remainder_to_point_to_start(HeapWord* start, HeapWord* end, bool reducing) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   126
  check_reducing_assertion(reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  if (start >= end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    // The start address is equal to the end address (or to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    // the right of the end address) so there are not cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    // that need to be updated..
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  // Write the backskip value for each region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  //    offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  //    card             2nd                       3rd
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  //     | +- 1st        |                         |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  //     v v             v                         v
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  //    |x|0|0|0|0|0|0|0|1|1|1|1|1|1| ... |1|1|1|1|2|2|2|2|2|2| ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  //    11              19                        75
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  //      12
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  //    offset card is the card that points to the start of an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  //      x - offset value of offset card
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  //    1st - start of first logarithmic region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  //      0 corresponds to logarithmic value N_words + 0 and 2**(3 * 0) = 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  //    2nd - start of second logarithmic region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  //      1 corresponds to logarithmic value N_words + 1 and 2**(3 * 1) = 8
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  //    3rd - start of third logarithmic region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  //      2 corresponds to logarithmic value N_words + 2 and 2**(3 * 2) = 64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  //    integer below the block offset entry is an example of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  //    the index of the entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  //    Given an address,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  //      Find the index for the address
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  //      Find the block offset table entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  //      Convert the entry to a back slide
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  //        (e.g., with today's, offset = 0x81 =>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  //          back slip = 2**(3*(0x81 - N_words)) = 2**3) = 8
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  //      Move back N (e.g., 8) entries and repeat with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  //        value of the new entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  size_t start_card = _array->index_for(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  size_t end_card = _array->index_for(end-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  assert(start ==_array->address_for_index(start_card), "Precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  assert(end ==_array->address_for_index(end_card)+N_words, "Precondition");
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   171
  set_remainder_to_point_to_start_incl(start_card, end_card, reducing); // closed interval
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
// Unlike the normal convention in this code, the argument here denotes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
// a closed, inclusive interval: [start_card, end_card], cf set_remainder_to_point_to_start()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
// above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
void
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   179
BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t end_card, bool reducing) {
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   180
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   181
  check_reducing_assertion(reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  if (start_card > end_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  assert(start_card > _array->index_for(_bottom), "Cannot be first card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  assert(_array->offset_array(start_card-1) <= N_words,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    "Offset card has an unexpected value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  size_t start_card_for_region = start_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  u_char offset = max_jubyte;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
   190
  for (int i = 0; i < N_powers; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    // -1 so that the the card with the actual offset is counted.  Another -1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    // so that the reach ends in this region and not at the start
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    // of the next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    size_t reach = start_card - 1 + (power_to_cards_back(i+1) - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    offset = N_words + i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    if (reach >= end_card) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   197
      _array->set_offset_array(start_card_for_region, end_card, offset, reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
      start_card_for_region = reach + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    }
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   201
    _array->set_offset_array(start_card_for_region, reach, offset, reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    start_card_for_region = reach + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  assert(start_card_for_region > end_card, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  DEBUG_ONLY(check_all_cards(start_card, end_card);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
// The card-interval [start_card, end_card] is a closed interval; this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
// is an expensive check -- use with care and only under protection of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
// suitable flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
void BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  if (end_card < start_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   217
  u_char last_entry = N_words;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    u_char entry = _array->offset_array(c);
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   220
    guarantee(entry >= last_entry, "Monotonicity");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
    if (c - start_card > power_to_cards_back(1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
      guarantee(entry > N_words, "Should be in logarithmic region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    size_t backskip = entry_to_cards_back(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    size_t landing_card = c - backskip;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    guarantee(landing_card >= (start_card - 1), "Inv");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    if (landing_card >= start_card) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   228
      guarantee(_array->offset_array(landing_card) <= entry, "Monotonicity");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    } else {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   230
      guarantee(landing_card == (start_card - 1), "Tautology");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   231
      // Note that N_words is the maximum offset value
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
      guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
    }
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   234
    last_entry = entry;  // remember for monotonicity test
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  assert(blk_start != NULL && blk_end > blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
         "phantom block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  single_block(blk_start, blk_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
// Action_mark - update the BOT for the block [blk_start, blk_end).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
//               Current typical use is for splitting a block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
// Action_single - udpate the BOT for an allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
// Action_verify - BOT verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
BlockOffsetArray::do_block_internal(HeapWord* blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
                                    HeapWord* blk_end,
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   253
                                    Action action, bool reducing) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  assert(Universe::heap()->is_in_reserved(blk_start),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
         "reference must be into the heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  assert(Universe::heap()->is_in_reserved(blk_end-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
         "limit must be within the heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  // This is optimized to make the test fast, assuming we only rarely
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  // cross boundaries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  uintptr_t end_ui = (uintptr_t)(blk_end - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  uintptr_t start_ui = (uintptr_t)blk_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  // Calculate the last card boundary preceding end of blk
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  intptr_t boundary_before_end = (intptr_t)end_ui;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  clear_bits(boundary_before_end, right_n_bits(LogN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  if (start_ui <= (uintptr_t)boundary_before_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    // blk starts at or crosses a boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    // Calculate index of card on which blk begins
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    size_t    start_index = _array->index_for(blk_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
    // Index of card on which blk ends
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
    size_t    end_index   = _array->index_for(blk_end - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    // Start address of card on which blk begins
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    HeapWord* boundary    = _array->address_for_index(start_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    assert(boundary <= blk_start, "blk should start at or after boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    if (blk_start != boundary) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
      // blk starts strictly after boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
      // adjust card boundary and start_index forward to next card
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
      boundary += N_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
      start_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    assert(start_index <= end_index, "monotonicity of index_for()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    switch (action) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
      case Action_mark: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
        if (init_to_zero()) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   285
          _array->set_offset_array(start_index, boundary, blk_start, reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
        } // Else fall through to the next case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
      case Action_single: {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   290
        _array->set_offset_array(start_index, boundary, blk_start, reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
        // We have finished marking the "offset card". We need to now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
        // mark the subsequent cards that this blk spans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
        if (start_index < end_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
          HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
          HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   296
          set_remainder_to_point_to_start(rem_st, rem_end, reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      case Action_check: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
        _array->check_offset_array(start_index, boundary, blk_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
        // We have finished checking the "offset card". We need to now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
        // check the subsequent cards that this blk spans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
        check_all_cards(start_index + 1, end_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
// The range [blk_start, blk_end) represents a single contiguous block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
// of storage; modify the block offset table to represent this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
// information; Right-open interval: [blk_start, blk_end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
// NOTE: this method does _not_ adjust _unallocated_block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
BlockOffsetArray::single_block(HeapWord* blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
                               HeapWord* blk_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  do_block_internal(blk_start, blk_end, Action_single);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
void BlockOffsetArray::verify() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  // For each entry in the block offset table, verify that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  // the entry correctly finds the start of an object at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  // first address covered by the block or to the left of that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  // first address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  size_t next_index = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  size_t last_index = last_active_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  // Use for debugging.  Initialize to NULL to distinguish the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // first iteration through the while loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  HeapWord* last_p = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  HeapWord* last_start = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  oop last_o = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  while (next_index <= last_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    // Use an address past the start of the address for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
    // the entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
    HeapWord* p = _array->address_for_index(next_index) + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    if (p >= _end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      // That's all of the allocated block table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
    // block_start() asserts that start <= p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
    HeapWord* start = block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    // First check if the start is an allocated block and only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
    // then if it is a valid object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    oop o = oop(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    assert(!Universe::is_fully_initialized() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
           _sp->is_free_block(start) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
           o->is_oop_or_null(), "Bad object was found");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    next_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    last_p = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    last_start = start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    last_o = o;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
// BlockOffsetArrayNonContigSpace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
// The block [blk_start, blk_end) has been allocated;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
// adjust the block offset table to represent this information;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
// NOTE: Clients of BlockOffsetArrayNonContigSpace: consider using
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
// the somewhat more lightweight split_block() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
// (when init_to_zero()) mark_block() wherever possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
// right-open interval: [blk_start, blk_end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
BlockOffsetArrayNonContigSpace::alloc_block(HeapWord* blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
                                            HeapWord* blk_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  assert(blk_start != NULL && blk_end > blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
         "phantom block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  single_block(blk_start, blk_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  allocated(blk_start, blk_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// Adjust BOT to show that a previously whole block has been split
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// into two.  We verify the BOT for the first part (prefix) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// update the  BOT for the second part (suffix).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
//      blk is the start of the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
//      blk_size is the size of the original block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
//      left_blk_size is the size of the first part of the split
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
void BlockOffsetArrayNonContigSpace::split_block(HeapWord* blk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
                                                 size_t blk_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
                                                 size_t left_blk_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  // Verify that the BOT shows [blk, blk + blk_size) to be one block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  verify_single_block(blk, blk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  // is one single block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  assert(blk_size > 0, "Should be positive");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  assert(left_blk_size > 0, "Should be positive");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  assert(left_blk_size < blk_size, "Not a split");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  // Start addresses of prefix block and suffix block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  HeapWord* pref_addr = blk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  HeapWord* suff_addr = blk + left_blk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  HeapWord* end_addr  = blk + blk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  // Indices for starts of prefix block and suffix block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  size_t pref_index = _array->index_for(pref_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  if (_array->address_for_index(pref_index) != pref_addr) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   405
    // pref_addr does not begin pref_index
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
    pref_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  size_t suff_index = _array->index_for(suff_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  if (_array->address_for_index(suff_index) != suff_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    // suff_addr does not begin suff_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    suff_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  // Definition: A block B, denoted [B_start, B_end) __starts__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  //     a card C, denoted [C_start, C_end), where C_start and C_end
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  //     are the heap addresses that card C covers, iff
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  //     B_start <= C_start < B_end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  //     We say that a card C "is started by" a block B, iff
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  //     B "starts" C.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  //     Note that the cardinality of the set of cards {C}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  //     started by a block B can be 0, 1, or more.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  // Below, pref_index and suff_index are, respectively, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  // first (least) card indices that the prefix and suffix of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  // the split start; end_index is one more than the index of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  // the last (greatest) card that blk starts.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  size_t end_index  = _array->index_for(end_addr - 1) + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  // Calculate the # cards that the prefix and suffix affect.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  size_t num_pref_cards = suff_index - pref_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  size_t num_suff_cards = end_index  - suff_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  // Change the cards that need changing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  if (num_suff_cards > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
    HeapWord* boundary = _array->address_for_index(suff_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
    // Set the offset card for suffix block
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   440
    _array->set_offset_array(suff_index, boundary, suff_addr, true /* reducing */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
    // Change any further cards that need changing in the suffix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
    if (num_pref_cards > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
      if (num_pref_cards >= num_suff_cards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
        // Unilaterally fix all of the suffix cards: closed card
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        // index interval in args below.
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   446
        set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
        // Unilaterally fix the first (num_pref_cards - 1) following
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        // the "offset card" in the suffix block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
        set_remainder_to_point_to_start_incl(suff_index + 1,
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   451
          suff_index + num_pref_cards - 1, true /* reducing */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
        // Fix the appropriate cards in the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
        // suffix block -- these are the last num_pref_cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
        // cards in each power block of the "new" range plumbed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
        // from suff_addr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
        bool more = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
        uint i = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
        while (more && (i < N_powers)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
          size_t back_by = power_to_cards_back(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
          size_t right_index = suff_index + back_by - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
          size_t left_index  = right_index - num_pref_cards + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
          if (right_index >= end_index - 1) { // last iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
            right_index = end_index - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
            more = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
          if (back_by > num_pref_cards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
            // Fill in the remainder of this "power block", if it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
            // is non-null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
            if (left_index <= right_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
              _array->set_offset_array(left_index, right_index,
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   471
                                     N_words + i - 1, true /* reducing */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
              more = false; // we are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
            i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
          i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
        while (more && (i < N_powers)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
          size_t back_by = power_to_cards_back(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
          size_t right_index = suff_index + back_by - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
          size_t left_index  = right_index - num_pref_cards + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
          if (right_index >= end_index - 1) { // last iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
            right_index = end_index - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
            if (left_index > right_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
              break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
            more  = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
          assert(left_index <= right_index, "Error");
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   492
          _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
          i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
    } // else no more cards to fix in suffix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  } // else nothing needs to be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  // Verify that we did the right thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  verify_single_block(pref_addr, left_blk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  verify_single_block(suff_addr, blk_size - left_blk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
// Mark the BOT such that if [blk_start, blk_end) straddles a card
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
// boundary, the card following the first such boundary is marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
// with the appropriate offset.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
// NOTE: this method does _not_ adjust _unallocated_block or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
// any cards subsequent to the first one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start,
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   511
                                           HeapWord* blk_end, bool reducing) {
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   512
  do_block_internal(blk_start, blk_end, Action_mark, reducing);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  const void* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  assert(_bottom <= addr && addr < _end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
         "addr must be covered by this Array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  // Must read this exactly once because it can be modified by parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  HeapWord* ub = _unallocated_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
    assert(ub < _end, "tautology (see above)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    return ub;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  // Otherwise, find the block start using the table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  size_t index = _array->index_for(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  HeapWord* q = _array->address_for_index(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  uint offset = _array->offset_array(index);    // Extend u_char to uint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  while (offset >= N_words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    // The excess of the offset from N_words indicates a power of Base
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    // to go back by.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    size_t n_cards_back = entry_to_cards_back(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    q -= (N_words * n_cards_back);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    assert(q >= _sp->bottom(), "Went below bottom!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    index -= n_cards_back;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    offset = _array->offset_array(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  assert(offset < N_words, "offset too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  index--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  q -= offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  HeapWord* n = q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  while (n <= addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
    debug_only(HeapWord* last = q);   // for debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
    q = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
    n += _sp->block_size(n);
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   551
    assert(n > q, err_msg("Looping at: " INTPTR_FORMAT, n));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  }
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   553
  assert(q <= addr, err_msg("wrong order for current (" INTPTR_FORMAT ") <= arg (" INTPTR_FORMAT ")", q, addr));
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   554
  assert(addr <= n, err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", addr, n));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  return q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  const void* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  assert(_bottom <= addr && addr < _end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
         "addr must be covered by this Array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  // Must read this exactly once because it can be modified by parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  // allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  HeapWord* ub = _unallocated_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
    assert(ub < _end, "tautology (see above)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    return ub;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  // Otherwise, find the block start using the table, but taking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  // care (cf block_start_unsafe() above) not to parse any objects/blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  // on the cards themsleves.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  size_t index = _array->index_for(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  assert(_array->address_for_index(index) == addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
         "arg should be start of card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  HeapWord* q = (HeapWord*)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  uint offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
    offset = _array->offset_array(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    if (offset < N_words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
      q -= offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
      size_t n_cards_back = entry_to_cards_back(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
      q -= (n_cards_back * N_words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
      index -= n_cards_back;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  } while (offset >= N_words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  assert(q <= addr, "block start should be to left of arg");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  return q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
// Verification & debugging - ensure that the offset table reflects the fact
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
// that the block [blk_start, blk_end) or [blk, blk + size) is a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
// single block of storage. NOTE: can't const this because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
// call to non-const do_block_internal() below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
void BlockOffsetArrayNonContigSpace::verify_single_block(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  HeapWord* blk_start, HeapWord* blk_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  if (VerifyBlockOffsetArray) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
    do_block_internal(blk_start, blk_end, Action_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
void BlockOffsetArrayNonContigSpace::verify_single_block(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  HeapWord* blk, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  verify_single_block(blk, blk + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
// Verify that the given block is before _unallocated_block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  HeapWord* blk_start, HeapWord* blk_end) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  if (BlockOffsetArrayUseUnallocatedBlock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    assert(blk_start < blk_end, "Block inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    assert(blk_end <= _unallocated_block, "_unallocated_block problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
void BlockOffsetArrayNonContigSpace::verify_not_unallocated(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  HeapWord* blk, size_t size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  verify_not_unallocated(blk, blk + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
size_t BlockOffsetArrayNonContigSpace::last_active_index() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  if (_unallocated_block == _bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    return _array->index_for(_unallocated_block - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
// BlockOffsetArrayContigSpace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
//////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
HeapWord* BlockOffsetArrayContigSpace::block_start_unsafe(const void* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
  // Otherwise, find the block start using the table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  assert(_bottom <= addr && addr < _end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
         "addr must be covered by this Array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
  size_t index = _array->index_for(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  // We must make sure that the offset table entry we use is valid.  If
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  // "addr" is past the end, start at the last known one and go forward.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  index = MIN2(index, _next_offset_index-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  HeapWord* q = _array->address_for_index(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  uint offset = _array->offset_array(index);    // Extend u_char to uint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  while (offset > N_words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    // The excess of the offset from N_words indicates a power of Base
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    // to go back by.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    size_t n_cards_back = entry_to_cards_back(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    q -= (N_words * n_cards_back);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
    assert(q >= _sp->bottom(), "Went below bottom!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
    index -= n_cards_back;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
    offset = _array->offset_array(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
  while (offset == N_words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
    assert(q >= _sp->bottom(), "Went below bottom!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
    q -= N_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
    index--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
    offset = _array->offset_array(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  assert(offset < N_words, "offset too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  q -= offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  HeapWord* n = q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  while (n <= addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
    debug_only(HeapWord* last = q);   // for debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
    q = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
    n += _sp->block_size(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  assert(q <= addr, "wrong order for current and arg");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
  assert(addr <= n, "wrong order for arg and next");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  return q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
//              _next_offset_threshold
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
//              |   _next_offset_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
//              v   v
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
//      +-------+-------+-------+-------+-------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
//      | i-1   |   i   | i+1   | i+2   | i+3   |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
//      +-------+-------+-------+-------+-------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
//       ( ^    ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
//         block-start
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
                                        HeapWord* blk_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  assert(blk_start != NULL && blk_end > blk_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
         "phantom block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  assert(blk_end > _next_offset_threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
         "should be past threshold");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  assert(blk_start <= _next_offset_threshold,
5402
c51fd0c1d005 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 1374
diff changeset
   699
         "blk_start should be at or before threshold");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  assert(pointer_delta(_next_offset_threshold, blk_start) <= N_words,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
         "offset should be <= BlockOffsetSharedArray::N");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  assert(Universe::heap()->is_in_reserved(blk_start),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
         "reference must be into the heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  assert(Universe::heap()->is_in_reserved(blk_end-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
         "limit must be within the heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  assert(_next_offset_threshold ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
         _array->_reserved.start() + _next_offset_index*N_words,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
         "index must agree with threshold");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  debug_only(size_t orig_next_offset_index = _next_offset_index;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  // Mark the card that holds the offset into the block.  Note
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  // that _next_offset_index and _next_offset_threshold are not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  // updated until the end of this method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  _array->set_offset_array(_next_offset_index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
                           _next_offset_threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
                           blk_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  // We need to now mark the subsequent cards that this blk spans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  // Index of card on which blk ends.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  size_t end_index   = _array->index_for(blk_end - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  // Are there more cards left to be updated?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  if (_next_offset_index + 1 <= end_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    HeapWord* rem_st  = _array->address_for_index(_next_offset_index + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    // Calculate rem_end this way because end_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    // may be the last valid index in the covered region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    HeapWord* rem_end = _array->address_for_index(end_index) +  N_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    set_remainder_to_point_to_start(rem_st, rem_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  // _next_offset_index and _next_offset_threshold updated here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  _next_offset_index = end_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  // Calculate _next_offset_threshold this way because end_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  // may be the last valid index in the covered region.
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   737
  _next_offset_threshold = _array->address_for_index(end_index) + N_words;
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 5547
diff changeset
   738
  assert(_next_offset_threshold >= blk_end, "Incorrect offset threshold");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  // The offset can be 0 if the block starts on a boundary.  That
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  // is checked by an assertion above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  size_t start_index = _array->index_for(blk_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  HeapWord* boundary    = _array->address_for_index(start_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  assert((_array->offset_array(orig_next_offset_index) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
          blk_start == boundary) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
          (_array->offset_array(orig_next_offset_index) > 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
         _array->offset_array(orig_next_offset_index) <= N_words),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
         "offset array should have been set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    assert(_array->offset_array(j) > 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
           _array->offset_array(j) <= (u_char) (N_words+N_powers-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
           "offset array should have been set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
HeapWord* BlockOffsetArrayContigSpace::initialize_threshold() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
         "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  _next_offset_index = _array->index_for(_bottom);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  _next_offset_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  _next_offset_threshold =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
    _array->address_for_index(_next_offset_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
  return _next_offset_threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
void BlockOffsetArrayContigSpace::zero_bottom_entry() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
         "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  size_t bottom_index = _array->index_for(_bottom);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
  _array->set_offset_array(bottom_index, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
void BlockOffsetArrayContigSpace::serialize(SerializeOopClosure* soc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
  if (soc->reading()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    // Null these values so that the serializer won't object to updating them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
    _next_offset_threshold = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    _next_offset_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  soc->do_ptr(&_next_offset_threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  soc->do_size_t(&_next_offset_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
size_t BlockOffsetArrayContigSpace::last_active_index() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  size_t result = _next_offset_index - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  return result >= 0 ? result : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
}